Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/417.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 停止观察JS Prototype不使用.bind的事件(此)_Javascript_Prototypejs_Dom Events - Fatal编程技术网

Javascript 停止观察JS Prototype不使用.bind的事件(此)

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() {

我正在开发一个基于原型库的Javascript类。这个类需要观察一个事件来执行拖动操作(当前的拖放控件不适合这种情况),但是我在让它停止观察事件时遇到了问题

以下是导致此问题的示例:

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
中有一个(不相关的)错误,可能值得一看。