Javascript/DOM:如何删除DOM对象的所有事件?
问:有没有办法完全删除对象的所有事件,例如div 编辑:我正在添加perJavascript/DOM:如何删除DOM对象的所有事件?,javascript,events,dom,Javascript,Events,Dom,问:有没有办法完全删除对象的所有事件,例如div 编辑:我正在添加perdiv.addEventListener('click',eventReturner(),false)事件 function eventReturner() { return function() { dosomething(); }; } EDIT2:我找到了一种可行的方法,但不可能用于我的案例: var returnedFunction; function addit() { v
div.addEventListener('click',eventReturner(),false)代码>事件
function eventReturner() {
return function() {
dosomething();
};
}
EDIT2:我找到了一种可行的方法,但不可能用于我的案例:
var returnedFunction;
function addit() {
var div = document.getElementById('div');
returnedFunction = eventReturner();
div.addEventListener('click',returnedFunction,false); //You HAVE to take here a var and not the direct call to eventReturner(), because the function address must be the same, and it would change, if the function was called again.
}
function removeit() {
var div = document.getElementById('div');
div.removeEventListener('click',returnedFunction,false);
}
//编辑
我不知道你用什么方法附加事件。对于addEventListener
,您可以使用:
div.removeEventListener('click',functionName,false); // functionName is the name of your callback function
如果您执行以下操作,浏览器可能会为您执行此操作:
复制div
及其属性,并将其插入到旧的属性之前,然后将内容从旧内容移动到新内容并删除旧内容?我不确定您对删除所有事件的意思。删除特定类型事件的所有处理程序,还是删除一种类型的所有事件处理程序
删除所有事件处理程序
如果要删除所有事件处理程序(任何类型),可以删除元素并用其克隆替换它:
var clone = element.cloneNode(true);
注意:这将保留属性和子级,但不会保留对DOM属性的任何更改
删除特定类型的“匿名”事件处理程序
另一种方法是使用,但我想你已经尝试过了,但没有效果
对匿名函数调用addEventListener
,每次都会创建一个新的侦听器。对匿名函数调用removeEventListener
无效。匿名函数每次调用时都会创建一个唯一的对象,它不是对现有对象的引用,尽管它可能会调用一个对象。以这种方式添加事件侦听器时,请确保只添加一次,它是永久的(无法删除),直到它添加到的对象被销毁
实际上,您是在向addEventListener
传递一个匿名函数,因为eventReturner
返回一个函数
您有两种可能解决此问题:
不要使用返回函数的函数。直接使用该功能:
function handler() {
dosomething();
}
div.addEventListener('click',handler,false);
为addEventListener
创建一个包装器,该包装器存储对返回函数的引用,并创建一些奇怪的removeAllEvents
函数:
var _eventHandlers = {}; // somewhere global
const addListener = (node, event, handler, capture = false) => {
if (!(event in _eventHandlers)) {
_eventHandlers[event] = []
}
// here we track the events and their nodes (note that we cannot
// use node as Object keys, as they'd get coerced into a string
_eventHandlers[event].push({ node: node, handler: handler, capture: capture })
node.addEventListener(event, handler, capture)
}
const removeAllListeners = (targetNode, event) => {
// remove listeners from the matching nodes
_eventHandlers[event]
.filter(({ node }) => node === targetNode)
.forEach(({ node, handler, capture }) => node.removeEventListener(event, handler, capture))
// update _eventHandlers global
_eventHandlers[event] = _eventHandlers[event].filter(
({ node }) => node !== targetNode,
)
}
然后您可以将其用于:
addListener(div, 'click', eventReturner(), false)
// and later
removeAllListeners(div, 'click')
注意:如果您的代码运行很长时间,并且您正在创建和删除许多元素,那么在销毁它们时,您必须确保删除\u eventHandlers
中包含的元素。这将从子级删除所有侦听器,但对于大型页面来说速度较慢。写起来极其简单
element.outerHTML = element.outerHTML;
使用事件侦听器自己的函数remove()
。例如:
getEventListeners().click.forEach((e)=>{e.remove()})
正如corwin.amber所说,Webkit和其他工具之间存在差异
铬合金:
getEventListeners(document);
这将为您提供一个包含所有现有事件侦听器的对象:
Object
click: Array[1]
closePopups: Array[1]
keyup: Array[1]
mouseout: Array[1]
mouseover: Array[1]
...
从这里,您可以访问要删除的侦听器:
getEventListeners(document).copy[0].remove();
document.removeEventListener("copy", getEventListeners(document).copy[0].listener)
因此,所有事件侦听器:
Object
click: Array[1]
closePopups: Array[1]
keyup: Array[1]
mouseout: Array[1]
mouseover: Array[1]
...
for(getEventListeners(文档)中的var eventType){
getEventListeners(文档)[eventType].forEach(
函数(o){o.remove();}
)
}
Firefox中的
有点不同,因为它使用了不包含删除函数的侦听器包装器。您必须获取要删除的侦听器:
getEventListeners(document).copy[0].remove();
document.removeEventListener("copy", getEventListeners(document).copy[0].listener)
所有事件侦听器:
我无意中发现了这篇试图禁用新闻网站恼人的版权保护的帖子
享受吧 删除文档上的所有事件
一艘班轮:
for (key in getEventListeners(document)) { getEventListeners(document)[key].forEach(function(c) { c.remove() }) }
漂亮版:
for (key in getEventListeners(document)) {
getEventListeners(document)[key].forEach(function(c) {
c.remove()
})
}
仅限铬合金
因为我试图删除量角器测试中的EventListener,并且无法访问
在测试中,以下操作可删除单一类型的所有事件侦听器:
function(eventType){
getEventListeners(window).[eventType].forEach(
function(e){
window.removeEventListener(eventType, e.listener)
}
);
}
我希望这对其他人有所帮助,因为之前的答案使用的是“删除”方法,从那以后就不再有效了。为了完成这些答案,这里有一些真实的示例,说明在访问网站时删除事件,并且无法控制生成的HTML和JavaScript代码
一些恼人的网站阻止您在登录表单上复制粘贴用户名,如果在onpaste
事件中添加了onpaste=“return false”
HTML属性,则很容易绕过此操作。
在本例中,我们只需右键单击输入字段,在类似Firefox的浏览器中选择“Inspect element”,然后删除HTML属性
但是,如果事件是通过JavaScript添加的,如下所示:
document.getElementById("lyca_login_mobile_no").onpaste = function(){return false};
我们还必须通过JavaScript删除该事件:
document.getElementById("lyca_login_mobile_no").onpaste = null;
在我的示例中,我使用ID“lyca_login_mobile_no”,因为它是我访问的网站使用的文本输入ID
删除事件的另一种方法(也将删除所有事件)是删除节点并创建一个新的节点,就像使用addEventListener
添加事件时使用的匿名函数一样,我们不能使用removeEventListener
删除该函数。
也可以通过浏览器控制台检查元素、复制HTML代码、删除HTML代码,然后在同一位置粘贴HTML代码来完成此操作
还可以通过JavaScript更快地实现自动化:
var oldNode = document.getElementById("lyca_login_mobile_no");
var newNode = oldNode.cloneNode(true);
oldNode.parentNode.insertBefore(newNode, oldNode);
oldNode.parentNode.removeChild(oldNode);
document.getElementById("lyca_login_mobile_no").value = "username";
更新:如果web应用程序是使用类似Angular的JavaScript框架制作的,那么之前的解决方案似乎不起作用或破坏了应用程序。
允许粘贴的另一个解决方法是通过JavaScript设置值:
var oldNode = document.getElementById("lyca_login_mobile_no");
var newNode = oldNode.cloneNode(true);
oldNode.parentNode.insertBefore(newNode, oldNode);
oldNode.parentNode.removeChild(oldNode);
document.getElementById("lyca_login_mobile_no").value = "username";
目前,我不知道是否有一种方法可以在不破坏像Angular这样完全用JavaScript编写的应用程序的情况下删除所有表单验证和限制事件。一种方法是添加一个新的事件侦听器,调用e.stopImmediatePropagation()。Angular对此问题有一个polyfill,您可以检查。我不太明白,但也许这能帮上忙
const REMOVE_ALL_LISTENERS_EVENT_LISTENER='removeAllListeners'
proto[REMOVE_ALL_LISTENERS_EVENT_LISTENER] = function () {
const target = this || _global;
const eventName = arguments[0];
if (!eventName) {
const keys = Object.keys(target);
for (let i = 0; i < keys.length; i++) {
const prop = keys[i];
const match = EVENT_NAME_SYMBOL_REGX.exec(prop);
let evtName = match && match[1];
// in nodejs EventEmitter, removeListener event is
// used for monitoring the removeListener call,
// so just keep removeListener eventListener until
// all other eventListeners are removed
if (evtName && evtName !== 'removeListener') {
this[REMOVE_ALL_LISTENERS_EVENT_LISTENER].call(this, evtName);
}
}
// remove removeListener listener finally
this[REMOVE_ALL_LISTENERS_EVENT_LISTENER].call(this, 'removeListener');
}
else {
const symbolEventNames = zoneSymbolEventNames$1[eventName];
if (symbolEventNames) {
const symbolEventName = symbolEventNames[FALSE_STR];
const symbolCaptureEventName = symbolEventNames[TRUE_STR];
const tasks = target[symbolEventName];
const captureTasks = target[symbolCaptureEventName];
if (tasks) {
const removeTasks = tasks.slice();
for (let i = 0; i < removeTasks.length; i++) {
const task = removeTasks[i];
let delegate = task.originalDelegate ? task.originalDelegate : task.callback;
this[REMOVE_EVENT_LISTENER].call(this, eventName, delegate, task.options);
}
}
if (captureTasks) {
const removeTasks = captureTasks.slice();
for (let i = 0; i < removeTasks.length; i++) {
const task = removeTasks[i];
let delegate = task.originalDelegate ? task.originalDelegate : task.callback;
this[REMOVE_EVENT_LISTENER].call(this, eventName, delegate, task.options);
}
}
}
}
if (returnTarget) {
return this;
}
};
proto[删除所有列表]
<div id="test" onclick="alert(42)">test</div>
const removeAttEvents = el =>
[...el.attributes].forEach(att =>
att.name.startsWith("on") && el.removeAttribute(att.name)
);