2011-06-17 4 views
1

Таким образом, мы имеем таблицу с большим количеством флажков, OnChange из флажка мы хотим вызвать некоторый яваскрипт мы используем что-то похожее на этом сниппаютEvent.observe неэффективен с прототипом javascript, альтернативы?

addEventObserver(elementId){ 
     // ($= means 'ends with') this is required for elementIds which are in a table and get prepended with some id 
     $$('[id$=:'+elementId+']').each(function(e) { 
      Event.observe(e, 'change', function(event) { 
       submitAction(something); 
      }); 
     }); 
} 

Так ниже входной флажка мы добавим вызов в яваскрипте функции

<input type="checkbox" name="somename" id="somePrependedIdsomeId">  
<script type="text/javascript" language="javascript"> 
        addEventObserver('someId'); 
       </script> 

это прекрасно работает с нашими настройками тестовой среды. В производстве, хотя у нас есть таблицы с ~ 700 флажками, и это заставляет браузер/cpu застревать.

Мы используем JSF

ответ

5

Я бы отказался от добавления прослушивателя событий к каждому отдельному флажку в пользу написания одного «умного» обработчика событий, прикрепленного к элементу контейнера. Вот простой пример:

var theDiv = document.getElementById("foo"); 
theDiv.onchange = function(e) { 
    if (e.target.tagName.toLowerCase() == "input" 
      && e.target.type.toLowerCase() == "checkbox") { 
     alert("do something"); 
    } 
} 

Демо: http://jsfiddle.net/xFC3A/

OnChange события, таким образом, захваченный контейнер DIV, который пузыри до. Событие, прикрепленное к div, может проверить тип элемента, который вызвал событие (source/target element depending on the browser), и реагировать соответствующим образом. Основными преимуществами являются:

  1. Только один обработчик событий - время не тратится на привязку обработчиков к сотням элементов.
  2. Он будет продолжать работать с динамически добавленными элементами (через AJAX, JS и т. Д.).

Read more about Event Delegation.

Некоторые полезные ссылки: http://www.quirksmode.org/js/events_properties.html

+1

также отличная точка. Один обработчик событий против700 обработчиков событий, безусловно, повысят производительность. – Scottie

+0

только вопрос ... theDiv.onchange ведет себя так же, как Event.observe? Я просто столкнулся с странным поведением с совместимостью, когда дело доходит до событий ... например. Toskan

+0

@Toskan - Используете ли вы Prototype для простого JS? Какой браузер? – karim79

1

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

Вы также используете метод Prototype each() ... можете ли вы перезаписать вещи, чтобы вместо этого использовать собственный javascript for()? Опять же, ссылаясь на jQuery здесь, но я получил НЕПРЕРЫВНУЮ прирост производительности за счет использования встроенных JS, а не библиотечных методов, когда это возможно. Я ускорил веб-приложение на 20x, удалив кучу методов jQuery .each() и заменив их на native для() циклов.

1

Я думаю Делегирование событие должно помочь вам, просто придаем умереть EventHandler Материнской всех Флажки

$('container').observe("change", changeBy); 

function changeBy(e){ 
       if (e.element().identify() != "container") { 
      doChange(e.element()); 
     } 
} 

function doChange(elem){ 
    submitAction(something); 
} 

Markup:

<div id="container"> <input type="checkbox" > ... </div> 

Вам не нужно делать foreach, и у вас нет сотен обработчиков событий, вы просто имеете один EventHandler, это довольно быстро.

1

Прототип уже обеспечивает делегирование события путем Event.on:

$('id_of_table').on('change', 'input[type=checkbox]', some_handler_function); 
+0

Это не работает в IE 8? – Toskan

+0

Я слышал, что IE беден от пузырящихся событий (на что опирается делегация), поэтому возможно, что это не сработает. Я не тестировал его явно. – clockworkgeek

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