This tutorial begins where Cross-Browser Event Handling left off. If we'd like to combine the encapsulation of event handling with the library written in Writing a DOM Library. We can do as follows:
(function(global) {
var XD = function(selector, container) {
return new XD.mth.init(selector, container);
};
var utils = {
...
};
var XD = function(selector, container) {
return new XD.mth.init(selector, container);
};
var utils = {
...
};
XD.Event = function(original) {
if(!this.stopPropagation) {
return new XD.Event(original);
}
// Copy properties
this.original = original;
this.type = original.type;
this.target = original.target || original.srcElement;
// .. Standardize other properties
};
XD.Event.prototype = {
stopPropagation: function() {
if(this.original.stopPropagation) {
this.original.stopPropagation();
}
else {
this.original.cancelBubble = true;
}
}
// Standardize other properties
};
// Create bind and unbind
if(document.addEventListener) {
utils.bind = function(element, eventType, handler) {
element.addEventListener(eventType, function(event) {
var result = handler.call(event.currentTarget, XD.Event(event));
if(result === false) {
event.preventDefault();
}
return result;
}, false);
};
utils.unbind = function(element, eventType, handler) {
element.removeEventListener(eventType, handler, false);
};
}
else if(document.attachEvent) {
utils.bind = function(element, eventType, handler) {
element.attachEvent('on' + eventType, function() {
var result = handler.call(element, XD.Event(window.event));
if(result === false) {
window.event.returnValue = false;
}
return result;
});
};
utils.unbind = function(element, eventType, handler) {
element.detachEvent(eventType, handler);
};
}
if(!this.stopPropagation) {
return new XD.Event(original);
}
// Copy properties
this.original = original;
this.type = original.type;
this.target = original.target || original.srcElement;
// .. Standardize other properties
};
XD.Event.prototype = {
stopPropagation: function() {
if(this.original.stopPropagation) {
this.original.stopPropagation();
}
else {
this.original.cancelBubble = true;
}
}
// Standardize other properties
};
// Create bind and unbind
if(document.addEventListener) {
utils.bind = function(element, eventType, handler) {
element.addEventListener(eventType, function(event) {
var result = handler.call(event.currentTarget, XD.Event(event));
if(result === false) {
event.preventDefault();
}
return result;
}, false);
};
utils.unbind = function(element, eventType, handler) {
element.removeEventListener(eventType, handler, false);
};
}
else if(document.attachEvent) {
utils.bind = function(element, eventType, handler) {
element.attachEvent('on' + eventType, function() {
var result = handler.call(element, XD.Event(window.event));
if(result === false) {
window.event.returnValue = false;
}
return result;
});
};
utils.unbind = function(element, eventType, handler) {
element.detachEvent(eventType, handler);
};
}
function extend(target, source) {
utils.each(source, function(value, key) {
target[key] = value;
});
}
...
XD.mth = XD.prototype = {
...
utils.each(source, function(value, key) {
target[key] = value;
});
}
...
XD.mth = XD.prototype = {
...
// the bind function on the wrapper
bind: function(eventType, handler) {
return XD.each(this, function(element) {
XD.bind(element, eventType, handler);
});
},
// the bind function on the wrapper
unbind: function(eventType, handler) {
return XD.each(this, function(element) {
XD.unbind(element, eventType, handler);
});
},
// the convenient function for registering the click event
click: function(handler) {
return this.bind('click', handler);
}
// other convenient functions for registering events
bind: function(eventType, handler) {
return XD.each(this, function(element) {
XD.bind(element, eventType, handler);
});
},
// the bind function on the wrapper
unbind: function(eventType, handler) {
return XD.each(this, function(element) {
XD.unbind(element, eventType, handler);
});
},
// the convenient function for registering the click event
click: function(handler) {
return this.bind('click', handler);
}
// other convenient functions for registering events
};
XD.mth.init.prototype = XD.mth;
global.XD = XD;
})(this);
XD.mth.init.prototype = XD.mth;
global.XD = XD;
})(this);
Event handling has many cross-browser differences. Here I only demonstrate several basic ideas of the encapsulation. The completed library can be downloaded here: gossip-0.3.js.
We can use the above library to rewrite the first example of Writing A DOM Library.
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<script type="text/javascript" src="js/gossip-0.3.js"></script>
<script type="text/javascript">
XD.bind(window, 'load', function() {
XD('#add').click(function() {
XD('<img>')
.attr('src', XD('#src').val())
.click(function(event) {
XD(this).remove();
})
.appendTo('#images');
});
});
</script>
</head>
<body>
<input id="src" type="text"><button id="add">Add</button>
<div id="images"></div>
</body>
</html>
We can rewrite the second example of Writing A DOM Library.
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<script type="text/javascript" src="js/gossip-0.3.js"></script>
<script type="text/javascript">
XD.bind(window, 'load', function() {
var container1XD = XD('#container1');
var container2XD = XD('#container2');
XD('#image').click(function() {
if(this.parentNode === container1XD[0]) {
container2XD.append(this);
}
else {
container1XD.append(this);
}
});
});
</script>
</head>
<body>
Container 1: <div id="container1">
<img id="image" src=
"https://openhome.cc/Gossip/images/caterpillar_small.jpg"/>
</div><br>
Container 2: <div id="container2"></div>
</body>
</html>