Javascript 是否可以删除javascript中给定元素的所有事件处理程序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2837542/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 02:07:08  来源:igfitidea点击:

Is it possible to remove all event handlers of a given element in javascript?

javascriptevents

提问by Martin Vseticka

I would like to remove ALL handlers for a given event type. Let's say I've added twice "onclick event" to a button and now I would like to return back to the original state where no event handler was set to the button.

我想删除给定事件类型的所有处理程序。假设我已经向按钮添加了两次“onclick 事件”,现在我想返回到没有为按钮设置事件处理程序的原始状态。

How can I do that?

我怎样才能做到这一点?

P.S.: I've found removeEventListener (non-IE)/detachEvent (IE) methods but the functions want me to pass as a parameter the function that handles the event which seems to me quite clumsy because I would have to store the functions somewhere.

PS:我找到了 removeEventListener(非 IE)/detachEvent(IE)方法,但函数希望我将处理事件的函数作为参数传递,这在我看来很笨拙,因为我必须将这些函数存储在某处。

EDIT: http://ejohn.org/blog/flexible-javascript-events/- I'm now using this code

编辑:http: //ejohn.org/blog/flexible-javascript-events/- 我现在使用这个代码

采纳答案by Martin Vseticka

http://www.quirksmode.org/js/events_advanced.html- "Which event handlers are registered?" - it seems it's not possible without DOM 3 level :-(

http://www.quirksmode.org/js/events_advanced.html- “注册了哪些事件处理程序?” - 似乎没有 DOM 3 级别是不可能的:-(

EDIT: I've come up with this code. It suits my needs. Maybe it will be helpful for someone else.

编辑:我想出了这个代码。它适合我的需求。也许这对其他人有帮助。

Javascript:

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; 
  }
}

Testing HTML page:

测试 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>

回答by ThiefMaster

It might be a good idea to use jQuery or a similar framework to manage all event handlers. This will give you easy-to-use, unobtrusive functions to add and remove event handlers:

使用 jQuery 或类似框架来管理所有事件处理程序可能是个好主意。这将为您提供易于使用、不显眼的函数来添加和删除事件处理程序:

$(...).bind('click', function() { ... });
$(...).unbind('click');
// or, to unbind all events:
$(...).unbind();

回答by fenyoapa

If you have only one child element under your element's parent (or if you don't mind all sibling's event handlers lost too):

如果你的元素的父元素下只有一个子元素(或者如果你不介意所有兄弟的事件处理程序也丢失了):

elem.parentElement.innerHTML = elem.parentElement.innerHTML;

Tested in Chrome 49, FF 44, IE 11

在 Chrome 49、FF 44、IE 11 中测试

It removes all 'addEventListener'-s.

它删除所有“addEventListener”-s。

回答by Mathew

According to this thread, you can use cloneNode to strip all the event listeners from a javascript element, like so:

根据此线程,您可以使用 cloneNode 从 javascript 元素中删除所有事件侦听器,如下所示:

 var new_element = old_element.cloneNode(true);
 old_element.parentNode.replaceChild(new_element, old_element);

回答by Mathew

Combining few ways together, including finding and removing all of the "on..." event-attributes from the element's attribute list, otherwise you are only removing the DOM function-handlers...

将几种方法结合在一起,包括从元素的属性列表中查找和删除所有“on...”事件属性,否则您只是删除 DOM 函数处理程序...

icompile.eladkarako.com/force-chrome-password-saving-by-removing-event-handlers-the-jsninja-way/

icompile.eladkarako.com/force-chrome-password-saving-by-removing-event-handlers-the-jsninja-way/

you are most welcome to add all your moo/jQuery/other framework since the following has no-dependencies in any of those (heck! if should even work in IE)

非常欢迎您添加所有 moo/jQuery/其他框架,因为以下任何一个都没有依赖项(哎呀!如果甚至应该在 IE 中工作)

回答by indikaanu83

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);
  }
}

this worked for me

这对我有用

回答by Zorf

As far as I know, you cannot add two onclick handlers to an element at all.

据我所知,您根本无法向元素添加两个 onclick 处理程序。

Say obj is an element then the property onclick of obj is considered a function and then called as a method whenever that event occurs. If it's not a function nothing will happen.

假设 obj 是一个元素,那么 obj 的属性 onclick 被视为一个函数,然后在该事件发生时作为方法调用。如果它不是一个函数,什么都不会发生。

JavaScript inherited from Scheme a very interesting property, in JavaScript, you don't define functions as in PHP or C. You create anonymous functions and store them in a variable. Javascript is 'Lisp-1', there are no function identifiers, there are variables, which can house numbers, arrays, and functions.

JavaScript 从 Scheme 继承了一个非常有趣的属性,在 JavaScript 中,您不必像在 PHP 或 C 中那样定义函数。您可以创建匿名函数并将它们存储在变量中。Javascript 是“Lisp-1”,没有函数标识符,只有变量,可以存放数字、数组和函数。

function name(arg) {return arg;}

Is if I'm not mistaken truly sugar for:

如果我没有误认为真正的糖是:

name = function(arg) {return arg;};

'name' here is a variable, we can also re-asign it no matter how we defined that function. Unlike Java's object model, in Javascript, a 'method' is purely a property, a variable that simply holds a function that may or may not use the 'this' keyword. This is why you can't have two onclick event at the same time. The runtime environment simply calls the property (which is expected to house a function) of the element called 'onclick' whenever you click on it. See it as the same ad hoc type behaviour of calling 'main' to start a program.

'name' 这里是一个变量,无论我们如何定义该函数,我们也可以重新分配它。与 Java 的对象模型不同,在 Javascript 中,“方法”纯粹是一个属性,一个变量,它只保存一个可能使用或不使用“this”关键字的函数。这就是为什么您不能同时拥有两个 onclick 事件的原因。运行时环境只是在您单击它时调用名为“onclick”的元素的属性(预计该属性将容纳一个函数)。将其视为调用“main”以启动程序的相同特殊类型行为。

To assign multiple event handlers, you use a function with a side effect, like.

要分配多个事件处理程序,您可以使用具有副作用的函数,例如。

obj.onclick = function {firstEvent();secondEvent();}

To change or remove it, we re-assign or de-assign it like any variable.

要更改或删除它,我们像任何变量一样重新分配或取消分配它。

obj.onclick = null;

And in case we need to invoke that behaviour in another way:

如果我们需要以另一种方式调用该行为:

obj.onclick();

We can also use this in that function of course to change the object itself or reference it.

当然,我们也可以在该函数中使用 this 来更改对象本身或引用它。

Edit: Oh wait, I see now that you mean wih 'a button' many different buttons.

编辑:哦等等,我现在明白你的意思是“一个按钮”有很多不同的按钮。

Well, then you just collect all elements like:

那么,您只需收集所有元素,例如:

allElements = document.getElementsByTagName('*');

And then you use a loop:

然后你使用一个循环:

var i = 0; while(obj = allElements[i++]) obj.onclick = null;

(and no, that single = is not a typo)

(不,那个单一的 = 不是错字)