【问题标题】:Es6 class with event handlers and issues with context/scope具有事件处理程序和上下文/范围问题的 Es6 类
【发布时间】:2018-01-11 01:08:43
【问题描述】:

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

不幸的是,我刚刚编写的 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

【问题讨论】:

  • 作为第二个参数传递给.addEventListener().removeEventListener() 的值应该是函数引用而不是匿名函数
  • 使用函数定义(而不是函数调用)更改匿名函数(允许我的控制器工作)会导致 onMouseDown() 等函数出错,这表明 mouseDown() 函数不是函数. onMouseDown 是处理程序,工作委托给 mouseDown

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


【解决方案1】:

在这里找到答案: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);

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

【讨论】:

    【解决方案2】:

    作为第二个参数传递给.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>

    【讨论】:

    • 您清楚地知道您的 Javascript,但您的答案与 OP 完全相同(并且功能完全相同)!我的答案包括一个将其描述为陷阱的链接!
    • .bind 返回一个新函数,所以它也不起作用。
    • @FelixKling 很好。更新
    猜你喜欢
    • 2018-08-18
    • 1970-01-01
    • 2021-01-21
    • 1970-01-01
    • 2011-04-24
    • 1970-01-01
    • 2022-11-19
    • 1970-01-01
    • 2011-07-05
    相关资源
    最近更新 更多