이번에는 Zepto 탭 이벤트를 사용하여 관통하고 탭하는 방법을 보여 드리겠습니다(코드 포함). Zepto 탭 이벤트를 사용하여 관통하고 탭할 때 주의 사항은 무엇입니까? 봐.
먼저 젭토 탭이벤트 침투란?탭 이벤트 침투는 여러 수준에 바인딩된 이벤트가 있음을 의미하며, 상위 수준은 탭 이벤트에 바인딩되고, 하위 수준은 클릭 이벤트에 바인딩됩니다. 트리거되고 이벤트가 발생합니다. 하위 레이어가 이유:
zepto는 탭 이벤트가 문서에 버블링될 때 트리거되도록 구현했기 때문입니다. 즉, 탭 이벤트가 문서에 바인딩되어 있고 클릭 이벤트가 실행을 지연시켰기 때문입니다.
아래에는 zepto.1.1.6 탭 이벤트의 소스 코드가 게시되어 있습니다.
<span style="font-size: 14px;">;(function($){<br> var touch = {},<br> touchTimeout, tapTimeout, swipeTimeout, longTapTimeout,<br> longTapDelay = 750,<br> gesture<br> function swipeDirection(x1, x2, y1, y2) {<br> return Math.abs(x1 - x2) >=<br> Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')<br> }<br> function longTap() {<br> longTapTimeout = null<br> if (touch.last) {<br> touch.el.trigger('longTap')<br> touch = {}<br> }<br> }<br> function cancelLongTap() {<br> if (longTapTimeout) clearTimeout(longTapTimeout)<br> longTapTimeout = null<br> }<br> function cancelAll() {<br> if (touchTimeout) clearTimeout(touchTimeout)<br> if (tapTimeout) clearTimeout(tapTimeout)<br> if (swipeTimeout) clearTimeout(swipeTimeout)<br> if (longTapTimeout) clearTimeout(longTapTimeout)<br> touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null<br> touch = {}<br> }<br> function isPrimaryTouch(event){<br> return (event.pointerType == 'touch' ||<br> event.pointerType == event.MSPOINTER_TYPE_TOUCH)<br> && event.isPrimary<br> }<br> function isPointerEventType(e, type){<br> return (e.type == 'pointer'+type ||<br> e.type.toLowerCase() == 'mspointer'+type)<br> }<br> $(document).ready(function(){<br> var now, delta, deltaX = 0, deltaY = 0, firstTouch, _isPointerType<br> if ('MSGesture' in window) {<br> gesture = new MSGesture()<br> gesture.target = document.body<br> }<br> $(document)<br> .bind('MSGestureEnd', function(e){<br> var swipeDirectionFromVelocity =<br> e.velocityX > 1 ? 'Right' : e.velocityX < -1 ? 'Left' : e.velocityY > 1 ? 'Down' : e.velocityY < -1 ? 'Up' : null;<br/> if (swipeDirectionFromVelocity) {<br/> touch.el.trigger('swipe')<br/> touch.el.trigger('swipe'+ swipeDirectionFromVelocity)<br/> }<br/> })<br/> .on('touchstart MSPointerDown pointerdown', function(e){<br/> if((_isPointerType = isPointerEventType(e, 'down')) &&<br/> !isPrimaryTouch(e)) return<br/> firstTouch = _isPointerType ? e : e.touches[0]<br/> if (e.touches && e.touches.length === 1 && touch.x2) {<br/> // Clear out touch movement data if we have it sticking around<br/> // This can occur if touchcancel doesn't fire due to preventDefault, etc.<br/> touch.x2 = undefined<br/> touch.y2 = undefined<br/> }<br/> now = Date.now()<br/> delta = now - (touch.last || now)<br/> touch.el = $('tagName' in firstTouch.target ?<br/> firstTouch.target : firstTouch.target.parentNode)<br/> touchTimeout && clearTimeout(touchTimeout)<br/> touch.x1 = firstTouch.pageX<br/> touch.y1 = firstTouch.pageY<br/> if (delta > 0 && delta <= 250) touch.isDoubleTap = true<br/> touch.last = now<br/> longTapTimeout = setTimeout(longTap, longTapDelay)<br/> // adds the current touch contact for IE gesture recognition<br/> if (gesture && _isPointerType) gesture.addPointer(e.pointerId);<br/> })<br/> .on('touchmove MSPointerMove pointermove', function(e){<br/> if((_isPointerType = isPointerEventType(e, 'move')) &&<br/> !isPrimaryTouch(e)) return<br/> firstTouch = _isPointerType ? e : e.touches[0]<br/> cancelLongTap()<br/> touch.x2 = firstTouch.pageX<br/> touch.y2 = firstTouch.pageY<br/> deltaX += Math.abs(touch.x1 - touch.x2)<br/> deltaY += Math.abs(touch.y1 - touch.y2)<br/> })<br/> .on('touchend MSPointerUp pointerup', function(e){<br/> if((_isPointerType = isPointerEventType(e, 'up')) &&<br/> !isPrimaryTouch(e)) return<br/> cancelLongTap()<br/> // swipe<br/> if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) ||<br> (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30))<br> swipeTimeout = setTimeout(function() {<br> touch.el.trigger('swipe')<br> touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)))<br> touch = {}<br> }, 0)<br> // normal tap<br> else if ('last' in touch)<br> // don't fire tap when delta position changed by more than 30 pixels,<br> // for instance when moving to a point and back to origin<br> if (deltaX < 30 && deltaY < 30) {<br> // delay by one tick so we can cancel the 'tap' event if 'scroll' fires<br> // ('tap' fires before 'scroll')<br> tapTimeout = setTimeout(function() {<br> // trigger universal 'tap' with the option to cancelTouch()<br> // (cancelTouch cancels processing of single vs double taps for faster 'tap' response)<br> var event = $.Event('tap')<br> event.cancelTouch = cancelAll<br> touch.el.trigger(event)<br> // trigger double tap immediately<br> if (touch.isDoubleTap) {<br> if (touch.el) touch.el.trigger('doubleTap')<br> touch = {}<br> }<br> // trigger single tap after 250ms of inactivity<br> else {<br> touchTimeout = setTimeout(function(){<br> touchTimeout = null<br> if (touch.el) touch.el.trigger('singleTap')<br> touch = {}<br> }, 250)<br> }<br> }, 0)<br> } else {<br> touch = {}<br> }<br> deltaX = deltaY = 0<br> })<br> // when the browser window loses focus,<br> // for example when a modal dialog is shown,<br> // cancel all ongoing events<br> .on('touchcancel MSPointerCancel pointercancel', cancelAll)<br> // scrolling the window indicates intention of the user<br> // to scroll, not tap or swipe, so cancel all ongoing events<br> $(window).on('scroll', cancelAll)<br> })<br> ;['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown',<br> 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(eventName){<br> $.fn[eventName] = function(callback){ return this.on(eventName, callback) }<br> })<br>})(Zepto)</span>
zepto 소스 코드에 따르면 탭 이벤트가 터치 이벤트를 통해 문서를 시뮬레이션합니다. 따라서 사용자가 탭 이벤트(touchstart, touchend)를 클릭하면 트리거되기 전에 문서까지 버블링되어야 합니다. 단, 사용자는 터치시작 및 터치엔드 시 클릭 이벤트를 발생시키게 되는데 이때 클릭 이벤트는 300ms 동안 지연되며, 이 300ms 이내에 탭 이벤트가 완료되면 상위 요소가 삭제되거나 숨겨집니다. 300ms가 도달하면 클릭 이벤트의 원리에 따라(클릭 이벤트의 요소가 최상위에 있을 때 클릭 이벤트에 들어가게 되므로 z-index 설정을 잘못하면 클릭 이벤트가 발생하지 않는 경우도 있음), 하단 이벤트가 실행되어 관통 현상이 나타납니다. 하위 레이어를 입력 요소로 설정합니다. 클릭 이벤트가 바인딩되지 않더라도 기본 포커스가 팝업 키보드에 있기 때문에 침투 현상이 특히 심각합니다.
해결책:
1. 클릭 이벤트 실행 지연을 방지하기 위해 github에 fastclick 플러그인이 있습니다. 파일을 import한 후, 다음 코드를 추가하고, 침투를 유발할 수 있는 탭 이벤트 요소를 클릭으로 교체합니다.
$(function(){ new FastClick(document.body); })
$("#close").on("touchend",function(e){
$("#alertBox").hide();
e.preventDefault();
});
4. 하위 클릭 이벤트가 발생하지 않도록 상위 요소의 사라짐을 지연해 보세요. (iOS9.2의 WeChat 6.3.15에서 테스트했습니다.) 그러나 이는 약간 나쁜 경험입니다. CSS3 전환을 사용하여 경험을 개선할 수 있습니다.
setTimeout(function(){ $(#alertBox).hide(); } , 350 );
5. 모든 탭을 클릭으로 대체하세요. 경험 문제를 일으키는 클릭 지연으로 인해 fastclick 플러그인을 추가하는 것이 가장 좋습니다.
다음은 제가 작성한 간단한 예입니다. 휴대폰을 사용하여 http://property.pingan.com/app/test/jltest/tap-through.html?a=1
에 액세스할 수 있습니다. 예제를 통해 기본 버튼이 이벤트 침투 후 누르는 효과가 있음을 명확하게 볼 수 있습니다. 자주 테스트하는 동안 WeChat은 페이지를 캐시하고 즉시 수정된 콘텐츠를 볼 수 없기 때문에 a=1과 같은 쓸모없는 매개변수를 URL에 추가하여 브라우저가 다시 로드되도록 할 수 있습니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
<title>test-tap-through</title>
<script src="js/zepto.min.js" charset="utf-8"></script>
<style media="screen">
body{
margin: 0;
padding: 0;
}
.test1,.test2{
position: relative;
}
.button{
width: 90%;
height: 75px;
background-color: #00ffff;
margin: 5%;
line-height: 75px;
text-align: center;
font-size: 40px;
}
.box{
position: absolute;
top:0;
left: 0;
width: 50%;
height: 200px;
background-color: #ff00ff;
margin: 5%;
line-height: 100px;
text-align: center;
font-size: 40px;
z-index: 100;
}
</style>
</head>
<body>
<p>
<input type="button" id="button1" value="button1">
<input type="button" id="button2" value="button2">
<p id="box1" style="display:none">box1</p>
<p id="box2" style="display:none">box2</p>
</p>
<p>
<input type="button" id="button3" value="button3">
<input type="button" id="button4" value="button4">
<p id="box3" style="display:none">box3</p>
<p id="box4" style="display:none">box4</p>
</p>
</body>
<script type="text/javascript">
$("#button1").click(function(){
$("#box2").hide();
$("#box1").show();
});
$("#button2").click(function(){
$("#box1").hide();
$("#box2").show();
});
$("#box2").tap(function(){
$("#box2").hide();
});
$("#box1").tap(function(){
$("#box1").hide();
});
$("#button3").click(function(){
$("#box4").hide();
$("#box3").show();
});
$("#button4").click(function(){
$("#box3").hide();
$("#box4").show();
});
$("#box3").tap(function(){
setTimeout(function(){$("#box3").hide();},350);
});
$("#box4").tap(function(){
setTimeout(function(){$("#box4").hide();},350);
});
</script>
</html>
추천 자료:
JS 객체 속성 및 메서드에 액세스하는 방법Yuanshengcss3을 사용하여 링 로딩 진행률 표시줄을 구현하는 방법위 내용은 Zepto 탭 이벤트 침투 및 포인트 침투 사용법(코드 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!