0

I have a container with two panes. I am making one of them re-sizable and absolute, and the other adjusts in real time based on the size of the first.

Unfortunately I am having problems with the es6 "resize-controller" that I just wrote. Because I made the wrong decision to use arrow functions, I am unable to remove the event listeners. Other than that and a bug with my math, it is functioning as expected. However when I tried to fix my mistakes with several possible solutions, I either get no functionality or errors about context and functions not being functions.

Hoping someone here could take a look at my exact setup and show me how it should be. Replacing the Arrow functions with normal functions, with or without event params, does not work. Would I be better off ditching Es6 classes for this one? Perhaps I have unlocked a few layers of complexity.

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
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
user2355058
  • 211
  • 3
  • 15
  • 1
    The value passed as second parameter to `.addEventListener()` and `.removeEventListener()` should be a function reference instead of an anonymous function – guest271314 Jan 11 '18 at 01:13
  • Changing the anonymous functions (which allow my controller to work) with function definitions (not function calls), results in errors in functions like onMouseDown() which say that the mouseDown() function is not a function. onMouseDown is the handler and the work is delegated to mouseDown – user2355058 Jan 11 '18 at 01:21
  • Related/potential duplicate: [How to removeEventListener that is addEventListener with anonymous function?](https://stackoverflow.com/q/5660131/218196) – Felix Kling Jan 11 '18 at 10:25

2 Answers2

2

Answer found here: https://gist.github.com/Restuta/e400a555ba24daa396cc

I simply defined the following code once in my constructor and then used them as my event handlers.

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

Declaring them outside the constructor is not a solution.

user2355058
  • 211
  • 3
  • 15
1

The value passed as second parameter to .addEventListener() and .removeEventListener() should be a function reference instead of an anonymous function. You can use .bind() to preserve 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>
guest271314
  • 1
  • 15
  • 104
  • 177