更改事件委派的事件的currentTarget



我试图在网站上添加一些委托事件,但我没有一个与传统侦听器回调签名(function( event ) {}(匹配的函数,为了获得当前listenning元素,我需要向函数传递另一个参数。

以下是我设法实现的目标:

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),但此时没有设置targetcurrentTarget

当然,这需要在香草js。

谢谢!

使用.call()调用回调,元素引用为this:的值

if ( e.target && ( initiator = e.target.closest( target ) ) ) {
callback.call(initiator, e);
}

在回调中,this将引用"启动器",您不需要其他参数。

您可以将所需元素作为自定义属性添加到事件对象中,如下所示:

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值绑定到原始事件。这是一把小提琴,但它没有经过太多测试,可能会在某些特定事件中失败。

最新更新