Действительно ли возможно удалить все обработчики событий данного элемента в JavaScript?

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

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

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

Править: http://ejohn.org/blog/flexible-javascript-events/ - я теперь использую этот код

38
задан Martin Vseticka 22 October 2015 в 05:08
поделиться

4 ответа

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>
7
ответ дан 27 November 2019 в 03:56
поделиться

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

$(...).bind('click', function() { ... });
$(...).unbind('click');
// or, to unbind all events:
$(...).unbind();
12
ответ дан 27 November 2019 в 03:56
поделиться

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

 var new_element = old_element.cloneNode(true);
 old_element.parentNode.replaceChild(new_element, old_element);
7
ответ дан 27 November 2019 в 03:56
поделиться

Насколько мне известно, вы вообще не можете добавить к элементу два обработчика 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», всякий раз, когда вы щелкаете по нему. Рассматривайте это как одно и то же поведение специального типа при вызове main для запуска программы.

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

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

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

obj.onclick = null;

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

obj.onclick();

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

Edit: Ой, подождите, теперь я понимаю, что вы имеете в виду «кнопка», много разных кнопок.

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

allElements = document.getElementsByTagName('*');

И затем используете цикл:

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

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

-7
ответ дан 27 November 2019 в 03:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: