> 웹 프론트엔드 > JS 튜토리얼 > Zepto 탭 이벤트 침투 및 포인트 침투 사용법(코드 포함)

Zepto 탭 이벤트 침투 및 포인트 침투 사용법(코드 포함)

php中世界最好的语言
풀어 주다: 2018-06-04 11:16:49
원래의
2203명이 탐색했습니다.

이번에는 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 ? &#39;Left&#39; : e.velocityY > 1 ? 'Down' : e.velocityY < -1 ? &#39;Up&#39; : null;<br/>                if (swipeDirectionFromVelocity) {<br/>                    touch.el.trigger(&#39;swipe&#39;)<br/>                    touch.el.trigger(&#39;swipe&#39;+ swipeDirectionFromVelocity)<br/>                }<br/>            })<br/>            .on(&#39;touchstart MSPointerDown pointerdown&#39;, function(e){<br/>                if((_isPointerType = isPointerEventType(e, &#39;down&#39;)) &&<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&#39;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 = $(&#39;tagName&#39; 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(&#39;touchmove MSPointerMove pointermove&#39;, function(e){<br/>                if((_isPointerType = isPointerEventType(e, &#39;move&#39;)) &&<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(&#39;touchend MSPointerUp pointerup&#39;, function(e){<br/>                if((_isPointerType = isPointerEventType(e, &#39;up&#39;)) &&<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); })
로그인 후 복사

2 탭이나 터치스타트 대신 터치엔드 이벤트를 수신하고 버블링을 방지합니다

$("#close").on("touchend",function(e){
$("#alertBox").hide();
e.preventDefault();
});
로그인 후 복사

3. css3 포인터 이벤트: true와 포인터 이벤트 없음을 번갈아 사용하여 하위 요소를 설정하고 방지합니다. .클릭 이벤트를 실행합니다.

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>
로그인 후 복사
이 기사의 사례를 읽으신 후 방법을 마스터하셨다고 생각합니다. 더 흥미로운 정보를 보려면 PHP 중국어 웹사이트의 다른 관련 기사를 주목하세요!

추천 자료:

JS 객체 속성 및 메서드에 액세스하는 방법


Yuanshengcss3을 사용하여 링 로딩 진행률 표시줄을 구현하는 방법

위 내용은 Zepto 탭 이벤트 침투 및 포인트 침투 사용법(코드 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