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

How to attach one event listener to many objects?

我正在将 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

如果您的所有其他对象都有一个父元素,您可以这样做:

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

如果不行,试试逗号分隔'.elemClass1, .elemClass2, .elemClass3'

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

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

简单直接的解决方案:

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

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

希望对您有所帮助