javascript – removeEventListener not working consistently

huangapple go评论60阅读模式
英文:

javascript - removeEventListener not working consistently

问题

以下是您提供的代码的翻译部分:

我遇到了一个奇怪的情况之前添加的事件监听器有时成功删除有时则没有

让我们从一个示例代码开始

this.Start_Measuring_Slider_Drag = function(p_Event) {

    // 鼠标按下事件触发的函数..

    console.log("开始拖动...");

    var l_Scroll_Pane_ID  = this.Foreign_Mesh.Config.Element_ID + "_VerticalScroll_Inner_div";
    var l_Scroll_Pane_Obj = document.getElementById(l_Scroll_Pane_ID);

    l_Scroll_Pane_Obj.addEventListener("mouseup", event => this.Complete_Scroll(event, l_Scroll_Pane_ID));
    l_Scroll_Pane_Obj.addEventListener("mousemove", event => this.Mouse_Move_During_Scroll(event, l_Scroll_Pane_ID));
    l_Scroll_Pane_Obj.addEventListener("mouseleave", event => this.Cancel_Scroll(event, l_Scroll_Pane_ID));
}

////////////////////////////////////////////////////////////////////////////////////////
this.Mouse_Move_During_Scroll = function (p_Event) {
    console.log("鼠标正在移动")
}
////////////////////////////////////////////////////////////////////////////////////////
this.Complete_Scroll = function (p_Event , p_Element_ID) {
    console.log("在y坐标完成滚动:" + (p_Event || window.event).pageY);

    this.Remove_Scrolling_Listeners(p_Element_ID);
}
////////////////////////////////////////////////////////////////////////////////////////
this.Cancel_Scroll = function(p_Event , p_Element_ID) {
    console.log("需要取消滚动:" + (p_Event || window.event).pageY)

    this.Remove_Scrolling_Listeners(p_Element_ID);
}
////////////////////////////////////////////////////////////////////////////////////////
this.Remove_Scrolling_Listeners = function (p_Element_ID) {

    console.log("移除监听器...")

    var l_Scroll_Pane_Obj = document.getElementById(p_Element_ID);

    l_Scroll_Pane_Obj.removeEventListener("mouseup", event => this.Complete_Scroll(event, p_Element_ID));
    l_Scroll_Pane_Obj.removeEventListener("mousemove", event => this.Mouse_Move_During_Scroll(event, p_Element_ID));
    l_Scroll_Pane_Obj.removeEventListener("mouseleave", event => this.Cancel_Scroll(event, p_Element_ID));
}

////////////////////////////////////////////////////////////////////////////////////////

希望这可以帮助您理解代码的翻译。如果您有任何其他问题,请随时提出。

英文:

I have a strange situation where previously added event listeners sometimes are successfully removed and sometimes they are not.

Let's start with a sample code:

    this.Start_Measuring_Slider_Drag = function(p_Event) {
// Function invoked upon mousedown event..
console.log("Start dragging...") ;
var l_Scroll_Pane_ID  = this.Foreign_Mesh.Config.Element_ID + "_VerticalScroll_Inner_div" ;
var l_Scroll_Pane_Obj = document.getElementById(l_Scroll_Pane_ID) ;
l_Scroll_Pane_Obj.addEventListener("mouseup"    , event => this.Complete_Scroll         (event , l_Scroll_Pane_ID)) ;
l_Scroll_Pane_Obj.addEventListener("mousemove"  , event => this.Mouse_Move_During_Scroll(event , l_Scroll_Pane_ID)) ;
l_Scroll_Pane_Obj.addEventListener("mouseleave" , event => this.Cancel_Scroll           (event , l_Scroll_Pane_ID)) ;
}
////////////////////////////////////////////////////////////////////////////////////////
this.Mouse_Move_During_Scroll = function (p_Event) {
console.log("Mouse is moving ")
}
////////////////////////////////////////////////////////////////////////////////////////
this.Complete_Scroll = function (p_Event , p_Element_ID) {
console.log("Completing scroll at y: " + (p_Event || window.event).pageY) ;
this.Remove_Scrolling_Listeners (p_Element_ID) ;
}
////////////////////////////////////////////////////////////////////////////////////////
this.Cancel_Scroll = function(p_Event , p_Element_ID) {
console.log("Need to cancel scroll at: " + (p_Event || window.event).pageY)
this.Remove_Scrolling_Listeners (p_Element_ID) ;
}
////////////////////////////////////////////////////////////////////////////////////////
this.Remove_Scrolling_Listeners = function (p_Element_ID) {
console.log("Removing listeners...")
var l_Scroll_Pane_Obj = document.getElementById(p_Element_ID) ;
l_Scroll_Pane_Obj.removeEventListener("mouseup"    , event => this.Complete_Scroll         (event , p_Element_ID)) ;
l_Scroll_Pane_Obj.removeEventListener("mousemove"  , event => this.Mouse_Move_During_Scroll(event , p_Element_ID)) ;
l_Scroll_Pane_Obj.removeEventListener("mouseleave" , event => this.Cancel_Scroll           (event , p_Element_ID)) ;
}
////////////////////////////////////////////////////////////////////////////////////////

