jQuery Mobile - 事件发射两次

时间:2014-06-06 10:54:54

标签: jquery-mobile

我知道这是一个已知问题,我尝试过stopPropagation解决方案。它不起作用。我很困惑为什么会发生这种情况(我不明白为什么会这样)。无论如何,这是代码。

我有一个jQM按钮:

<a href="#" id="glossary_option1" class="ui-btn ui-btn-right ui-btn-icon-notext ui-nodisc-icon ui-alt-icon">No text</a> 

我使用此代码来打开和关闭它:

$("#glossary_option2").click(function(){
  toggleGlos();
});

这调用了这个函数,最终也会被glossary_option2,3和4调用(因此我有了函数)

function toggleGlos() {
    if (localStorage.glossaryopt === "off") {
        $("#glossary_option1").removeClass("ui-icon-nobook").addClass("ui-icon-book");
        $("#glossary_option2").removeClass("ui-icon-nobook").addClass("ui-icon-book");
        $("#glossary_option3").removeClass("ui-icon-nobook").addClass("ui-icon-book");
        $("#glossary_option4").removeClass("ui-icon-nobook").addClass("ui-icon-book");
        console.log(localStorage.glossaryopt);
        localStorage.glossaryopt = "on";
        $(".glossaryLink").css({
            "color": "white",
                "background-color": "#CC8DCC",
                "border": "1px solid white",
                "padding": "0px 4px",
                "font-size": "0.9em"
        });
    } else {
        localStorage.glossaryopt = "off";
        $("#glossary_option1").removeClass("ui-icon-book").addClass("ui-icon-nobook");
        $("#glossary_option2").removeClass("ui-icon-book").addClass("ui-icon-nobook");
        $("#glossary_option3").removeClass("ui-icon-book").addClass("ui-icon-nobook");
        $("#glossary_option4").removeClass("ui-icon-book").addClass("ui-icon-nobook");
        console.log(localStorage.glossaryopt);
        $(".glossaryLink").css({
            "color": "black",
                "background-color": "white",
                "border": "none",
                "padding": "0",
                "font-size": "1em"
        });
    }
}

每次单击按钮,此功能的两个部分都会触发。如控制台日志所示,glossaryopt已打开然后关闭。

我知道这是一个已知的问题,但是。我无法解决它而且b。我已经做了很多次这样的事情。为什么现在不工作?

1 个答案:

答案 0 :(得分:3)

防止多事件绑定/触发

jQuery Mobile 的工作方式与经典网络应用程序不同。根据您每次访问某个页面时设置绑定事件的方式,它会反复绑定事件。这不是错误,只是 jQuery Mobile 处理其网页的方式。例如,看一下这段代码snipet:

$(document).on('pagebeforeshow','#index' ,function(e,data){    
    $(document).on('click', '#test-button',function(e) {
        alert('Button click');
    });    
});

使用jsFiddle示例:http://jsfiddle.net/Gajotres/CCfL4/

每当您访问 #index 页面时,点击事件将被绑定到按钮 #test-button 。通过从第1页移动到第2页并返回几次来测试它。有几种方法可以防止这个问题:

解决方案1 ​​

最佳解决方案是使用 pageinit 绑定事件。如果您查看官方文档,您会发现 pageinit 只会触发一次,就像文档就绪一样,所以事件不会再被绑定。这是最好的解决方案,因为您没有像使用off方法删除事件时那样的处理开销。

使用jsFiddle示例:http://jsfiddle.net/Gajotres/AAFH8/

这个有效的解决方案是基于之前的一个有问题的例子。

解决方案2

在绑定事件之前删除事件:

$(document).on('pagebeforeshow', '#index', function(){       
    $(document).off('click', '#test-button').on('click', '#test-button',function(e) {
        alert('Button click');
    }); 
});

使用jsFiddle示例:http://jsfiddle.net/Gajotres/K8YmG/

解决方案3

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

$('#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好得多。

解决方案4

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

$(document).on('pagebeforeshow', '#index', function(){       
    $(document).on('click', '#test-button',function(e) {
        if(e.handled !== true) // This will prevent event triggering more then once
        {
            alert('Clicked');
            e.handled = true;
        }
    }); 
});

使用jsFiddle示例:http://jsfiddle.net/Gajotres/Yerv9/

最后的注释

你最好的选择是:

$(document).off('click',"#glossary_option2").on('click',"#glossary_option2", function(){
    toggleGlos();
});