在构造函数的某些类中,我有附加到click事件侦听器的方法。
this.mapButton.addEventListener('click', this.expandOrCollapseMap.bind(this));
该方法的职责是下载地图并在视图上展开。
expandOrCollapseMap(eventArgs) {
// eventArgs.currentTarget != null
loadGoogleMapsApi({
key: '{{GOOGLE_MAPS.API_KEY}}',
}).then((googleMaps)=>{
if(!this.map) {
this.mapAPI = googleMaps;
this.map = new googleMaps.Map(this.mapContainer, {
zoom: 12,
center: {
lat: 40.722216,
lng: -73.987501
},
scrollwheel: false
});
}
}).then(()=>{
// eventArgs.currentTarget is null
let clickedButton = eventArgs.currentTarget;
this.changeMapIcon(clickedButton);
this.changeMapHeight();
this.addMarkersToMap(this.restaurants);
this.expanded = !this.expanded;
})
.catch((err)=>{
this.map = null;
console.log("Error while loading map: ", err);
});
}
我的问题是为什么当我在Chrome中调试诺言然后我可以访问eventArgs.currentTarget
,而内部则回调eventArgs.currentTarget
为空,但可以访问eventArgs
的其他属性?
答案 0 :(得分:3)
该事件在它所冒泡的所有元素之间共享。这意味着共享事件的每个元素都将接收事件对象的相同实例。为什么重要?
根据MDN
(event.currentTarget)标识事件的当前目标,如 事件遍历DOM。它总是指的是哪个元素 已附加事件处理程序,而不是event.target 标识事件发生的元素。
总结:event.currentTarget
是对象的瞬态属性,对于所有事件的订阅者都是相同的;这意味着在事件监听器完成后,currentTarget
将被设置为下一个事件监听器的元素,直到找不到,currentTarget
将(正确)设置为null。
请参阅下面描述的示例:
document.getElementById('btnnnn').addEventListener('click', e => {
e.test = 'test'; // we set here the property to prove that event object is shared with body
// now we'll print two similar properties that are in fact totally different in all senses
console.log('inside event', e.target, e.currentTarget);
// and now we delay the same thing; it is going to be executed after all event listeners
setTimeout(() => console.log('after all event listeners', e.target, e.currentTarget), 0);
});
// check that it's the same object
document.body.addEventListener('click', e => console.log('body, same object?', e.test));

<button id="btnnnn">Click me</button>
&#13;
最后这里是the specification,在第7点明确指示在事件完成其循环后将currentTarget设置为null。
答案 1 :(得分:1)
这是由于event bubbling。将在不同的元素上触发相同的事件对象,并且在触发安装在该元素上的侦听器之前将currentEventTarget
设置为当前元素。一旦事件到达文档根目录,currentEventTarget
就会设置为null
。因此,如果您异步地观察它(在promise回调中),那就是您将获得的值。
解决方法很简单:只需将let clickedButton = eventArgs.currentTarget;
放在函数的顶部即可。