Предотвращение всплывания (bubbling) и захвата (capture) событий

Предотвратить передачу события от одного элемента другому, так называемое "всплывание" события, можно при помощи следующей функции:

function stopBubble(oEvent){
    if(oEvent && oEvent.stopPropagation)
        oEvent.stopPropagation();    // для DOM-совместимых браузеров
    else
        window.event.cancelBubble = true; //для IE
}

Здесь oEvent – это объект "событие". Если объект oEvent не определен (имеем дело с Internet Explorer), то используем window.event.

Для тех, кто не знает, что такое передача событий, вкратце объясню его смысл.

Событие JavaScript выполняется в две фазы - "захват" (capturing) и "всплывание" (bubbling). Эти схемы передачи событий определяют, какие элементы будут обрабатывать данное событие и в каком порядке. Пример передачи события для обоих схем представлен на следующем рисунке:

Захват и всплывание событий

Рисунок показывает, в каком порядке вызываются обработчики событий при щелчке на ссылке.

Вначале вызывается обработчик для объекта document, затем <body>, затем <div> и так далее до элемента <a>. Это называется "фазой захвата" события.

По окончании первой фазы, начинается вторая - "всплывание" события, когда обработчики событий вызываются в обратном порядке: <a>, <li> и так далее до объекта document.

DOM-совместимые браузеры поддерживают оба вида передачи событий, в то время как Internet Explorer поддерживает только всплывание.

При использовании обычных обработчиков событий выполняется только вторая фаза - всплывание. Если же вместо обработчиков добавляются слушатели событий при помощи функции addEventListener(), то тип передачи событий можно выбирать:

// используется всплывание
elem.addEventListener('click', func, false);
// используется захват
elem.addEventListener('click', func, true);

Последний параметр в функции addEventListener() указывает на тип передачи событий, если false, то используется всплывание, если true, то захват.

Теперь объясню, для чего же нужно прерывать передачу событий.

Допустим, что в приведенном на рисунке примере, элементу <a> и его родительскому элементу <li> назначены обработчики событий. Тогда, при щелчке на ссылке, выполнятся оба обработчика. Однако, если нам необходимо выполнить только обработчик для ссылки, то применяем приведенную выше функцию:

function linkHandler(oEvent){
       oEvent = oEvent || window.event;        // получаем объект Event

       // тело обработчика
       // ...

       // предотвращаем дальнейшую передачу события
       stopBubble(oEvent);
}
function stopBubble(oEvent){
       if(oEvent && oEvent.stopPropagation)
               oEvent.stopPropagation();       // для DOM-совместимых браузеров
       else
               window.event.cancelBubble = true; //для IE
}

.