JQuery事件模型和防止重复处理程序 [英] JQuery event model and preventing duplicate handlers

查看:133
本文介绍了JQuery事件模型和防止重复处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

再次,我想使用$(divid)将一个包含自己的脚本的页面加载到div中。load(...)。我遇到的问题与事件有关。假设我们从父页面和我们绑定的加载页面(猴子)触发(猴子),并且只做一个警报(猴子绑定)。如果多次调用相同的加载方法,则会多次调用绑定。现在我可以在绑定之前解除绑定,或者在绑定之前检查处理程序的数量,然后不绑定它,以防止这种情况。两个选项都是可扩展的,如果我以后想要绑定到另一个子页面(页面加载到div中)的触发器。



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

  //发现这个StackOverflow 
函数getFunctionName(fn)
{
var rgx = / ^ function\s +([^ \(\s)+)/
var matches = rgx。 exec(fn.toString());
返回匹配匹配[1]:(匿名)
}

函数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 (处理程序)== handlerName){
exists = true;
}
});
}
}
返回存在;
}

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

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

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

解决方案

这不是一个完整的答案,但是我很快发现如何用最小的更改来修复所有的代码。在我的基础js类(这是一个对象,每个页面上使用标准按钮连接按类名称等)我添加了以下方法来检查dupe处理程序:

  BindOnce:function(triggerName,fn){
function handlerExists(triggerName,theHandler){
function getFunctionName(fn){
var rgx = / ^ function\s +([^ \(\s)+)/
var matches = rgx.exec(fn.toString());
返回匹配匹配[1] :(匿名)
}
exists = false;
var handlerName = getFunctionName(theHandler);
if($(document).data('events')!= =未定义){
var event = $(document).data('events')[triggerName];
if(event!== undefined){
$ .each(event,function (i,handler){
if(getFunctionName(handler)== handlerName){
exists = true;
}
});
}
}
返回存在;
}
if(!handlerExists(triggerName,fn)){
$(document).bind(triggerName,fn);
}
},

然后我只是调用它而不是绑定方法!

  $。mystuff.BindOnce(TheTrigger,OnTriggered)

请注意,您不能在这里使用anon方法,因为它们将被称为1,2,3等,唯一的方式来检查重复是使用toString()方法,这在复杂的应用程序中是相当缓慢的


Once again I want to load a page which contains its own script into a div using $("divid").load(...). The problem I face is related to events. Let's say we trigger("monkey") from the parent page and on the loaded page we bind("monkey") and just do an alert("monkey bound"). If the same load method is called multiple times, the bind is called multiple times. Now I could just unbind it before I bind it, or check the number of handlers before the bind and then not bind it to prevent this. Neither option is scalable as what if I later want to bind to that trigger in another "sub page" (a page loaded into a div).

What I ideally want to do then is check if the handler I am about to add already exists, but I still WANT to use anonymous handlers... (asking a bit much with that last request I think). Currently I have a workaround by using pre-defined/named methods and then checking this before the bind.

// 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;
    }

This is a pretty crude way of going about it I feel, but appears to work. I just do the following before the bind as follows:

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

Does anyone have a more elegant solution? for instance, is there any way to check a particular script is loaded? so I could use getScript() to load the js from the child page on first load, and then simply not load it on subsequent loads (and just fire a trigger which would be handled by he preexisting js)..

解决方案

This isn't a full answer, but I quickly found how to fix all my code with minimal changes. In my "base" js class (this is an object which is used on every page for standard button hookups by class name etc) I added the following method which does the check for dupe handlers:

BindOnce: function(triggerName, fn) {
    function handlerExists(triggerName, theHandler) {
        function getFunctionName(fn) {
            var rgx = /^function\s+([^\(\s]+)/
            var matches = rgx.exec(fn.toString());
            return matches ? matches[1] : "(anonymous)"
        }
        exists = false;
        var handlerName = getFunctionName(theHandler);
        if ($(document).data('events') !== undefined) {
            var event = $(document).data('events')[triggerName];
            if (event !== undefined) {
                $.each(event, function(i, handler) {
                    if (getFunctionName(handler) == handlerName) {
                        exists = true;
                    }
                });
            }
        }
        return exists;
    }
    if (!handlerExists(triggerName, fn)) {
        $(document).bind(triggerName, fn);
    }
},

Then I just invoke it instead of the bind method!

$.mystuff.BindOnce("TheTrigger", OnTriggered)

Note that you can't use anon methods here as they would just be called 1, 2, 3 etc and the only way to check for dupes would be with a toString() on the method, which would be pretty slow in a complex application

这篇关于JQuery事件模型和防止重复处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