Skip to content

Instantly share code, notes, and snippets.

@karataev
Created November 29, 2018 14:20
Show Gist options
  • Save karataev/da4b4821741c95b8958fc144adecf8ca to your computer and use it in GitHub Desktop.
Save karataev/da4b4821741c95b8958fc144adecf8ca to your computer and use it in GitHub Desktop.
Events capture/bubble visualization
div {
position: relative;
padding: 30px;
}
label {
display: block;
}
div:after {
position: absolute;
top: 5px;
left: 5px;
box-sizing: border-box;
}
div.highlight {
background: #1e1f26;
}
.one {background: #588C7E}
.one:after {content: '1'}
.two {background: #F2E394}
.two:after {content: '2'}
.three {background: #F2AE72}
.three:after {content: '3'}
.four {background: #D96459}
.four:after {content: '4'}
.five {background: #8C4646}
.five:after {content: '5'}
<p>
Click on an elment to see events capture/bubble.
</p>
<p>
<label>
capture phase (down)
<input type="checkbox" class="capture">
</label>
<label>
bubble phase (up)
<input type="checkbox" checked class="bubble" />
</label>
</p>
<div class="one">
<div class="two">
<div class="three">
<div class="four">
<div class="five"></div>
</div>
</div>
</div>
</div>
/*
Пример: https://jsfiddle.net/eg1mynah/
В DOM вшита система событий для реагирования на внешние и внутренние раздражители.
При клике на элементе событие начинает свой путь с самого верхнего элемента (document) и спускается до элемента, по которому
кликнул пользователь. Этот путь называется capturing phase. После этого событие начинает всплывать в обратную сторону до
корневого элемента document. Это bubbling phase.
addEventListener('click', handler, true) <- подписка в capturing phase.
addEventListener('click', handler) <- подписка в bubble phase.
Первым вариантом почти никто не пользуется. В реальной разработке используется подписка на события в фазе всплытия.
Событие можно остановить, используя .stopPropagation() метод.
*/
console.clear();
let capturePhase = false;
let bubblePhase = true;
document.querySelector('.capture').addEventListener('change', e => {
capturePhase = e.target.checked;
cloneTree();
addListeners();
})
document.querySelector('.bubble').addEventListener('change', e => {
bubblePhase = e.target.checked;
cloneTree();
addListeners();
})
let query = [];
function cloneTree() {
let root = document.querySelector('.one');
let clone = root.cloneNode(true);
document.body.removeChild(root);
document.body.appendChild(clone);
}
function addListeners() {
if (capturePhase) {
document.querySelectorAll('div').forEach(el => {
el.addEventListener('click', e => {
query.push(el);
}, true)
})
}
if (bubblePhase) {
document.querySelectorAll('div').forEach(el => {
el.addEventListener('click', e => {
query.push(el);
})
})
}
}
addListeners();
setInterval(() => {
if (query.length === 0) return;
let el = query.shift();
//console.log(el);
el.classList.add('highlight');
setTimeout(() => {
el.classList.remove('highlight');
}, 100);
}, 100);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment