我正在尝试在网站上添加一些委托事件,但我没有一个与传统侦听器回调签名(function( event ) {}
)匹配的函数,并且要获取当前的侦听元素,我需要将另一个参数传递给函数
这是我设法实现的目标:
const delegate = function( element, events, target, callback ) {
events.split( " " ).forEach( event => element.addEventListener( event, function( e ) {
let initiator;
if ( e.target && ( initiator = e.target.closest( target ) ) ) {
callback( e, initiator );
}
} ) );
};
let count = 0;
delegate( document, "click", ".js-test-delegate", function( event, elem ) {
elem.innerHTML = `you click on this container ${++count} time(s)`;
} );
const div = document.createElement("div")
div.classList.add( "js-test-delegate" );
document.querySelector( ".container" ) .appendChild( div );
.container{
width: 300px;
height: 300px;
background: rgba(256,0,0,.2);
}
.js-test-delegate{
width: 100px;
height: 100px;
position: relative;
top: 100px;
left: 100px;
background: rgba(0,256,0,.2);
}
<div class="container"></div>
是否可以通过方法在事件中传递elem
元素,以使他替换currentTarget
属性以使其行为更简单?
我尝试修改Event
,但是currentTarget
之类的属性是只读的,或者克隆事件event = new Event( "click", e)
但target
和currentTarget
暂时未设置。 / p>
当然,这需要在普通js中使用。
谢谢!
答案 0 :(得分:0)
使用.call()
调用以元素引用作为this
值的回调:
if ( e.target && ( initiator = e.target.closest( target ) ) ) {
callback.call(initiator, e);
}
在回调中,this
将引用“启动器”,并且您不需要其他参数。
答案 1 :(得分:0)
您可以将所需元素作为自定义属性添加到事件对象,如下所示:
const delegate = function( element, events, target, callback ) {
events.split(" ").forEach(event => element.addEventListener(event, function(e) {
let initiator = e.target.closest(target);
if (e.target && initiator) {
e.initiator= initiator;
callback(e);
// If you want also to bind this to the initiator, call:
// callback.call(initiator, e);
}
}));
};
现在,您可以从event
对象中读取自定义属性:
delegate(document, 'click', '.js-test-delegate'", function(e) {
e.initiator.innerHTML = `you click on this container ${++count} time(s)`;
});
可以绕过event
对象中的属性的只读保护,但不是一件容易的事。您将需要创建一个新对象,并向其中添加所有属性,并将所有方法的this
值绑定到原始事件。这是fiddle进行的操作,但是尚未经过充分测试,并且可能会因某些特定事件而失败。