如何将一个事件监听器附加到许多对象?

时间:2015-05-28 02:16:36

标签: javascript events listener

我将jQuery选择器缓存到对象上:

var a = {x:1};
var b = {y:2};

a.$btn = $('<div/>').addClass('button').appendTo('body').find('.button');
b.$btn = $('<div/>').addClass('button').appendTo('body').find('.button');

$('.button').on('click', function(e){ doSomething(e); });

是否可以使用单个事件监听器并更改a.x或b.y?

编辑:我目前正在为每个创建的对象添加事件,这些事件有效,但似乎效率低下:

a.$btn.on('click', function(e) { doSomething.call(this,e); }.bind(this));

编辑2:jsfiddle

2 个答案:

答案 0 :(得分:1)

您可以为每个创建的按钮分配处理程序,或使用@ user2182349所述的event delegation

但是,事件委托并不能解决单个处理程序的上下文问题。我看到两种解决方案。

简单直接的解决方案:

切换层次结构:已创建的按钮应具有对象的引用。例如:

a.$btn = $('<div/>').addClass('button').appendTo('body').find('.button');
a.$btn.object = a;
$('.button').on('click', function(e){ doSomething.call(e.target.object, e); });

还有另一个更复杂的解决方案。这会阻止您修改对象结构。如果您拥有已创建对象的池,则可以对其进行迭代并通过按钮找到父对象。

var pool = [a, b];
function findObject(button){
    for (var obj in pool){
        if(obj.$btn === button){
            return obj;
        }
    }
    return null;
}
function handler(e){
    var obj = findObject(e.target);
    if(obj){
         doSomething.call(obj, e);
    }
}

修改

关于来自更新的OP的JSFiddle:

var a = b = Object.create(null);
a.x = 1;
b.y = 2;

只创建1个(一个!)对象和两个引用它的变量。因此,您最终会得到一个包含两个属性的对象:xy。 看一下更新的fiddle

希望这有帮助

答案 1 :(得分:0)

如果你有所有其他对象的父元素,你可以这样做:

$('#parent').on('click', '.elemClass1 .elemClass2 .elemClass3',function(e){ doSomething(e); });

如果不起作用,请尝试用逗号分隔'.elemClass1, .elemClass2, .elemClass3'