在离开页面之前删除事件监听器
Removing event listeners before leaving a page
我开发了一个 javascript 拖放,主要使用标准 'allowdrop'、'drag' 和 'drop' 事件。
我想自定义 'ghosted' 拖动的对象,所以我添加了一个 display:none div,它填充了可拖动元素的 innerHTML 并使其可见(显示:块;)当用户开始拖动时。
draggable div 绝对定位并匹配鼠标移动。为此,我需要向 document.body 添加 3 个事件监听器。它们如下:
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";
});
一切正常。拖放操作完全符合我的预期。
问题是当我转到另一个页面时,显然那些 body 事件侦听器仍然 运行。
我在这里看到了很多答案,并且尝试了我所看到的一切。对于初学者来说:
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;
}
...但是 console.log 输出甚至没有出现(更不用说 'null 是错误的,我很确定)。我也试过这个,在 jQuery 就绪函数中:
$(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);
});
..但是,控制台甚至没有收到该输出。
我也用 'onbeforeunload' 和 'onunload' 尝试了以上两种方法。
我做错了什么? - 特别是与删除这些 window.body 事件侦听器有关,我的意思是(我可以稍后解决的任何其他问题)。
谢谢。
removeEventListener 需要处理程序
不使用匿名函数是解决方案。
像这样:
var dragHandler = function (ev) {
console.log("dragover event triggered");
};
document.body.addEventListener('dragover', dragHandler);
及之后:
window.onunload = function() {
console.log("about to clear event listeners prior to leaving page");
document.body.removeEventListener('dragover', dragHandler);
return;
}
我开发了一个 javascript 拖放,主要使用标准 'allowdrop'、'drag' 和 'drop' 事件。
我想自定义 'ghosted' 拖动的对象,所以我添加了一个 display:none div,它填充了可拖动元素的 innerHTML 并使其可见(显示:块;)当用户开始拖动时。
draggable div 绝对定位并匹配鼠标移动。为此,我需要向 document.body 添加 3 个事件监听器。它们如下:
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";
});
一切正常。拖放操作完全符合我的预期。
问题是当我转到另一个页面时,显然那些 body 事件侦听器仍然 运行。
我在这里看到了很多答案,并且尝试了我所看到的一切。对于初学者来说:
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;
}
...但是 console.log 输出甚至没有出现(更不用说 'null 是错误的,我很确定)。我也试过这个,在 jQuery 就绪函数中:
$(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);
});
..但是,控制台甚至没有收到该输出。
我也用 'onbeforeunload' 和 'onunload' 尝试了以上两种方法。
我做错了什么? - 特别是与删除这些 window.body 事件侦听器有关,我的意思是(我可以稍后解决的任何其他问题)。
谢谢。
removeEventListener 需要处理程序
不使用匿名函数是解决方案。 像这样:
var dragHandler = function (ev) {
console.log("dragover event triggered");
};
document.body.addEventListener('dragover', dragHandler);
及之后:
window.onunload = function() {
console.log("about to clear event listeners prior to leaving page");
document.body.removeEventListener('dragover', dragHandler);
return;
}