Подтвердить что ты не робот

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

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

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

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

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

4b9b3361

Ответ 1

http://www.quirksmode.org/js/events_advanced.html - "Какие обработчики событий зарегистрированы?" - кажется, это невозможно без уровня DOM 3: - (

EDIT: Я придумал этот код. Это соответствует моим потребностям. Возможно, это будет полезно для кого-то еще.

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>

Ответ 2

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

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

Ответ 3

Если у вас есть только один дочерний элемент под родительским элементом (или если вы не возражаете против всех обработчиков событий sibling), выполните следующие действия.

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

Протестировано в Chrome 49, FF 44, IE 11

Он удаляет все 'addEventListener'-s.

Ответ 4

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

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

Ответ 5

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

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

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

Ответ 6

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

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

JavaScript унаследовал от Scheme очень интересное свойство, в JavaScript вы не определяете функции, как в PHP или C. Вы создаете анонимные функции и сохраняете их в переменной. Javascript is '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();

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

Редактировать: О, подождите, теперь я вижу, что вы имеете в виду кнопку с несколькими кнопками.

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

allElements = document.getElementsByTagName('*');

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

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

(и нет, что single = не является опечаткой)