If you're interested in functional programming, you might also want to checkout my second blog which i'm actively working on!!

Friday, April 11, 2014

Javascript event delegation (bubbling)

<!DOCTYPE html>
<html>
<head>
<title>Using event delegation</title>
<script src="scripts/matchers.js"></script>
<script src="scripts/eventdelegation.js"></script>
</head>
<body>
<div id="item-list">
<div class="item">Item 1</div>
<span class="item">Item 2</span>
<h3>Item 3</h3>
</div>
</body>
</html>
view raw gistfile1.html hosted with ❤ by GitHub
/**
* matchers.js
**/
/***********************************************************/
function Matchers(matchers) {
this.matchers = matchers || [];
}
Matchers.prototype.getMatchers = function() {
return this.matchers;
}
Matchers.prototype.add = function(matcher) {
return new Matchers(this.matchers.concat(matcher));
}
Matchers.prototype.matches = function(obj) {
return this.matchers.every(function(matcher){
return matcher.matches(obj);
});
}
Matchers.from = function() {
var matchers = [];
for (var i=0, len=arguments.length; i < len; i++) {
matchers.push(arguments[i]);
}
return new Matchers(matchers);
}
/***********************************************************/
function AbstractMatcher(predicate) {
this.predicate = predicate;
}
AbstractMatcher.prototype.matches = function(obj) {
return this.predicate(obj);
}
/***********************************************************/
ElementMatcher.prototype.constructor = ElementMatcher;
ElementMatcher.prototype = new AbstractMatcher();
function ElementMatcher(predicate) {
AbstractMatcher.prototype.constructor.call(this, predicate);
}
ElementMatcher.byClassName = function(className) {
return new ElementMatcher(
function(element) {
var classes = element.className.split(" ");
if (!classes) return false;
return classes.indexOf(className) > -1;
}
);
}
ElementMatcher.byNodeName = function(nodeName) {
return new ElementMatcher(
function(element) {
return element.nodeName === nodeName.toUpperCase();
}
);
}
/***********************************************************/
view raw gistfile1.js hosted with ❤ by GitHub
/**
* eventdelegation.js
*
* Remark: this does not work in IE as I use addEventListener which is not supported by IE.
**/
window.onload = (function(){
return function(){
//only place an onclick handler on the parent and let onclick events from the actual
//items bubble up to the parent where we handle them
document.getElementById("item-list").addEventListener("click", function(event) {
var target = event.target;
if (Matchers.from(ElementMatcher.byNodeName("div"), ElementMatcher.byClassName("item")).matches(target)) {
alert("You clicked on a <div class=\"item\"> with value '" + target.innerHTML + "'");
} else if(ElementMatcher.byClassName("item").matches(target)) {
alert("You clicked on a element with class=\"*item*\" with value '" + target.innerHTML + "'");
} else {
alert("We are not handling this click event");
}
});
};
})();
/** Compare this to JQuery
http://api.jquery.com/on/
//attach an onlick handler to each table row
$( "#dataTable tbody tr" ).on( "click", function() {
alert( $( this ).text() );
});
//attach an onclick handler to the table rows container -> tbody (use event delegation)
$( "#dataTable tbody" ).on( "click", "tr", function() {
alert( $( this ).text() );
});
**/
view raw gistfile1.js hosted with ❤ by GitHub

No comments:

Post a Comment