带有事件处理程序的Es6类和上下文/范围问题

时间:2018-01-11 01:08:44

标签: reactjs javascript-events ecmascript-6 event-handling mouseevent

我有一个有两个窗格的容器。我正在使其中一个重新调整大小和绝对,另一个根据第一个大小实时调整。

不幸的是我遇到了刚刚编写的es6“resize-controller”的问题。因为我做错了决定使用箭头函数,我无法删除事件监听器。除此之外,我的数学错误,它正如预期的那样运作。然而,当我尝试使用几种可能的解决方案来修复我的错误时,我要么没有关于上下文的功能或错误,也没有关于函数的错误。

希望有人在这里看看我的确切设置,并告诉我应该如何。用普通函数替换箭头函数,有或没有事件参数,都不起作用。我最好放弃Es6课程吗?也许我已经解开了几层复杂性。

class ResizeController {

constructor(){
    this.chatContainer = document.getElementById("chatContainer");
    this.messageWindowContainer = document.getElementById("messageWindowContainer");
    this.messageWindowContentContainer = document.getElementById("messageWindowContentContainer");
    this.messageWindowContent = document.getElementById("messageWindowContent");
    this.startX = "";
    this.startWidth = this.getMessageWindowWidth();
}

init(){
    this.messageWindowContainer.addEventListener('mousedown', (e)=>{e.stopPropagation()});
    this.messageWindowContentContainer.addEventListener('mousedown', (e)=>{this.onMouseDown(e)});
    this.messageWindowContent.addEventListener('mousedown', (e)=>{e.stopPropagation()})
}

onMouseDown(e) {
    this.onDown(e);
    e.preventDefault();
}

onDown(e){
    this.startX = e.clientX;
    this.messageWindowContentContainer.addEventListener('mousemove', (e)=>{this.onMouseMove(e)});
    this.messageWindowContentContainer.addEventListener('mouseup', (e)=>{this.onMouseUp(e)});
}

onMouseMove(e){
    this.mouseMove(e);
    e.preventDefault();
}

onMouseUp(e){
    this.mouseUp(e);
    e.preventDefault();
}

mouseMove(e) {
        this.messageWindowContainer.setAttribute("style","width:"+( this.startWidth - e.clientX + this.startX)+"px");
}

mouseUp(e){
    console.log("stopdrag")
    this.messageWindowContentContainer.removeEventListener('mousemove', (e)=>{this.onMouseMove(e)});
    this.messageWindowContentContainer.removeEventListener('mouseup', (e)=>{this.onMouseUp(e)});
}


getMessageWindowWidth(){
    let chatContainerWidth = document.getElementById("chatContainer").offsetWidth;
    let messageWindowContainerWidth = document.getElementById("messageWindowContainer").offsetWidth;
    return (chatContainerWidth - messageWindowContainerWidth);
}


}


export default ResizeController

2 个答案:

答案 0 :(得分:2)

在此处找到答案:https://gist.github.com/Restuta/e400a555ba24daa396cc

我只是在构造函数中定义了以下代码,然后将它们用作我的事件处理程序。

this.bound_onMouseDown = this.onMouseDown.bind(this); this.bound_onMouseMove = this.onMouseMove.bind(this); this.bound_onMouseUp = this.onMouseUp.bind(this);

在构造函数之外声明它们不是解决方案。

答案 1 :(得分:1)

作为第二个参数传递给.addEventListener().removeEventListener()的值应该是函数引用而不是匿名函数。您可以使用.bind()保留this



class ResizeController {
  constructor() {
    this.chatContainer = document.getElementById("chatContainer");
    this.button = document.querySelector("button");
    this.init();
  }
  init() {
    // pass function reference
    this._onMouseMove = this.onMouseMove.bind(this);
    this.chatContainer.addEventListener("mousemove", this._onMouseMove);
    this.button.onclick = () => this.removeListener();
  }
  onMouseMove(e) {
    this.chatContainer.innerHTML = "moved at " + new Date();
  }
  removeListener() {
    // pass function reference
    this.chatContainer.removeEventListener("mousemove", this._onMouseMove);
    this.chatContainer.textContent = "removed mousemove event listener";
  }
}

onload = () => new ResizeController();

#chatContainer {
  display: block;
  position: relative;
  width: 300px;
  height: 200px;
  border: 2px solid blue;
}

<div id="chatContainer"></div>
<button>remove mousemove event listener</button>
&#13;
&#13;
&#13;