and here is the output within the console.

javascript – removeEventListener not working consistently

The output at the console shows (green arrows + (A)) that, after removing the listeners, there are no captured mouse movements (though I did move it quite a lot!!).
The orange arrow (B) indicates that the mouse moved away from the div ("mouseout" event) which also invoked the function that removes the listeners ("this.Remove_Scrolling_Listeners"). Here, however, movements of the mouse are still being watched as shown by the red arrow (C).

Bottom line: The same mechanism is used to remove listeners but it sometimes work and sometimes does not.

Any suggestion will be most appreciated.

UPDATE:

Following Keith's suggestion, I changed the code as shown hereinunder:

    this.Start_Measuring_Slider_Drag = function(p_Event) {
console.log("Start dragging...") ;
var l_Scroll_Pane_ID  = this.Foreign_Mesh.Config.Element_ID + "_VerticalScroll_Inner_div" ;
var l_Scroll_Pane_Obj = document.getElementById(l_Scroll_Pane_ID) ;
this._mouseUp    = event => this.Complete_Scroll         (event) ;
this._mouseMove  = event => this.Mouse_Move_During_Scroll(event) ;
this._mouseLeave = event => this.Cancel_Scroll           (event) ;
l_Scroll_Pane_Obj.addEventListener("mouseup"    , this.Complete_Scroll         (this._mouseUp    )) ;
l_Scroll_Pane_Obj.addEventListener("mousemove"  , this.Mouse_Move_During_Scroll(this._mouseMove  )) ;
l_Scroll_Pane_Obj.addEventListener("mouseleave" , this.Cancel_Scroll           (this._mouseLeave )) ;
}
////////////////////////////////////////////////////////////////////////////////////////
this.Mouse_Move_During_Scroll = function (p_Event) {
console.log("Mouse is moving ")
// console.log("Mouse Y coordinate: " + (p_Event || window.event).pageY)
}
////////////////////////////////////////////////////////////////////////////////////////
this.Complete_Scroll = function (p_Event) {
console.log("Completing scroll at y: " + (p_Event || window.event).pageY) ;
this.Remove_Scrolling_Listeners () ;
}
////////////////////////////////////////////////////////////////////////////////////////
this.Cancel_Scroll = function(p_Event) {
console.log("Need to cancel scroll at: " + (p_Event || window.event).pageY)
this.Remove_Scrolling_Listeners () ;
}
////////////////////////////////////////////////////////////////////////////////////////
this.Remove_Scrolling_Listeners = function () {
console.log("Removing listeners...")
var l_Scroll_Pane_ID  = this.Foreign_Mesh.Config.Element_ID + "_VerticalScroll_Inner_div" ;
var l_Scroll_Pane_Obj = document.getElementById(l_Scroll_Pane_ID) ;
l_Scroll_Pane_Obj.removeEventListener("mouseup"    , this._mouseUp    ) ;
l_Scroll_Pane_Obj.removeEventListener("mousemove"  , this._mouseMove  ) ;
l_Scroll_Pane_Obj.removeEventListener("mouseleave" , this._mouseLeave ) ;
}
////////////////////////////////////////////////////////////////////////////////////////

This does not work at all... Upon pressing the mouse button (i.e. mousedown), all the events appear to be fired at once as shown in the console:

Start dragging...
Completing scroll at y: undefined
Removing listeners...
Mouse is moving 
Need to cancel scroll at: undefined
Removing listeners...

