Можно ли удалить все обработчики событий данного элемента в JavaScript? - PullRequest
36 голосов
/ 15 мая 2010

Я хотел бы удалить ВСЕ обработчики для данного типа события. Допустим, я дважды добавил «событие onclick» к кнопке, и теперь я хотел бы вернуться к исходному состоянию, когда для кнопки не был установлен обработчик события.

Как я могу это сделать?

PS: я нашел методы removeEventListener (не-IE) / detachEvent (IE), но функции хотят, чтобы я передал в качестве параметра функцию, которая обрабатывает событие, которое мне кажется довольно неуклюжим, потому что мне пришлось бы хранить где-то функционирует

РЕДАКТИРОВАТЬ: http://ejohn.org/blog/flexible-javascript-events/ - я сейчас использую этот код

Ответы [ 7 ]

10 голосов
/ 15 мая 2010

Возможно, будет хорошей идеей использовать jQuery или аналогичную инфраструктуру для управления всеми обработчиками событий. Это даст вам простые в использовании, ненавязчивые функции для добавления и удаления обработчиков событий:

$(...).bind('click', function() { ... });
$(...).unbind('click');
// or, to unbind all events:
$(...).unbind();
9 голосов
/ 08 марта 2016

Если у вас есть только один дочерний элемент под родительским элементом вашего элемента (или если вы не возражаете против всех потерянных обработчиков событий родного брата):

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

Проверено в Chrome 49, FF 44, IE 11

Удаляет все 'addEventListener' -s.

7 голосов
/ 15 мая 2010

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>
5 голосов
/ 15 мая 2010

Согласно этой теме , вы можете использовать cloneNode, чтобы убрать все прослушиватели событий из элемента javascript, например:

 var new_element = old_element.cloneNode(true);
 old_element.parentNode.replaceChild(new_element, old_element);
0 голосов
/ 23 февраля 2019
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);
  }
}

это сработало для меня

0 голосов
/ 22 октября 2015

Объединение нескольких способов вместе, включая поиск и удаление всех атрибутов события «on ...» из списка атрибутов элемента, в противном случае вы удаляете только обработчики функций DOM ...

icompile.eladkarako.com / сила-хром-пароль сберегательный по удаляющему-обработке событий, заместитель jsninja-полосной /

вы можете добавить все свои фреймворки moo / jQuery / other, так как ни у одного из них нет зависимостей (черт возьми! Если должно даже работать в IE)

0 голосов
/ 15 мая 2010

Насколько я знаю, вы вообще не можете добавить два обработчика onclick к элементу.

Скажем, obj является элементом, тогда свойство onclick объекта obj считается функцией, а затем вызывается как метод всякий раз, когда происходит это событие. Если это не функция, ничего не произойдет.

JavaScript унаследовал от Scheme очень интересное свойство, в JavaScript вы не определяете функции как в PHP или C. Вы создаете анонимные функции и сохраняете их в переменной. Javascript - это «Lisp-1», здесь нет идентификаторов функций, есть переменные, которые могут содержать номера, массивы и функции.

function name(arg) {return arg;}

Если я не ошибаюсь, действительно сахар для:

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

'name' здесь переменная, мы также можем переопределить ее независимо от того, как мы определили эту функцию. В отличие от объектной модели Java, в Javascript «метод» - это просто свойство, переменная, которая просто содержит функцию, которая может использовать или не использовать ключевое слово «this». Вот почему вы не можете иметь два события onclick одновременно. Среда выполнения просто вызывает свойство (которое, как ожидается, будет содержать функцию) элемента, называемого onclick, всякий раз, когда вы щелкаете по нему. Рассматривайте это как то же поведение типа ad hoc вызова 'main' для запуска программы.

Чтобы назначить несколько обработчиков событий, вы используете функцию с побочным эффектом, например.

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

Чтобы изменить или удалить его, мы переназначаем или отменяем его как любую переменную.

obj.onclick = null;

И в случае, если нам нужно вызвать это поведение по-другому:

obj.onclick();

Мы также можем использовать это в этой функции, конечно, чтобы изменить сам объект или ссылаться на него.

Редактировать: Ой, подожди, теперь я вижу, что ты имеешь в виду с помощью кнопки много разных кнопок.

Ну, тогда вы просто собираете все элементы, как:

allElements = document.getElementsByTagName('*');

А затем вы используете цикл:

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

(и нет, этот одиночный = не опечатка)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...