我想删除给定事件类型的所有处理程序。假设我已经向按钮添加了两次“onclick事件”,现在我想返回原始状态,其中没有为该按钮设置事件处理程序。
我该怎么做?
PS:我发现了removeEventListener(非IE)/ detachEvent(IE)方法,但函数希望我作为参数传递处理事件的函数,这对我来说非常笨拙,因为我必须存储功能在某处。编辑:http://ejohn.org/blog/flexible-javascript-events/ - 我现在正在使用此代码
答案 0 :(得分:10)
使用jQuery或类似的框架来管理所有事件处理程序可能是个好主意。 这将为您提供易于使用,不显眼的功能来添加和删除事件处理程序:
$(...).bind('click', function() { ... });
$(...).unbind('click');
// or, to unbind all events:
$(...).unbind();
答案 1 :(得分:9)
如果你的元素的父元素下只有一个子元素(或者如果你不介意所有兄弟的事件处理程序也丢失了):
elem.parentElement.innerHTML = elem.parentElement.innerHTML;
在Chrome 49,FF 44,IE 11中测试
删除所有'addEventListener'-s。
答案 2 :(得分:7)
http://www.quirksmode.org/js/events_advanced.html - “注册了哪些事件处理程序?” - 没有DOM 3级别似乎不可能: - (
编辑:我已经想出了这段代码。它符合我的需要。也许这对其他人有帮助。使用Javascript:
function DomLib() {
}
/**
* Based on: http://ejohn.org/blog/flexible-javascript-events/
* Function that register event and enables it to be removed without explicitly giving the function definition
*/
DomLib.prototype.regEventEx = function (el, eventName, funct) {
if (el.attachEvent) {
el['e'+eventName+funct] = funct;
el[eventName+funct] = function(){el['e'+eventName+funct](window.event);}
el.attachEvent( 'on'+eventName, el[eventName+funct] );
} else {
el.addEventListener(eventName, funct, false);
}
if(!el.eventHolder) el.eventHolder = [];
el.eventHolder[el.eventHolder.length] = new Array(eventName, funct);
}
DomLib.prototype.removeEvent = function (obj, type, fn) {
if (obj.detachEvent) {
obj.detachEvent( 'on'+type, obj[type+fn] );
obj[type+fn] = null;
} else {
obj.removeEventListener( type, fn, false );
}
}
DomLib.prototype.hasEventEx = function (el, eventName, funct) {
if (!el.eventHolder) {
return false;
} else {
for (var i = 0; i < el.eventHolder.length; i++) {
if (el.eventHolder[i][0] == eventType && String(el.eventHolder[i][1]) == String(funct)) {
return true;
}
}
}
return false;
}
/**
* @return - returns true if an event was removed
*/
DomLib.prototype.removeEventsByTypeEx = function (el, eventType) {
if (el.eventHolder) {
var removed = 0;
for (var i = 0; i < el.eventHolder.length; i++) {
if (el.eventHolder[i][0] == eventType) {
this.removeEvent(el, eventType, el.eventHolder[i][1]);
el.eventHolder.splice(i, 1);
removed++;
i--;
}
}
return (removed > 0) ? true : false;
} else {
return false;
}
}
测试HTML页面:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Expires" content="Fri, Jan 01 1900 00:00:00 GMT">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Lang" content="en">
<meta name="author" content="">
<meta http-equiv="Reply-to" content="@.com">
<meta name="generator" content="PhpED 5.8">
<meta name="description" content="">
<meta name="keywords" content="">
<meta name="creation-date" content="01/01/2009">
<meta name="revisit-after" content="15 days">
<title>DomLibTest</title>
<link rel="stylesheet" type="text/css" href="my.css">
<!-- FILL IN: Location of your jQuery library -->
<script type="text/javascript" src="jQuery/jQuery-current.js"></script>
<!-- FILL IN: Plugin for debugging ... http://www.ecitadel.net/blog/2009/12/08/developing-jquery-use-dump-instead-alert -->
<script type="text/javascript" src="jQuery/jQuery.dump.js"></script>
<script type="text/javascript" src="DomLib.js"></script>
</head>
<body>
<div id="testElem-1"></div>
<script type="text/javascript">
<!--
var domLib = new DomLib();
function removeTest(el) {
var funct = function() { alert("#1: How Are You?");};
var funct2 = function() { alert("#2: How Are You?");};
domLib.regEventEx(el, "click", funct);
domLib.regEventEx(el, "mousemove", funct2);
domLib.regEventEx(el, "mousemove", funct2);
domLib.regEventEx(el, "mousemove", funct2);
$.dump(el.eventHolder);
domLib.removeEventsByTypeEx(el, "mousemove");
$.dump(el.eventHolder);
}
removeTest(document.getElementById('testElem-1'));
-->
</script>
</body>
</html>
答案 3 :(得分:5)
根据this thread,您可以使用cloneNode从javascript元素中删除所有事件侦听器,如下所示:
var new_element = old_element.cloneNode(true);
old_element.parentNode.replaceChild(new_element, old_element);
答案 4 :(得分:0)
将几种方式结合在一起,包括查找和删除所有&#34; on ...&#34;来自元素属性列表的event-attributes,否则你只是删除了DOM函数处理程序...
icompile.eladkarako.com/force-chrome-password-saving-by-removing-event-handlers-the-jsninja-way/
非常欢迎您添加所有moo / jQuery /其他框架,因为以下内容中没有依赖任何内容(哎呀!如果甚至应该在IE中工作)
答案 5 :(得分:0)
function removeEvents(elem) {
var children = elem.children;
for (var i = 0; i < children.length; i++) {
var el = children[i];
el.removeAttribute("onkeyup");
el.removeAttribute("onmouseover");
el.removeAttribute("onmouseout");
el.removeAttribute("onclick");
removeEvents(el);
}
}
这对我有用
答案 6 :(得分:-6)
据我所知,你根本不能为一个元素添加两个onclick处理程序。
假设obj是一个元素,那么obj的属性onclick被认为是一个函数,然后在该事件发生时被调用为方法。如果它不是一个功能,那么什么都不会发生。
JavaScript继承自Scheme一个非常有趣的属性,在JavaScript中,您没有像在PHP或C中那样定义函数。您可以创建匿名函数并将它们存储在变量中。 Javascript是'Lisp-1',没有函数标识符,有变量,可以容纳数字,数组和函数。
function name(arg) {return arg;}
如果我没有误认为真的糖:
name = function(arg) {return arg;};
'name'这里是一个变量,无论我们如何定义该函数,我们也可以重新设置它。与Java的对象模型不同,在Javascript中,'method'纯粹是一个属性,一个简单地包含可能使用或不使用'this'关键字的函数的变量。这就是为什么你不能同时有两个onclick事件。只要单击它,运行时环境就会调用名为'onclick'的元素的属性(预期会包含一个函数)。将其视为调用“main”启动程序的相同ad hoc类型行为。
要分配多个事件处理程序,可以使用带副作用的函数,例如。
obj.onclick = function {firstEvent();secondEvent();}
要更改或删除它,我们会像任何变量一样重新分配或取消分配。
obj.onclick = null;
如果我们需要以另一种方式调用该行为:
obj.onclick();
我们也可以在该函数中使用它来改变对象本身或引用它。
编辑:哦等等,我现在看到你的意思是“按钮”许多不同的按钮。
那么,你只需收集所有元素,如:
allElements = document.getElementsByTagName('*');
然后你使用循环:
var i = 0; while(obj = allElements[i++]) obj.onclick = null;
(不,那个单身=不是拼写错误)