访问函数中调用的函数内部的函数参数

时间:2018-06-17 19:42:13

标签: javascript click es6-promise

在构造函数的某些类中,我有附加到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的其他属性?

2 个答案:

答案 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;
&#13;
&#13;

最后这里是the specification,在第7点明确指示在事件完成其循环后将currentTarget设置为null。

答案 1 :(得分:1)

这是由于event bubbling。将在不同的元素上触发相同的事件对象,并且在触发安装在该元素上的侦听器之前将currentEventTarget设置为当前元素。一旦事件到达文档根目录,currentEventTarget就会设置为null。因此,如果您异步地观察它(在promise回调中),那就是您将获得的值。

解决方法很简单:只需将let clickedButton = eventArgs.currentTarget;放在函数的顶部即可。