This condition repeats whenever mousedown event takes place. Furthermore, when moving the mouse while the button is down (i.e. dragging), no indication is shown that the system is monitoring the mouse movements (nothing is written into the console since, normally, when the mouse moves it would display the same message with the number of repetitions, something like "123 Mouse is moving
").

UPDATE 2:
I wrongly implemented Keith's suggested solution. Once fixed (to look as suggested), things work like a charm. See Keith's answer for details.

答案1

得分: 1

I'm assuming your code is part of a class, with all the this logic.

As such the modifications I would suggest is keeping a track of the event handler you're adding.

eg.

    this.Start_Measuring_Slider_Drag = function(p_Event) {

        // Function invoked upon mousedown event..

        console.log("Start dragging...");

        var l_Scroll_Pane_ID  = this.Foreign_Mesh.Config.Element_ID + "_VerticalScroll_Inner_div";
        var l_Scroll_Pane_Obj = document.getElementById(l_Scroll_Pane_ID);

        //keep a track of the events we will be adding.
        this._mouseUp = event => this.Complete_Scroll(event , l_Scroll_Pane_ID);
        this._mouseMove = event => this.Mouse_Move_During_Scroll(event , l_Scroll_Pane_ID);
        this._mouseLeave = event => this.Cancel_Scroll(event , l_Scroll_Pane_ID);

        //now add the event listeners. 
        l_Scroll_Pane_Obj.addEventListener("mouseup", this._mouseUp);
        l_Scroll_Pane_Obj.addEventListener("mousemove", this._mouseMove);
        l_Scroll_Pane_Obj.addEventListener("mouseleave", this._mouseLeave);
    }

    ////////////////////////////////////////////////////////////////////////////////////////
    this.Mouse_Move_During_Scroll = function (p_Event) {
        console.log("Mouse is moving")
    }
    ////////////////////////////////////////////////////////////////////////////////////////
    this.Complete_Scroll = function (p_Event , p_Element_ID) {
        console.log("Completing scroll at y: " + (p_Event || window.event).pageY);
        
        this.Remove_Scrolling_Listeners(p_Element_ID);
    }
    ////////////////////////////////////////////////////////////////////////////////////////
    this.Cancel_Scroll = function(p_Event , p_Element_ID) {
        console.log("Need to cancel scroll at: " + (p_Event || window.event).pageY);

        this.Remove_Scrolling_Listeners(p_Element_ID);
    }
    ////////////////////////////////////////////////////////////////////////////////////////
    this.Remove_Scrolling_Listeners = function (p_Element_ID) {

        console.log("Removing listeners...");

        var l_Scroll_Pane_Obj = document.getElementById(p_Element_ID);

        //use our stored events to remove
        l_Scroll_Pane_Obj.removeEventListener("mouseup", this._mouseUp);
        l_Scroll_Pane_Obj.removeEventListener("mousemove", this._mouseMove);
        l_Scroll_Pane_Obj.removeEventListener("mouseleave", this._mouseLeave);
    }
英文:

I'm assuming your code is part of a class, with all the this logic.

As such the modifications I would suggest is keeping a track of the event handler your adding.

eg.

    this.Start_Measuring_Slider_Drag = function(p_Event) {
// Function invoked upon mousedown event..
console.log("Start dragging...") ;
var l_Scroll_Pane_ID  = this.Foreign_Mesh.Config.Element_ID + "_VerticalScroll_Inner_div" ;
var l_Scroll_Pane_Obj = document.getElementById(l_Scroll_Pane_ID) ;
//keep a track of the events we will be adding.
this._mouseUp = event => this.Complete_Scroll(event , l_Scroll_Pane_ID);
this._mouseMove = event => this.Mouse_Move_During_Scroll(event , l_Scroll_Pane_ID);
this._mouseLeave = event => this.Cancel_Scroll           (event , l_Scroll_Pane_ID);
//now add the event listeners. 
l_Scroll_Pane_Obj.addEventListener("mouseup", this._mouseUp) ;
l_Scroll_Pane_Obj.addEventListener("mousemove", this._mouseMove) ;
l_Scroll_Pane_Obj.addEventListener("mouseleave", this._mouseLeave ) ;
}
////////////////////////////////////////////////////////////////////////////////////////
this.Mouse_Move_During_Scroll = function (p_Event) {
console.log("Mouse is moving ")
}
////////////////////////////////////////////////////////////////////////////////////////
this.Complete_Scroll = function (p_Event , p_Element_ID) {
console.log("Completing scroll at y: " + (p_Event || window.event).pageY) ;
this.Remove_Scrolling_Listeners (p_Element_ID) ;
}
////////////////////////////////////////////////////////////////////////////////////////
this.Cancel_Scroll = function(p_Event , p_Element_ID) {
console.log("Need to cancel scroll at: " + (p_Event || window.event).pageY)
this.Remove_Scrolling_Listeners (p_Element_ID) ;
}
////////////////////////////////////////////////////////////////////////////////////////
this.Remove_Scrolling_Listeners = function (p_Element_ID) {
console.log("Removing listeners...")
var l_Scroll_Pane_Obj = document.getElementById(p_Element_ID) ;
//use our stored events to remove
l_Scroll_Pane_Obj.removeEventListener("mouseup", this._mouseUp) ;
l_Scroll_Pane_Obj.removeEventListener("mousemove", this._mouseMove) ;
l_Scroll_Pane_Obj.removeEventListener("mouseleave" , this._mouseLeave) ;
}

huangapple
  • 本文由 发表于 2023年5月22日 18:09:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76305099.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定