Javascript 停止观察JS Prototype不使用.bind的事件(此)
我正在开发一个基于原型库的Javascript类。这个类需要观察一个事件来执行拖动操作(当前的拖放控件不适合这种情况),但是我在让它停止观察事件时遇到了问题 以下是导致此问题的示例:Javascript 停止观察JS Prototype不使用.bind的事件(此),javascript,prototypejs,dom-events,Javascript,Prototypejs,Dom Events,我正在开发一个基于原型库的Javascript类。这个类需要观察一个事件来执行拖动操作(当前的拖放控件不适合这种情况),但是我在让它停止观察事件时遇到了问题 以下是导致此问题的示例: var TestClass = Class.create({ initialize: function(element) { this.element = element; Event.observe(element, 'mousedown', function() {
var TestClass = Class.create({
initialize: function(element) {
this.element = element;
Event.observe(element, 'mousedown', function() {
Event.observe(window, 'mousemove', this.updateDrag.bind(this));
Event.observe(window, 'mouseup', this.stopDrag.bind(this));
});
},
updateDrag: function(event) {
var x = Event.pointerX(event);
var y = Event.pointerY(event);
this.element.style.top = y + 'px';
this.element.style.left = x + 'px';
},
stopDrag: function(event) {
console.log("stopping drag");
Event.stopObserving(window, 'mousemove', this.updateDrag.bind(this));
Event.stopObserving(window, 'mouseup', this.stopDrag.bind(this));
}
});
如果没有.bind(this),那么this.element是未定义的,但是有了它,事件不会停止被观察(尽管控制台输出会发生)。每次调用它时都返回一个新的函数引用(这是它的工作:-),并且只有在函数引用是匹配的情况下才会解除处理程序的挂钩
要解决此问题,请记住绑定为属性的事件处理程序,然后将该属性与stopObserving
一起使用。或者,如果您负责该元素,只需关闭第三个参数,就可以解除对mousemove
和mouseup
事件的所有处理程序的挂钩。(有关将参数保留到停止观察的更多信息,请参阅链接文档)
因此,要么:
initialize: function(element) {
this.element = element;
this.boundUpdateDrag = this.updateDrag.bind(this);
this.boundStopDrag = this.stopDrag.bind(this);
Event.observe(element, 'mousedown', function() {
// Off-topic, but see note at end of answer, unrelated bug here
Event.observe(window, 'mousemove', this.boundUpdateDrag);
Event.observe(window, 'mouseup', this.boundStopDrag);
});
},
stopDrag: function(event) {
console.log("stopping drag");
Event.stopObserving(window, 'mousemove', this.boundUpdateDrag);
Event.stopObserving(window, 'mouseup', this.boundStopDrag);
}
或者只是
stopDrag: function(event) {
console.log("stopping drag");
Event.stopObserving(window, 'mousemove');
Event.stopObserving(window, 'mouseup');
}
但请注意,后者删除了该元素上那些事件的所有处理程序(好的,是通过原型连接的那些处理程序)
与主题无关,但请注意,initialize
函数中有一个错误:它在mousedown
的处理程序中使用了this
,但没有确保将this
设置为应该设置的值。您需要绑定该匿名函数,或者使用initialize
中的变量来利用该匿名函数是闭包这一事实
因此,请再次使用bind:
initialize: function(element) {
this.element = element;
this.boundUpdateDrag = this.updateDrag.bind(this);
this.boundStopDrag = this.stopDrag.bind(this);
Event.observe(element, 'mousedown', (function() {
Event.observe(window, 'mousemove', this.boundUpdateDrag);
Event.observe(window, 'mouseup', this.boundStopDrag);
}).bind(this));
},
或者使用您正在定义闭包的事实:
initialize: function(element) {
var self;
self = this; // Remember 'this' on a variable that will be in scope for the closure
this.element = element;
this.boundUpdateDrag = this.updateDrag.bind(this);
this.boundStopDrag = this.stopDrag.bind(this);
Event.observe(element, 'mousedown', function() {
// Note we're using 'self' rather than 'this'
Event.observe(window, 'mousemove', self.boundUpdateDrag);
Event.observe(window, 'mouseup', self.boundStopDrag);
});
},
每次调用时返回一个新的函数引用(这是它的工作:-)),并且仅当函数引用是匹配的时才会取消钩住处理程序
要解决此问题,请记住绑定为属性的事件处理程序,然后将该属性与stopObserving
一起使用。或者,如果您负责该元素,只需关闭第三个参数,就可以解除对mousemove
和mouseup
事件的所有处理程序的挂钩。(有关将参数保留到停止观察的更多信息,请参阅链接文档)
因此,要么:
initialize: function(element) {
this.element = element;
this.boundUpdateDrag = this.updateDrag.bind(this);
this.boundStopDrag = this.stopDrag.bind(this);
Event.observe(element, 'mousedown', function() {
// Off-topic, but see note at end of answer, unrelated bug here
Event.observe(window, 'mousemove', this.boundUpdateDrag);
Event.observe(window, 'mouseup', this.boundStopDrag);
});
},
stopDrag: function(event) {
console.log("stopping drag");
Event.stopObserving(window, 'mousemove', this.boundUpdateDrag);
Event.stopObserving(window, 'mouseup', this.boundStopDrag);
}
或者只是
stopDrag: function(event) {
console.log("stopping drag");
Event.stopObserving(window, 'mousemove');
Event.stopObserving(window, 'mouseup');
}
但请注意,后者删除了该元素上那些事件的所有处理程序(好的,是通过原型连接的那些处理程序)
与主题无关,但请注意,initialize
函数中有一个错误:它在mousedown
的处理程序中使用了this
,但没有确保将this
设置为应该设置的值。您需要绑定该匿名函数,或者使用initialize
中的变量来利用该匿名函数是闭包这一事实
因此,请再次使用bind:
initialize: function(element) {
this.element = element;
this.boundUpdateDrag = this.updateDrag.bind(this);
this.boundStopDrag = this.stopDrag.bind(this);
Event.observe(element, 'mousedown', (function() {
Event.observe(window, 'mousemove', this.boundUpdateDrag);
Event.observe(window, 'mouseup', this.boundStopDrag);
}).bind(this));
},
或者使用您正在定义闭包的事实:
initialize: function(element) {
var self;
self = this; // Remember 'this' on a variable that will be in scope for the closure
this.element = element;
this.boundUpdateDrag = this.updateDrag.bind(this);
this.boundStopDrag = this.stopDrag.bind(this);
Event.observe(element, 'mousedown', function() {
// Note we're using 'self' rather than 'this'
Event.observe(window, 'mousemove', self.boundUpdateDrag);
Event.observe(window, 'mouseup', self.boundStopDrag);
});
},
啊,谢谢。我应该更仔细地阅读这些文件。把所有的手柄都拔下来,效果很好。啊,谢谢你。我应该更仔细地阅读这些文件。把所有的操控者都脱钩,效果很好。很高兴这有帮助。我刚刚更新了我的答案,因为我注意到initialize
中有一个(不相关的)错误,可能值得一看。很高兴这有帮助。我刚刚更新了我的答案,因为我注意到initialize
中有一个(不相关的)错误,可能值得一看。