Предположим у нас есть html-таблица 100×100 ячеек,в каждой ячейке – ссылка. При нажатии на каждую, должно происходить что-либо невероятное.
Мы можем сделать 10 тыс обработчиков onclick и медленно, но верно добиться своей цели.
А можем глупостей не делать. Ведь хватит только одного!


Дело в том, что события в DOM умею “всплывать” – т.е. если представить документ в виде слоёной структуры, где сам document находиться сверху, радуя глаз хрустящей корочкой, а все дочерние элементы под ним, то событие возбуждённое на нижних уровнях, не найдя свой законный обработчик у потревоженного объекта начинает потихоньку лезть наверх, шевеля всё на своём пути, и искать свой обработчик последовательно у всех предков.
Что это собственно даёт? Это может существенно сократить количество обработчиков событий на странице. На идеальной сферической странице вакуумного веб-приложения всего один обработчик!

Перейду к примерам:

  window.onload = function(){
  var tbl = document.getElementById('tbl'), links = tbl.getElementsByTagName('a'), linkcount = links.length;
     for (var i = 0; i < linkcount; i++){
                  (function(){
                    var num = i;
                     x[i].onclick  = function(){  
                     alert('Это обработчик номер ' + num + ' из ' + linkcount + ', ужас правда?');
                     return false;
                  };
        })();
     }
  } 

Готово. 10000 обработчиков. Легко. Просто. И долго…

А теперь Горбатый! (Я сказал "Горбатый?!?")

      window.onload = function(){
         var tbl = document.getElementById("tbl");
         tbl.onclick = function(e) {
                e = e || window.event;
                var elem = e.target || e.srcElement;
                    if ('a' === elem.nodeName.toLowerCase()) {
                            alert('Это обработчик. Один. ЕДИНСТВЕННЫЙ!');
                    }
             }
      }

А если не видно разницы, то зачем платить больше ?

С jQuery эта техника будет выглядеть следующим образом:

    $('#tbl').bind('click',function(e) {
            if ($(e.target).is('a')) {
                    alert('Это обработчик. Один. ЕДИНСТВЕННЫЙ!');
                    return false;
            }
    });

В заключение пару плагинов для jQuery, берущие "пыльную" работу в свои руки:

jQuery.listen

$('#tbl').listen('click', 'a', function (e) {
    alert('Это обработчик. Один. ЕДИНСТВЕННЫЙ!');
    e.preventDefault();
});

и jquery.eventdelegation

$('#tbl').delegate('click', 'a', function () {
    alert('Это обработчик. Один. ЕДИНСТВЕННЫЙ!');
    return false;
});

Удачного всплытия!

Всплытие покажет
Tagged on:     

5 thoughts on “Всплытие покажет

  • 05.05.2008 at 15:30
    Permalink

    А зачем $(e.target).parent().parent().parent().is(‘table’) ? Тут тоже достаточно простой проверки nodeName.

  • 05.05.2008 at 16:20
    Permalink

    Верно, в данном случае достаточно. Спасибо, поправил.
    (сначала сделал пример сложнее, поэтому такие заборы остались)

  • 05.05.2008 at 18:31
    Permalink

    Еще момент не для данного случая, но существование которого возможно. В каком-то из браузеров у объекта не окажется события onclick.

  • 05.05.2008 at 19:02
    Permalink

    onclick есть у всех современных браузеров… во всяком случае, у всех, с кем работает jQuery:)

Leave a Reply