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/

相关文章

页面搜索关键词突出 // 页面搜索关键词突出 $(function () {...
jQuery实时显示日期、时间 html: &lt;span id=&quot...
jQuery 添加水印 &lt;script src=&quot;../../../.....
中文:Sys.WebForms.PageRequestManagerParserErrorExceptio...
1. 用Response.Write方法 代码如下: Response.Write(&q...
Jquery实现按钮点击遮罩加载,处理完后恢复 思路: 1.点击按...