【问题标题】:how to properly unbind events in Jquery-Mobile using on/off when a page is kept in the DOM?当页面保存在 DOM 中时,如何使用 on/off 正确取消绑定 Jquery-Mobile 中的事件?
【发布时间】:2012-06-08 14:08:45
【问题描述】:

由于 Jquery Mobile 在导航时会在 DOM 中保留一些页面,因此在来回移动时可能会多次访问一个页面。

如果我要绑定到如下页面并在此绑定内执行我的所有页面逻辑,其中包括“嵌套元素绑定”:

// listener for the page to show:
$(document).on('pagebeforeshow.register', '#register', function() {

    // stuff

    // page event bindings:
    $(document).on('click.register', '.registerSubmitter', function(e) {
        // do something
        });
    });

来回移动会导致我的嵌套绑定被附加多次。

现在尝试像这样解决这个问题(不起作用......):

 $(document).on('click', '.registrySubmitter', function(e) {

         if ( $(this).attr('val') != true ) {
            $(this).attr('val') == true;
            // do something
            }
     });

所以我只允许第一个绑定通过,然后阻止所有其他绑定尝试。

虽然这可行,但远非最佳。

问题
事件绑定应该如何以及何时正确解除绑定/关闭?有没有一般的方法(杀死所有)还是我必须每次绑定都做这个绑定?也许更重要的是:在用户进入/离开页面时执行一次绑定并保留它或绑定/取消绑定在性能方面是否更好?

感谢您的意见!

编辑
所以我正在为我的所有事件命名空间,然后像这样监听 pageHide:

$(document).on('pagehide.register', '#register', function(){
   $(document).off('.registryEvents');
   });

虽然这似乎解除了绑定,但当我关闭页面上的自定义对话框/选择菜单时它也会触发,因此在离开页面之前我会失去绑定。所以部分答案,我应该使用 off(),但是如何绑定到真正离开的页面与打开和关闭选择菜单?

【问题讨论】:

    标签: javascript jquery events jquery-mobile unbind


    【解决方案1】:

    当您像这样使用.on() 时,您将事件处理委托给document 元素,这意味着您可以随时设置该委托事件绑定,因为document 元素始终可用。

    我有两个建议:

    • 使用pageinitpagecreate 事件仅在将页面添加到DOM 并初始化时运行特定于页面的绑定。使用这种方法,我不会在 pageinitpagecreate 事件处理程序中委托事件绑定,因为当它们触发时,伪页面上的所有元素都在 DOM 中:

    .

    $(document).on('pageinit', '#register', function() {
        //note that `this` refers to the `#register` element
        $(this).find('.registerSubmitter').on('click', function(e) {
            // do something
        });
    });
    
    • 绑定一次委托的事件处理程序,不用担心页面何时真正在 DOM 中:

    .

    //this can be run in the global scope
    $(document).on('click.register', '.registerSubmitter', function(e) {
        // do something
    });
    

    基本上,当您像您一样使用委托绑定事件时,添加事件处理程序的实际 CPU 占用较少,但每次调度事件(任何类型的冒泡事件)时,都必须检查它是否与委托匹配事件处理程序的选择器。

    当您直接绑定到元素时,执行实际绑定通常需要更多时间,因为每个单独的元素都必须绑定到而不是像事件委托那样绑定到 document 元素一次。然而,这样做的好处是除非特定元素接收到特定事件,否则不会运行任何代码。

    文档中的简要介绍:

    在初始化页面后触发。 我们建议绑定到此事件而不是 DOM ready(),因为这 无论页面是直接加载还是 作为 Ajax 导航的一部分,内容被拉入另一个页面 系统。

    来源:http://jquerymobile.com/demos/1.1.0/docs/api/events.html

    【讨论】:

    • 我认为 pageinit 只在应用程序初始化时运行一次。它会在添加每个新页面时运行吗?
    • 是的,它会在伪页面初始化的任何时候运行。
    • 我在 pagebeforeshow 中使用了您的第二个建议,当返回到注册页面时会导致多个绑定。那么我应该在全球范围内这样做吗?听起来很容易......
    • 如果您使用事件委托,请执行一次,不要将委托事件绑定放在另一个委托事件绑定中,因为每次将事件处理程序添加到 document 元素时,它们只会叠加。所以我的建议是将委托的事件绑定放在任何其他事件处理程序之外,或者使内部事件处理程序成为常规的.bind() 样式绑定,以便在从 DOM 中删除伪页面后它们不会持续存在(我喜欢这个方法)。
    • 这仍然很棘手,因为我正在加载一个页面,然后我根据用户的选择拉入表单。绑定到这些表单元素...需要重新考虑这一点。
    猜你喜欢
    • 2013-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多