Javascript事件addEventListener注册多次同一功能;使用OOP Javascript [英] Javascript event addEventListener registering multiple times for same function; using OOP Javascript

查看:244
本文介绍了Javascript事件addEventListener注册多次同一功能;使用OOP Javascript的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用面向对象的Javascript,与注册事件监听器一起使用。从我对事件侦听器的了解,如果应用于eventtarget的函数已经被注册,则重复尝试添加同一个事件侦听器将被忽略。换句话说,它只应该一次。但是下面的代码并不是这样(也可以在jsfiddle上看到)。

I'm employing Object-Oriented Javascript, in conjunction with registering event listeners. From what I understand about event listeners, if the function applied to eventtarget has already been registered, repeated attempts to add this same event listener will be ignored. In other words, it should only fire once. But that is not the case in the code below (also can be seen on jsfiddle).

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget.addEventListener


多个相同的事件侦听器

Multiple identical event listeners

如果在相同的EventTarget上注册了多个相同的EventListener,参数,重复的实例被丢弃。它们不会导致EventListener被调用两次,并且由于重复的数据被丢弃,所以不需要使用removeEventListener方法手动删除。

If multiple identical EventListeners are registered on the same EventTarget with the same parameters, the duplicate instances are discarded. They do not cause the EventListener to be called twice, and since the duplicates are discarded, they do not need to be removed manually with the removeEventListener method.

http://jsfiddle.net/qd1e8f6c/

HTML

<div id="wrapper">
    <input id="t1" type="text" />
    <input id="btn" type="button" />
</div>

JS

var namespace = namespace || {};

namespace.event = {
    addListener: function(el, type) {
        var handle = function() {
            switch (type) {
                case "focus": 
                    console.log(el.value);
                    break;
                case "click":
                    console.log(el.id + " was clicked");
                    break;
            }
        };

        el.addEventListener(type, handle, false);
    }
};

namespace.ExampleClass = function() {
    this.init = function(el1, el2) {
        el1.value = "123";
        el2.value = "Click Me";
    };
};

var textbox = document.getElementById("t1");
var button = document.getElementById("btn");

var inst = new namespace.ExampleClass();

inst.init( textbox, button );

namespace.event.addListener(textbox, "focus");
namespace.event.addListener(button, "click");

// same handle -- shoudln't it only add the event once?
namespace.event.addListener(textbox, "focus");
namespace.event.addListener(button, "click");

如上面代码的最后几行所示,一个名为 addListener 被执行两次,它向每个输入注册一个事件。然后,再次执行 addListener 。我期望它不会再注册并忽略,但它实际上注册。我不明白命名空间中名为 handle 的函数是完全相同的。我在这里做错了什么?

As you can see in the last few lines of the code above, a function called addListener is executed twice, which registers an event to each input. Then, addListener is executed again. I'm expecting it to not register again and ignore, but it actually registers. I don't get it. The function in the namespace called handle is exactly the same. What am I doing wrong here?

任何帮助都会很棒。非常感谢你。

Any help would be great. Thank you so much.

推荐答案

你不能将相同的类型/功能对绑定到元素。但是,这并不是您正在做的,您每次调用 namespace.addEventListener 处理程序函数c> function。

You cannot bind the same type/function pair to an element. However, that is not what you are doing, you are explicitly creating a new handler function on every call to your namespace.addEventListener function.

你有什么:

namespace.event = {
    addListener: function(el, type) {
        var handle = function() {
            switch (type) {
                case "focus": 
                    console.log(el.value);
                    break;
                case "click":
                    console.log(el.id + " was clicked");
                    break;
            }
        };

        el.addEventListener(type, handle, false);
    }
};

你会期待什么?

var handle = function(evt) {
    var el = evt.currentTarget;

    switch (type) {
        case "focus": 
            console.log(el.value);
            break;
        case "click":
            console.log(el.id + " was clicked");
            break;
    }
};

namespace.event = {
    addListener: function(el, type) {
        el.addEventListener(type, handle, false);
    }
};

因为只有一个句柄在第二种情况下。

because there is only one instance of handle in the second case.

您所拥有的是一种命名空间的方法,但最常见的是这些天JS命名空间是通过模块模式完成的。

What you have is one approach to namespacing, but most often these days, JS namespacing is done via the Module Pattern

对于你的例子,你甚至不会真正关心通过这个'namespace'变量使你的代码全局可访问,因为它只用在你的代码中,所以你可以do:

For your case for example, you don't even appear to really care about making your code globally accessible via this 'namespace' variable since it is only used in your code, so you could do:

var namespace = (function(){
    function handle(evt) {
        var el = evt.currentTarget;

        switch (type) {
            case "focus": 
                console.log(el.value);
                break;
            case "click":
                console.log(el.id + " was clicked");
               break;
        }
    };

    function addListener(el, type) {
        el.addEventListener(type, handle, false);
    }

    function ExampleClass() {
        this.init = function(el1, el2) {
            el1.value = "123";
            el2.value = "Click Me";
        };
    };

    var textbox = document.getElementById("t1");
    var button = document.getElementById("btn");

    var inst = new ExampleClass();

    inst.init( textbox, button );

    addListener(textbox, "focus");
    addListener(button, "click");


    // And if you do care about 'inst' being global, you'd explicitly add it to the window.
    window.inst = inst;

    // Whatever functions you want to expose as 'namespace' would go here.
    return {
        event: {
            addEventListener: addEventListener
        }
    };
})();

这篇关于Javascript事件addEventListener注册多次同一功能;使用OOP Javascript的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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