javascript - การลบตัวฟังเหตุการณ์ที่ถูกเพิ่มด้วย bind
ใน JavaScript วิธีที่ดีที่สุดในการลบฟังก์ชันที่ถูกเพิ่มเป็นตัวฟังเหตุการณ์โดยใช้ bind() คืออะไร?
ตัวอย่าง
(function(){
// constructor
MyClass = function() {
this.myButton = document.getElementById("myButtonID");
this.myButton.addEventListener("click", this.clickListener.bind(this));
};
MyClass.prototype.clickListener = function(event) {
console.log(this); // must be MyClass
};
// public method
MyClass.prototype.disableButton = function() {
this.myButton.removeEventListener("click", ___________);
};
})();
วิธีเดียวที่ฉันนึกออกคือการติดตามผู้ฟังทุกคนที่ถูกเพิ่มด้วย bind
ตัวอย่างข้างต้นด้วยวิธีนี้:
(function(){
// constructor
MyClass = function() {
this.myButton = document.getElementById("myButtonID");
this.clickListenerBind = this.clickListener.bind(this);
this.myButton.addEventListener("click", this.clickListenerBind);
};
MyClass.prototype.clickListener = function(event) {
console.log(this); // must be MyClass
};
// public method
MyClass.prototype.disableButton = function() {
this.myButton.removeEventListener("click", this.clickListenerBind);
};
})();
มีวิธีที่ดีกว่านี้ในการทำหรือไม่?
คำตอบ #1
แม้ว่าสิ่งที่ @machineghost พูดจะเป็นความจริง ว่าเหตุการณ์ถูกเพิ่มและลบในลักษณะเดียวกัน แต่ส่วนที่ขาดหายไปของสมการคือสิ่งนี้:
มีการสร้างการอ้างอิงฟังก์ชันใหม่หลังจากที่เรียกใช้
.bind()
ดู bind() เปลี่ยนการอ้างอิงฟังก์ชันหรือไม่? | วิธีการตั้งค่าอย่างถาวร?
ดังนั้น การเพิ่มหรือลบมัน ให้กำหนดการอ้างอิงไปยังตัวแปร:
var x = this.myListener.bind(this);
Toolbox.addListener(window, 'scroll', x);
Toolbox.removeListener(window, 'scroll', x);
สิ่งนี้ใช้ได้ตามที่ฉันคาดหวัง
คำตอบ #2
สำหรับผู้ที่มีปัญหานี้ขณะลงทะเบียน/ลบตัวฟังของคอมโพเนนต์ React กับ/จาก Flux store ให้เพิ่มบรรทัดด้านล่างไปยัง constructor ของคอมโพเนนต์ของคุณ:
class App extends React.Component {
constructor(props){
super(props);
// it's a trick! needed in order to overcome the remove event listener
this.onChange = this.onChange.bind(this);
}
// then as regular...
componentDidMount (){
AppStore.addChangeListener(this.onChange);
}
componentWillUnmount (){
AppStore.removeChangeListener(this.onChange);
}
onChange () {
let state = AppStore.getState();
this.setState(state);
}
render() {
// ...
}
}