2012-06-24 4 views
4

Рассмотрим основной addEventListener вaddEventListener для новых элементов

window.onload=function(){ 
    document.getElementById("alert") 
    .addEventListener('click', function(){ 
    alert("OK"); 
    }, false); 
} 

где <div id="alert">ALERT</div> не существует в исходном документе, и мы называем его от внешнего источника с помощью AJAX. Как мы можем заставить addEventListener работать с новыми добавленными элементами в документы (после первоначальной проверки элементов DOM на window.onload)?

В jQuery мы делаем это по live() или delegate(); но как мы можем это сделать с addEventListener в чистом Javascript? На самом деле, я ищу эквивалент delegate(), так как live() прикрепляет событие к корневому документу; Я хочу сделать новое прослушивание событий на уровне parent.

ответ

5

Слишком упрощенная и очень далекая от системы событий jQuery, но основная идея есть.

http://jsfiddle.net/fJzBL/

var div = document.createElement("div"), 
    prefix = ["moz","webkit","ms","o"].filter(function(prefix){ 
     return prefix+"MatchesSelector" in div; 
    })[0] + "MatchesSelector"; 

Element.prototype.addDelegateListener = function(type, selector, fn) { 

    this.addEventListener(type, function(e){ 
     var target = e.target; 

     while(target && target !== this && !target[prefix](selector)) { 
      target = target.parentNode; 
     } 

     if(target && target !== this) { 
      return fn.call(target, e); 
     } 

    }, false); 
}; 

Что вам не хватает на с этим:

  • оптимизации производительности, каждый делегат слушатель будет работать полный цикл, так что если вы добавите много на одном элементе, вы будете работать все эти петли
  • Writable event object. Таким образом, вы не можете исправить e.currentTarget что очень важно, так как this обычно используются в качестве ссылки на какой-то экземпляр
  • Там нет реализации хранилища данных, так что не существует хороший способ, чтобы удалить обработчик, если вы сделаете функции вручную каждый раз
  • только бурлящие события поддерживаются, поэтому нет "change" или "submit" и т.д., которые вы приняли как должное с JQuery
  • Многих других, которые я просто забывая о том на текущем
+0

очень интересные моменты, и я узнал, но я думаю, что делегат jQuery() также имеет эти недостатки более или менее. – Googlebot

+0

@ Не все эти недостатки - это то, что у jQuery нет – Esailija

1
document.addEventListener("DOMNodeInserted", evtNewElement, false); 

function evtNewElement(e) { 
    try { 
     switch(e.target.id) { 
      case 'alert': /* addEventListener stuff */ ; break; 
      default: /**/ 
     } 
    } catch(ex) {} 
} 

Примечание: в соответствии с комментарием @hemlock, похоже, это семейство событий устарело. Вместо этого мы должны отправиться в сторону mutation observers.

+1

Примечания: Мутация события устаревшее в уровне 3 йот. http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMNodeInserted – Hemlock

+0

спасибо, я этого не знал. Увидят для обходного пути тогда – Sebas

Смежные вопросы