代码之家  ›  专栏  ›  技术社区  ›  MartyIX

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

  •  36
  • MartyIX  · 技术社区  · 15 年前

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

    我该怎么做?

    P.S.:我找到了removeEventListener(non-ie)/detachEvent(ie)方法,但是函数希望我将处理事件的函数作为参数传递,在我看来这很笨拙,因为我必须将函数存储在某个地方。

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

    7 回复  |  直到 6 年前
        1
  •  10
  •   ThiefMaster    15 年前

    最好使用jquery或类似的框架来管理所有事件处理程序。 这将为您提供易于使用、不引人注目的函数来添加和删除事件处理程序:

    $(...).bind('click', function() { ... });
    $(...).unbind('click');
    // or, to unbind all events:
    $(...).unbind();
    
        2
  •  8
  •   fenyoapa    9 年前

    如果在元素的父元素下只有一个子元素(或者如果您不介意所有同级的事件处理程序都丢失):

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

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

    它删除所有的“addEventListener”。

        3
  •  7
  •   MartyIX    15 年前

    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>
    
        4
  •  5
  •   Mathew    15 年前

    根据 this thread ,您可以使用clonenode从一个javascript元素中除去所有事件侦听器,如下所示:

     var new_element = old_element.cloneNode(true);
     old_element.parentNode.replaceChild(new_element, old_element);
    
        5
  •  0
  •   user257319    9 年前

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

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

    非常欢迎您添加所有的moo/jquery/其他框架,因为以下框架中没有任何依赖项(见鬼!如果要在IE中工作的话)

        6
  •  0
  •   indikaanu83    6 年前
    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);
      }
    }
    

    这对我有用

        7
  •  -6
  •   Zorf    15 年前

    据我所知,一个元素不能添加两个onclick处理程序。

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

    从Scheme继承的javascript是一个非常有趣的属性,在javascript中,您不会像在php或c中那样定义函数。您创建匿名函数并将其存储在变量中。javascript是“lisp-1”,没有函数标识符,有变量,可以容纳数字、数组和函数。

    function name(arg) {return arg;}
    

    如果我没有把糖误认为:

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

    这里的“name”是一个变量,无论我们如何定义该函数,我们都可以对它重新赋值。与Java的对象模型不同,在JavaScript中,一个“方法”纯粹是一个属性,一个简单地保存一个可以使用或不使用“这个”关键字的函数的变量。这就是为什么你不能同时有两个onclick事件。运行时环境只需在每次单击时调用名为“on click”的元素的属性(应该包含函数)。把它看作是调用“main”来启动程序的相同的特殊类型行为。

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

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

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

    obj.onclick = null;
    

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

    obj.onclick();
    

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

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

    那么,你只需要收集所有元素,比如:

    allElements = document.getElementsByTagName('*');
    

    然后使用循环:

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

    (不,那个单曲=不是打字错误)