Распространение событий
Когда мы нажимаем на какой-либо элемент на станице и генерируется событие нажатия, то это событие может распространяться от элемента к элементу. Например, если мы нажимаем на блок div
, то также мы нажимаем и на элемент body
, в котором блок div
находится. То есть происходит распространение события.
Есть несколько форм распространения событий:
Восходящие (bubbling)
событие распространяется вверх по деревуDOM
от дочерних узлов к родительскимНисходящие (capturing)
событие распространяется вниз по деревуDOM
от родительских узлов к дочерним, пока не достигнет того элемента, на котором это событие и возникло
Восходящие события
Рассмотрим восходящие (bubbling)
события, которые распространяются в верх по дереву DOM
. Допустим, у нас есть следующая веб-страница:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
#blueRect{
width:100px;
height:100px;
background-color:blue;
}
#redRect{
width:50px;
height:50px;
background-color:red;
}
</style>
</head>
<body>
<div id="blueRect">
<div id="redRect"></div>
</div>
<script>
var redRect = document.getElementById("redRect");
redRect.addEventListener("click", function(){
console.log("Событие на redRect");
});
var blueRect = document.getElementById("blueRect");
blueRect.addEventListener("click", function(){
console.log("Событие на blueRect");
});
document.body.addEventListener("click", function(){
console.log("Событие на body");
});
</script>
</body>
</html>
Если мы нажмем на вложенный div
, то событие пойдет к родительскому элементу div
и далее к элементу body
:
Надо сказать, что подобное поведение не всегда является желательным. И в этом случае мы можем остановить распространение событие с помощью метода stopPropagation()
объекта Event
:
var redRect = document.getElementById("redRect");
redRect.addEventListener("click", function(e){
console.log("Событие на redRect");
e.stopPropagation();
});
И в результате нажатия событие будет обработано только обработчиком для redRect
.
Нисходящие события
События также могут быть нисходящие (capturing)
. Для их использования в метод addEventListener()
в качестве третьего необязательного параметра передается логическое значение true
или false
, которое указывает, будет ли событие нисходящим. По умолчанию все события восходящие.
Возьмем ту же веб-станицу, только изменим ее код javascript:
var redRect = document.getElementById("redRect");
redRect.addEventListener("click", function(){
console.log("Событие на redRect");
}, true);
var blueRect = document.getElementById("blueRect");
blueRect.addEventListener("click", function(){
console.log("Событие на blueRect");
}, true);
document.body.addEventListener("click", function(){
console.log("Событие на body");
}, true);
Теперь события будут распространяться в обратном порядке: