JQuery事件模型和防止重复处理程序

前端之家收集整理的这篇文章主要介绍了JQuery事件模型和防止重复处理程序前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
再次,我想加载一个包含自己的脚本的页面,使用$(“divider”)加载(…)。我遇到的问题与事件有关。假设我们从父页面和我们绑定的加载页面(“猴子”)触发(“猴子”),并且只做一个警报(“猴子绑定”)。如果多次调用相同的加载方法,则会多次调用绑定。现在我可以在绑定之前解除绑定,或者在绑定之前检查处理程序的数量,然后不要绑定它,以防止这种情况。两个选项都是可扩展的,如果我以后想在另一个“子页面”(加载到div中的页面)绑定到该触发器。

我最理想的做法是检查我即将添加的处理程序是否已经存在,但是我仍然希望使用匿名处理程序…(对于我最后的请求,请问一点)。目前我有一个解决方法使用预定义/命名方法,然后在绑定之前检查它。

// Found this on StackOverflow
function getFunctionName(fn)
{
 var rgx = /^function\s+([^\(\s]+)/
 var matches = rgx.exec(fn.toString());
 return matches ? matches[1] : "(anonymous)"
}

function HandlerExists(triggerName,handlerName) {
        exists = false;
        if ($(document).data('events') !== undefined) {
            var event = $(document).data('events')[triggerName];
            if(event !== undefined)
            {
                $.each(event,function(i,handler) {
                    alert(handlerName);
                    if (getFunctionName(handler) == handlerName) {
                        exists = true;
                    }
                });
            }
        }
        return exists;
    }

这是一个非常粗暴的方式,我觉得,但似乎工作。我只是在绑定之前执行以下操作:

if (!HandlerExists("test","theMethod")) {
    $(document).bind("test",theMethod);
}

有人有更优雅的解决方案吗?例如,有没有办法检查特定的脚本是否加载?所以我可以使用getScript()在第一次加载时从子页面加载js,然后只是在后续的加载时加载它(并且只需触发一个由他预先存在的js处理的触发器)。

解决方法

使用jQuery的事件命名空间防止重复绑定

实际上有几种防止重复的不同方法。一个只是将原来的处理程序传递给unbind,但如果它是一个副本,而不是内存中的相同空间,它将不会解除绑定,另一个流行的方式(使用命名空间)是一种更确定的方法

这是事件的常见问题。所以我会解释一下jQuery事件,并使用命名空间来防止重复的绑定。

答案:(短而直)

// bind handler normally
$('#myElement').bind('myEvent',myMainHandler);

// bind another using namespace
$('#myElement').bind('myEvent.myNamespace',myUniqueHandler);

// unbind the unique and rebind the unique
$('#myElement').unbind('myEvent.myNamespace').bind('myEvent.myNamespace',myUniqueHandler);
$('#myElement').bind('myEvent.myNamespace',myUniqueHandler);

// trigger event
$('#myElement').trigger('myEvent');

// output
myMainHandler() // fires once!
myUniqueHandler() // fires once!

答案示例:(详细说明)

首先让我们创建一个要绑定的示例元素。我们将使用ID为#button的按钮。然后使3个函数可以和将被用作处理程序来绑定到事件:

函数exampleOne()我们将绑定一下。
函数exampleTwo()我们将绑定到点击的命名空间。
函数exampleThree()我们将绑定到点击的namepsace,但是解除绑定并绑定多次,而不会删除其他绑定,从而防止重复绑定,而不删除任何其他绑定的方法

示例开始:(创建要绑定的元素和一些方法作为我们的处理程序)

<button id="button">click me!</button>


// create the example methods for our handlers
function exampleOne(){ alert('One fired!'); }
function exampleTwo(){ alert('Two fired!'); }
function exampleThree(){ alert('Three fired!'); }

绑定示例单击一下:

$('#button').bind('click',exampleOne); // bind example one to "click"

现在如果用户单击按钮或调用$(‘#button’)。触发(‘点击’),您将收到警报“One Fired!”;

绑定示例两个命名空间的点击:“名称是任意的,我们将使用myNamespace2”

$('#button').bind('click.myNamespace2',exampleTwo);

这个很酷的事情是,我们可以触发“点击”,这将触发exampleOne()和exampleTwo(),或者我们可以触发“click.myNamespace2”,这样只会触发exampleTwo()

绑定示例三到点击的命名空间:“再次,名称是任意的,只要它与exampleTwo的命名空间不同,我们将使用myNamespace3”

$('#button').bind('click.myNamespace3',exampleThree);

现在,如果“click”被触发,所有三个示例方法将被触发,或者我们可以定位一个特定的命名空间。

将其全部丢弃,以防止重复

如果我们继续绑定exampleThree()像这样:

$('#button').bind('click.myNamespace3',exampleThree); 
$('#button').bind('click.myNamespace3',exampleThree);
$('#button').bind('click.myNamespace3',exampleThree);

他们会被解雇三次,因为每次调用绑定时,都将它添加到事件数组中。那么真的很简单在绑定之前,为该命名空间解除绑定,如下所示:

$('#button').unbind('click.myNamespace3').bind('click.myNamespace3',exampleThree);
$('#button').unbind('click.myNamespace3').bind('click.myNamespace3',exampleThree);

如果触发点击功能,则exampleOne(),exampleTwo()和exampleThree()只会被触发一次。

用一个简单的功能把它全部包装起来:

var myClickBinding = function(jqEle,handler,namespace){
    if(namespace == undefined){
        jqEle.bind('click',handler);
    }else{
        jqEle.unbind('click.'+namespace).bind('click.'+namespace,handler);
    }
}

概要:

jQuery事件命名空间允许绑定到主事件,但是还允许创建和清除子命名空间,而不会影响兄弟命名空间或父级命名空间,而极少的创造性思维允许防止重复的绑定。

进一步说明:http://api.jquery.com/event.namespace/

猜你在找的jQuery相关文章