如何在 JavaScript for 循环中绑定委托事件
How to bind delegated events within JavaScript for-loop
我有一个对象数组,我正在使用标准 JavaScript for 循环遍历这些对象。我正在尝试使用 jQuery 在循环中为这些对象中的每一个创建委托事件。每个对象都有一个 eventType
属性,它可以是任何自定义事件,还有一个 el
属性,它是一个代表 CSS 选择器的字符串元素。使用委托事件的要点是我想将事件绑定到 body
或 document
这样如果 DOM 中不存在元素,它仍然会得到正确的事件处理程序。下面是一些伪代码:
// Fn that does the looping (all of this in large prototype definition)
trackAll: function(callback) {
for (var i = 0, l = this.dataSet.length; i < l; i++) {
var current_object = this.dataSet[i];
// Validate properties first (check for errors)
this.propertyCheck(current_object);
// Then run the tracking
if (callback && typeof callback === 'function') {
this.autoTracker(current_object, callback);
} else {
this.autoTracker(current_object);
}
}
}
上面的dataSet
是对象数组。每个对象都有这样的足迹:
{
trackType: 'event',
el: '.some_class li > a',
page: 'Homepage',
type: 'Custom description',
label: window.location.href,
eventType: 'click',
bodyClass: null,
row: null
}
所以这个特定的对象引用一个特定的锚点 link 作为它的元素,trackType
为 'event' 并且 eventType
为 'click'
最终,dataSet
数组中会有许多这些对象,我正在尝试循环并为每个对象创建事件 listeners/handlers。这是处理此问题的更多伪代码:
autoTracker: function(config, callback) {
var self = this;
if (config.el !== null && config.el !== 'undefined') {
config.el = $(config.el);
if (config.trackType.toLowerCase() === 'event' || config.trackType.toLowerCase() === 'pageview') {
$(document).on(config.eventType, config.el, function(e) {
console.log('fired!'); //=> this fires for ALL items in the array on ONE single click (or whatever eventType)
});
if (callback && typeof callback === 'function') {
callback.apply(config); //=> keep reference to `config` object in callback
}
}
}
}
因此,在 trackAll
函数(调用此 autoTracker
函数)中可以看到循环内的 dataSet
数组中的每个对象都会调用上述函数。问题是 $(document).on(config.eventType, config.el, function(e) { ... });
的处理程序回调中的 运行 会立即为数组中的每个项目获取 运行 。换句话说,例如单击 body
将立即触发数组中每个对象的处理程序。
如何在循环中使用绑定到 body
或 document
的事件正确创建委托事件,这样它就不会同时触发每个事件?我觉得存在变量范围问题,我能够使用闭包和 .bind()
在循环内成功创建和绑定事件,但这只会将事件直接绑定到元素,因此当函数 运行s。这不是我想要做的。我需要使用委托事件,这样如果元素不立即存在于 DOM 中,它们仍然可以获得 events/handlers。这里有什么想法吗?
.on() 的第二个参数应该是字符串,而不是 jquery 对象。
一些评论:
更改 属性 的类型,例如 config.el = $(config.el);
会使代码难以推理。
而且,这一切似乎都有些迂回。一种更常见的模式是在创建需要事件处理程序的元素时将语义 class 名称放在它们上。喜欢<a class=clickable>
,然后.on(click, '.clickable')
。
我有一个对象数组,我正在使用标准 JavaScript for 循环遍历这些对象。我正在尝试使用 jQuery 在循环中为这些对象中的每一个创建委托事件。每个对象都有一个 eventType
属性,它可以是任何自定义事件,还有一个 el
属性,它是一个代表 CSS 选择器的字符串元素。使用委托事件的要点是我想将事件绑定到 body
或 document
这样如果 DOM 中不存在元素,它仍然会得到正确的事件处理程序。下面是一些伪代码:
// Fn that does the looping (all of this in large prototype definition)
trackAll: function(callback) {
for (var i = 0, l = this.dataSet.length; i < l; i++) {
var current_object = this.dataSet[i];
// Validate properties first (check for errors)
this.propertyCheck(current_object);
// Then run the tracking
if (callback && typeof callback === 'function') {
this.autoTracker(current_object, callback);
} else {
this.autoTracker(current_object);
}
}
}
上面的dataSet
是对象数组。每个对象都有这样的足迹:
{
trackType: 'event',
el: '.some_class li > a',
page: 'Homepage',
type: 'Custom description',
label: window.location.href,
eventType: 'click',
bodyClass: null,
row: null
}
所以这个特定的对象引用一个特定的锚点 link 作为它的元素,trackType
为 'event' 并且 eventType
为 'click'
最终,dataSet
数组中会有许多这些对象,我正在尝试循环并为每个对象创建事件 listeners/handlers。这是处理此问题的更多伪代码:
autoTracker: function(config, callback) {
var self = this;
if (config.el !== null && config.el !== 'undefined') {
config.el = $(config.el);
if (config.trackType.toLowerCase() === 'event' || config.trackType.toLowerCase() === 'pageview') {
$(document).on(config.eventType, config.el, function(e) {
console.log('fired!'); //=> this fires for ALL items in the array on ONE single click (or whatever eventType)
});
if (callback && typeof callback === 'function') {
callback.apply(config); //=> keep reference to `config` object in callback
}
}
}
}
因此,在 trackAll
函数(调用此 autoTracker
函数)中可以看到循环内的 dataSet
数组中的每个对象都会调用上述函数。问题是 $(document).on(config.eventType, config.el, function(e) { ... });
的处理程序回调中的 运行 会立即为数组中的每个项目获取 运行 。换句话说,例如单击 body
将立即触发数组中每个对象的处理程序。
如何在循环中使用绑定到 body
或 document
的事件正确创建委托事件,这样它就不会同时触发每个事件?我觉得存在变量范围问题,我能够使用闭包和 .bind()
在循环内成功创建和绑定事件,但这只会将事件直接绑定到元素,因此当函数 运行s。这不是我想要做的。我需要使用委托事件,这样如果元素不立即存在于 DOM 中,它们仍然可以获得 events/handlers。这里有什么想法吗?
.on() 的第二个参数应该是字符串,而不是 jquery 对象。
一些评论:
更改 属性 的类型,例如 config.el = $(config.el);
会使代码难以推理。
而且,这一切似乎都有些迂回。一种更常见的模式是在创建需要事件处理程序的元素时将语义 class 名称放在它们上。喜欢<a class=clickable>
,然后.on(click, '.clickable')
。