如何阻止动态元素在 Jquery/Jquery Mobile 中重新绑定?

Posted

技术标签:

【中文标题】如何阻止动态元素在 Jquery/Jquery Mobile 中重新绑定?【英文标题】:How to block dynamic elements from being re-bound to in Jquery/Jquery Mobile? 【发布时间】:2013-03-03 03:50:32 【问题描述】:

我通常会阻止多次绑定到这样的元素:

$(document)
    .find('.ui-input-search input')
    .filter(function()  return $(this).jqmData('bound') !== true; )
    .jqmData('bound', true)
    .on('change keyup', function (e) 
        //do sth
    );

当元素在页面上并且“准备好使用”时效果很好。

问题是,我想对动态添加到页面的元素做同样的事情。在这些元素上,JQM 在某些情况下不会增强元素,因此绑定到正在创建的元素有时不起作用。

问题: 如果我不想在 pagehide 上取消绑定,我将如何更改上述代码以在设置绑定后也锁定元素?

所以我想做这样的事情:

$(document).on('change keyup','.ui-input-search input', function (e) 
  // bind to the selector only once
);

但我不能使用:not选择器.ui-input-search input:not(.bound)因为IE,所以我很好奇:

感谢您的反馈!

【问题讨论】:

为什么因为IE不能使用:not选择器? 因为需要支持IE8 - caniuse :not 不是CSS,不是jQuery。 刚刚也学到了。 【参考方案1】:

但我不能使用 :not 选择器 .ui-input-search input:not(.bound) 因为是IE,所以很好奇:

引用the browser support page:

不管浏览器是否支持 CSS 选择器,所有选择器 在api.jquery.com/category/selectors/ 列出的将返回正确的 作为 jQuery 函数的参数传递时的一组元素。

无论浏览器的 CSS 引擎是否支持该选择器,您都可以在使用 jQuery 形成集合时使用 :not 选择器。

【讨论】:

酷!不知道。谢谢【参考方案2】:

有几种方法,你可以在我的其他ARTICLE中找到它们,或者找到它们HERE。只需搜索章节:Prevent multiple event triggering

防止多事件触发

由于有趣的 jQM 加载架构,多事件触发一直是个问题。例如,看看这段代码:

$('#index').live('pagebeforeshow',function(e,data)    
    $('#test-button').live('click', function(e) 
        alert('Button click');
    );    
);

或者你可以在这里测试:http://jsfiddle.net/Gajotres/yWTG2/

每次访问页面#index点击事件都会绑定到按钮#test-button。有几种方法可以防止此问题:

解决方案 1:

在绑定之前移除事件:

$('#index').live('pagebeforeshow',function(e,data)    
    $('#test-button').die().live('click', function(e) 
        alert('Button click');
    );    
);

如果你有不同的事件绑定到一个对象:

$('#index').live('pagebeforeshow',function(e,data)    
    $('#test-button').die('click').live('click', function(e) 
        alert('Button click');
    );    
);

解决方案 2:

使用 jQuery 过滤器选择器,如下所示:

$('#carousel div:Event(!click)').each(function()
    //If click is not bind to #carousel div do something
);

因为事件过滤器不是官方 jQuery 框架的一部分,所以可以在这里找到:http://www.codenothing.com/archives/2009/event-filter/

简而言之,如果您主要关心的是速度,那么解决方案 2 比解决方案 1 好得多。

解决方案 3:

一个新的,可能是其中最简单的一个。

$(document).on('pagebeforeshow', '#page', function(event)  
    if(event.handled !== true) // This will prevent event triggering more then once
    
        // Some code
        event.handled = true;
    
    return false;                
);

Tnx 到 sholsinger 以获取此解决方案:http://sholsinger.com/archive/2011/08/prevent-jquery-live-handlers-from-firing-multiple-times/

pageChange 事件怪癖 - 触发两次

有时pagechange事件会触发两次,和前面提到的问题没有任何关系。

pagebeforechange 事件发生两次的原因是由于在 toPage 不是 jQuery 增强的 DOM 对象时 changePage 中的递归调用。这种递归是危险的,因为允许开发人员在事件中更改 toPage。如果开发人员始终将 toPage 设置为字符串,则在 pagebeforechange 事件处理程序中,无论它是否是一个对象,都会导致无限递归循环。 pageload 事件将新页面作为数据对象的 page 属性传递(这应该添加到文档中,当前未列出)。因此,pageload 事件可用于访问加载的页面。

简而言之,这是因为您正在通过 pageChange 发送附加参数。

例子:

<a data-role="button" data-icon="arrow-r" data-iconpos="right" href="#care-plan-view?id=9e273f31-2672-47fd-9baa-6c35f093a800&amp;name=Sat"><h3>Sat</h3></a>

结论

3 号下的解决方案是您的最佳选择。绑定和解除绑定可能需要处理。

【讨论】:

不错!感谢您提供详细信息!【参考方案3】:

我通常使用命名空间。

$('.selector').unbind('change.namespace').bind('change.namespace', function () 

由于我使用命名空间绑定它,我可以将它从具有该命名空间的所有元素中删除,而无需担心删除其他处理程序。

【讨论】:

是的,但这需要另一个“解除绑定”,我不想使用(绑定/解除绑定太多)。我只想设置一次。

以上是关于如何阻止动态元素在 Jquery/Jquery Mobile 中重新绑定?的主要内容,如果未能解决你的问题,请参考以下文章

如何制作 div,由 jquery 在 woocommerce 结帐表单、动态或完全在表单内添加?

jquery如何定位倒数第二个元素,如一个div里有5个ul,那jquery如何才能锁定到倒数第二个ul

为动态添加的元素绑定事件

jQuery 小部件。如何取当前的可修改元素?

如何通过jquery隐藏和显示元素

最简单冒泡事件及阻止冒泡事件