Skip to content

Instantly share code, notes, and snippets.

@pbogden
Last active May 6, 2021 11:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pbogden/f359cd2d9b754db5d3ba to your computer and use it in GitHub Desktop.
Save pbogden/f359cd2d9b754db5d3ba to your computer and use it in GitHub Desktop.
event

Event bubbling & capturing demo

  1. SVG elements are not nested -- they don't bubble to each other. Topmost element is the target.
  2. Blue SVG rect captures the event with d3.event.stopPropagation();
  3. Nested DIV elements bubble to each other up the DOM tree.
  4. Non-nested DIV elements don't bubble to each other.
<!DOCTYPE html>
<meta charset="utf-8">
<title>event</title>
<style>
body {
margin: 0;
}
div {
position: absolute;
background-color: steelblue;
}
#div1 {
top: 200px;
left: 460px;
width: 200px;
height: 200px;
}
#div2 {
background-color: crimson;
top: 25px;
left: 25px;
width: 150px;
height: 150px;
}
#div3 {
top: 25px;
left: 25px;
width: 100px;
height: 100px;
background-color: gold;
text-align: center;
line-height: 25px;
}
#div4 {
top: 200px;
left: 700px;
width: 200px;
height: 200px;
}
#div5 {
top: 225px;
left: 725px;
width: 150px;
height: 150px;
background-color: crimson;
}
#div6 {
top: 250px;
left: 750px;
width: 100px;
height: 100px;
background-color: gold;
text-align: center;
line-height: 25px;
}
svg {
background-color: lightgray;
}
body {
font-family: sans-serif;
font-size: 20px;
}
#info {
position: absolute;
top: 10px;
left: 50px;
background-color: white;
padding: 10px;
}
</style>
<body id='body'>
<svg></svg>
<div id="info"></div>
<div id='div1'>
<div id='div2'>
<div id='div3'><br>DIV<br>nested
</div>
</div>
</div>
<div id='div4'> </div>
<div id='div5'> </div>
<div id='div6'> <br>DIV<br>not nested</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<script>
var width = 960, height = 500,
eventType = "click",
count = 0;
d3.selectAll('div')
.on('click', bubbled)
d3.select('body')
.on('click', bubbled)
d3.select(window)
.on('click', captured)
var info = d3.select("#info").html("click something");
var svg = d3.select("svg")
.attr("width", width)
.attr("height", height)
.attr("id", "svg")
.on(eventType, bubbled);
var g = svg.append("g");
g.append('rect')
.attr("id", "blue-rect")
.attr("x", 100)
.attr("y", 200)
.attr("width", 200)
.attr("height", 200)
.style("fill", "steelblue")
.on(eventType, captured);
g.append('rect')
.attr("id", "red-rect")
.attr("x", 125)
.attr("y", 225)
.attr("width", 150)
.attr("height", 150)
.style("fill", "crimson")
.on(eventType, bubbled);
g.append('rect')
.attr("id", "yellow-rect")
.attr("x", 150)
.attr("y", 250)
.attr("width", 100)
.attr("height", 100)
.style("fill", "gold")
.on(eventType, bubbled);
g.append('text')
.attr('x', 200)
.attr('y', 300)
.attr('dy', "0.3em")
.style('text-anchor', 'middle')
.style('pointer-events', 'none')
.text('SVG')
function captured(){
if (count === 0) info.html("");
d3.event.stopPropagation()
var str = count++ + ": "
+ label(this) + " captured the event from target: " + label(d3.event.target)
+ "<br>" + info.html();
info.html(str);
count = 0;
}
function bubbled(){
console.log('background-color from getComputedStyle', window.getComputedStyle(this, null).getPropertyValue('background-color'))
console.log('fill (computed)', window.getComputedStyle(this, null).getPropertyValue('fill'))
console.log('style.fill', this.style.fill)
console.log(this.style)
if (count === 0) info.html("");
var str = count++ + ": "
+ label(this) + " bubbled the event from target: " + label(d3.event.target)
+ "<br>" + info.html();
info.html(str);
}
function label(that) {
try {
return d3.select(that).attr('id');
} catch (e) {
console.log('Caught error', e);
return d3.select(that).toString();
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment