JavaScript events and bubbling -
i have following (simplified) markup code:
<div id="container"> <div data-value="1"> <span>click me 1</span> </div> <div data-value="2"> <span>click me 2</span> </div> </div> <div id="messages"></div> i want take advantage of bubbling attaching event listener on #container, , clicked children's data-value.
document.getelementbyid('container').addeventlistener('click', function(e){ document.getelementbyid('messages').innerhtml = 'you clicked ' + e.target.dataset.value; }, false); everything works fine if clicked area div area (in red in fiddle). how can data-value when click comes children of div (e.g. click on blue span) data value without changing event listener?
here's fiddle: http://jsfiddle.net/hglagy31/1/
e.target element user clicked, showing undefined since <span> not have data-value attribute. go tree , find nearest ancestor contain data-value.
document.getelementbyid('container').addeventlistener('click', function(e) { // find nearest ancestor data-value defined var node = e.target; while (!node.dataset.value) { node = node.parentnode; } document.getelementbyid('messages').innerhtml = 'you clicked ' + node.dataset.value; }, false); #container > div { background: red; } #container > div > span { background: blue; color: white; } <div id="container"> <div data-value="1"> <span>click me 1</span> </div> <div data-value="2"> <span>click me 2</span> </div> </div> <div id="messages"></div> to make more robust, check whether node undefined before continuing in while loop , exit if so:
while (!node.dataset || !node.dataset.value) { node = node.parentnode; if (!node) { document.getelementbyid('messages').innerhtml = 'could not find data-value'; return; } } document.getelementbyid('container').addeventlistener('click', function(e) { // find nearest ancestor data-value defined var node = e.target; while (!node.dataset || !node.dataset.value) { node = node.parentnode; if (!node) { document.getelementbyid('messages').innerhtml = 'could not find data-value'; return; } } document.getelementbyid('messages').innerhtml = 'you clicked ' + node.dataset.value; }, false); #container > div { background: red; } #container > div > span { background: blue; color: white; } <div id="container"> <div data-value="1"> <span>click me 1</span> </div> <div data-value="2"> <span>click me 2</span> </div> <div> <span>click me 3</span> </div> </div> <div id="messages"></div>
Comments
Post a Comment