停止 jQuery Mobile 滑动事件双冒泡

Posted

技术标签:

【中文标题】停止 jQuery Mobile 滑动事件双冒泡【英文标题】:Stop jQuery Mobile swipe event double bubbling 【发布时间】:2012-04-03 13:45:21 【问题描述】:

我在 iPad Safari 上有 jQuery Mobile,由于某种原因,触摸滑动事件触发了两次。

人们在过去一年和本周都报告了同样的问题,但我找不到关于如何在不修改 jQuery Mobile 的情况下修复双重事件的解释,我不想这样做。 Thread on jQuery forums

滑动处理程序的以下元素绑定都具有相同的错误双事件结果,即每次滑动都会调用两次警报。

jQuery Mobile 触摸事件应该如何绑定才能避免双重冒泡?

// Test 1: Binding directly to document with delegate()
$(document).delegate(document, 'swipeleft swiperight', function (event) 
    alert('You just ' + event.type + 'ed!');
);


// Test 2: Binding to document with on() handler recommended as of 1.7 with and without preventDefault
$(document).on('swipeleft',function(event, data)
    event.preventDefault();
    alert('You just ' + event.type + 'ed!');
);


// Test 3: Binding to body with on() with and without event.stopPropagation 
$('body').on('swipeleft',function(event, data)
   event.stopPropagation();
   alert('You just ' + event.type + 'ed!');
);


// Test 4: Binding to div by class
$('.container').on('swipeleft',function(event, data)
   event.stopPropagation();
   alert('You just ' + event.type + 'ed!');
);

【问题讨论】:

【参考方案1】:

event.stopImmediatePropagation() 是诀窍,它与 stopPropagation() 不同。确保在 document.ready 中调用 jQuery on() 方法似乎有所帮助。我可以使用任何元素选择器来绑定事件,包括使用向上滑动和从here向下滑动。

$(document).ready(function()    
    $(document).on('swipeleft swiperight swipedown swipeup',function(event, data)
        event.stopImmediatePropagation();
        console.log('(document).Stop prop: You just ' + event.type + 'ed!');
    );
);

【讨论】:

我把它放在$(document).bind('pageinit') 下,它不起作用。我必须在每个滑动事件处理程序中输入 event.stopImmediatePropagation(); 才能使其工作 这是有道理的。您的滑动事件触发了两次,需要使用stopImmediatePropagation() 停止,就像上面的答案一样。 pageinit 事件不是双重冒泡,因此不需要手动停止。 pageinit 每页只应触发一次,但它会为每个动态添加的页面再次触发。 这似乎比其他解决方案效果更好,尽管我仍然在 swiperight 上遇到一些奇怪的行为......我的 android 4.x 之前有几个(随机?)页面有点疯狂它落在正确的位置。 很高兴这是朝着正确方向迈出的一步。这种奇怪的行为听起来不像是滑动事件触发了两次。在没有看到任何东西的情况下,我的第一个想法是 jQuery 努力在滑动动画发生之前计算序列中所有页面的尺寸。尽管它与响应式设计不一致,但通过向块元素(如图像)添加固定的高度和宽度,我获得了更好的动画效果。我认为它有助于动画数学。【参考方案2】:

好吧,滑动事件有同样的问题被调用了两次。 解决方法是这样绑定事件:

$(document).on('swipeleft', '#div_id',  function(event)
    //console.log("swipleft"+event);
    // code 
);

【讨论】:

感谢分享。我想知道是否未能将容器作为参数调用on 一次在任何被刷过的容器上,然后立即再次在文档上。 嗡嗡声可能是问题所在……不知道究竟会发生什么。但是在 Document 下面的级别上附加滑动时会出现问题。 这个帮助了我。实际上,我只是测试了使用 swipeleft 绑定到文档而不是 swiperight,这导致两个事件都触发了两次。正如预期的那样,我还将它更改为 swiperight 的那一刻,两个事件都触发了一次。 (并且不需要 event.stopImmediatePropagation())。【参考方案3】:

这对我来说也确实有帮助。我试图用移动 jquery 滑动页面并且滑动事件(左和右)被触发了几次。 event.stopImmediatePropagation() 它就像一个魅力。谢谢 !!

这是我的代码。

<script type="text/javascript"> 
    $(document).bind( 'pageinit', function(event)  
        $("div:jqmData(role='page')").live('swipeleft swiperight',function(event)
            if (event.type == 'swipeleft')  
                var prev = $(this).prev("div:jqmData(role='page')");
                if(typeof(prev.data('url')) !='undefined') 
                    $.mobile.changePage(prev.data('url'),  transition: 'slide', reverse: false);
                    event.stopImmediatePropagation();
                
            
            if (event.type == 'swiperight')  
                var next = $(this).next("div:jqmData(role='page')"); 
                if(typeof(next.data('url')) != 'undefined') 
                    $.mobile.changePage(next.data('url'),  transition: 'slide', reverse: false);
                    event.stopImmediatePropagation();
                                   
                       
        );
    ); 
    </script>

html -

<div data-role="page" id="page1" data-url="#page1"> 
    <div data-role="content">
        <div>
        <h1> Page 1 </h1>
        <p>I'm first in the source order so I'm shown as the page.</p>      
        <p>View internal page called</p>    
            <ul data-role="listview" data-inset="true" data-theme="c">
                <li>Swipe Right to view Page 2</li>
            </ul>
        </div>
    </div>
</div>
<div data-role="page" id="page2" data-url="#page2"> 
    <div data-role="content">
        <div>
        <h1> Page 2 </h1>
        <p>I'm first in the source order so I'm shown as the page.</p>      
        <p>View internal page called</p>    
            <ul data-role="listview" data-inset="true" data-theme="c">
                <li>Swipe Right to view Page 3</li>
            </ul>
        </div>
    </div>
</div>

【讨论】:

以上是关于停止 jQuery Mobile 滑动事件双冒泡的主要内容,如果未能解决你的问题,请参考以下文章

mobile_竖向滑屏_rem适配

将 HTML 动态附加到 Div 后,Jquery Mobile Slider 不滑动

jQuery Mobile 面板不应该在向左滑动时关闭

如何在jQuery Mobile中向上滑动并向下滑动事件? [重复]

Windows Phone 上的 JQuery Mobile 滑动事件

jQuery Mobile 滑动事件不起作用