Removing event listeners before leaving a page

岁酱吖の 提交于 2020-02-25 09:37:54

问题


I've developed a javascript drag and drop that mostly uses the standard 'allowdrop', 'drag' and 'drop' events.

I wanted to customise the 'ghosted' dragged object, so I've added a display:none div that get populated with the innerHTML of the draggable element and made visible (display:block;) when the user starts dragging.

The draggable div is absolutely positioned and matches the mouse movements. For this I needed to add 3 event listeners to document.body. They are as follows:

document.body.addEventListener('dragover', function (ev) {
    console.log("dragover event triggered");
    ev = ev || window.event;
    ev.preventDefault();
    dragX = ev.pageX;
    dragY = ev.pageY;
    document.getElementById("dragged-container").style.left = (dragX - dragOffsetX) + "px";
    document.getElementById("dragged-container").style.top = (dragY - dragOffsetY - 10) + "px";    
    if (mostRecentHoveredDropTargetId!="") {
        if (dragX<mostRecentHoveredDropTargetRect.left || dragX>mostRecentHoveredDropTargetRect.right || dragY<mostRecentHoveredDropTargetRect.top || dragY>mostRecentHoveredDropTargetRect.bottom) {
            document.getElementById(mostRecentHoveredDropTargetId).classList.remove("drop-target-hover");
            mostRecentHoveredDropTargetId = "";
        }
    }
});

document.body.addEventListener('drop', function (ev) {
    console.log("drop event triggered");
    ev.preventDefault();
    var data = ev.dataTransfer.getData("text"); // data set to the id of the draggable element
    if (document.getElementById(data)!=null) {
        document.getElementById(data).classList.remove("dragged");
        document.getElementById("dragged-container").innerHTML = "";
        document.getElementById("dragged-container").style.display = "none";
        var draggablesClasses = document.getElementById(data).className;
        if ((draggablesClasses.indexOf('draggable')==-1 || draggablesClasses=="") && document.getElementById(data).getAttribute('draggable')=="true") {
            if (draggablesClasses=="") {
                document.getElementById(data).className += "draggable";
            } else {
                document.getElementById(data).className += " draggable";
            }
        }
    }
});

// resets dragged-container and origin .draggable, when mouse released outside browser window
document.body.addEventListener('mouseleave', function (ev) {
    if (jqueryReady==true) {
        $(".dragged").addClass("draggable");
        $(".dragged").removeClass("dragged");
    }
    document.getElementById("dragged-container").innerHTML = "";
    document.getElementById("dragged-container").style.display = "none";
});

This is all working fine. The drag and drop performs exactly as I expect.

The problem is when I go to another page, obviously those body event listeners are still running.

I've seen a number of answers here and have tried everything I've seen. For starters this:

window.onunload = function() {
    console.log("about to clear event listeners prior to leaving page");
    document.body.removeEventListener('dragover', null);
    document.body.removeEventListener('drop', null);
    document.body.removeEventListener('mouseleave', null);
    return;
} 

...but the console.log output doesn't even appear (let alone the 'null's being wrong, I'm pretty sure). I've also tried this, in the jQuery ready function:

$(window).bind('beforeunload', function(){
        console.log("about to clear event listeners prior to leaving page");
        document.body.removeEventListener('dragover', null);
        document.body.removeEventListener('drop', null);
        document.body.removeEventListener('mouseleave', null);
    });

..but, once again, the console isn't even receiving that output.

I have also tried both the above with 'onbeforeunload' AND 'onunload'.

What am I doing wrong? - specifically to do with removing these window.body event listeners, I mean (Anything else I can sort out later).

Thanks.


回答1:


removeEventListener requires the handler

Don't use anonymous functions is the solution. Like this:

var dragHandler = function (ev) {
    console.log("dragover event triggered");
};
document.body.addEventListener('dragover', dragHandler);

and after:

window.onunload = function() {
    console.log("about to clear event listeners prior to leaving page");
    document.body.removeEventListener('dragover', dragHandler);
    return;
}


来源:https://stackoverflow.com/questions/36918366/removing-event-listeners-before-leaving-a-page

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!