Dormilich
New member
Hallo,
ich habe mir einen Event Listener zusammengebaut, der auch die Event-capture-Phase im IE bewerkstelligen soll, nur fehlt mir leider ein IE (bzw. mehrere), um den Code richtig zu testen.
Danke schon mal im Voraus.
Testseite
Code:
ich habe mir einen Event Listener zusammengebaut, der auch die Event-capture-Phase im IE bewerkstelligen soll, nur fehlt mir leider ein IE (bzw. mehrere), um den Code richtig zu testen.
Danke schon mal im Voraus.
Testseite
Code:
PHP:
// based upon an addEvent() implementation from Tino Zijdel
// http://therealcrisp.xs4all.nl/upload/addEvent2.html
var Events = (function ()
{
/**
* workaround for Array.lastIndexOf()
*
* @param (mixed) val value to search for
* @param (Array) arr array to search in
* @return (int) array index of val or -1
*/
function array_search(val, arr)
{
var i = arr.length;
while (i--) {
if (arr[i] && arr[i] === val) {
break;
}
}
return i;
}
/**
* build the array of elements to loop through in capturing phase
*
* @param (Node) elem element from which to search up
* @return (Array) list of elements starting with input
* element until top node
*/
function getParents(elem)
{
var p = [elem];
while (elem.parentNode) {
elem = elem.parentNode;
p.push(elem);
}
return p;
}
/**
* workaround for Function.call()
*
* @param (Function) Fn function reference
* @param (Node) node on which the handler is to execute
* @param (Event) current event object
* @return (mixed) return value of the function Fn
*/
function callHandler(Fn, obj, evt)
{
var retValue = true;
if (Function.call) {
retValue = Fn.call(obj, evt);
}
else {
try {
obj.__fn = Fn;
retValue = obj.__fn(evt);
delete obj.__fn;
}
catch (f) {
obj.__fn = null;
}
}
return retValue;
}
/**
* function that executes events according to DOM
*
* @param (mixed) e Event object, if passed
* @return (bool) combined return value of bubble handlers
*/
function IEHandler(e)
{
// if no Event object is passed (IE)
e = e || window.event;
// add .stopPropagation()
if (!e.stopPropagation) {
e.stopPropagation = function ()
{
this.cancelEvent = true;
this.cancelBubble = true;
}
}
// get Event Target
var base = e.target || e.srcElement,
// get Event Type
evTypeRef = '__' + e.type,
// return values for bubbling handlers
retValue = true,
i, j, l, elem, chain, evPhase;
// execute only once
if (base == this) {
// get elements for capturing
chain = getParents(base);
for (i = chain.length; i--;) {
elem = chain[i];
// if there are functions attached
// to execute in capturing context
if (elem[evTypeRef] && elem[evTypeRef].capture) {
evPhase = elem[evTypeRef].capture;
// execute each function
for (j = 0, l = evPhase.length; j < l; j++) {
if (evPhase[j]) {
// exit on stopPropagation()
if (e.cancelEvent === true) {
return null;
}
// there can be no value returned due to the
// executing element of this loop is the Event
// target and not the element the handler
// executes on.
callHandler(evPhase[j], elem, e);
}
}
}
}
}
// if there are functions attached to execute in bubbling context
if (this[evTypeRef] && this[evTypeRef].bubble) {
evPhase = this[evTypeRef].bubble;
for (j = 0, l = evPhase.length; j < l; j++) {
if (evPhase[j]) {
// this time we're in the correct element context so we can
// safely return something
retValue = callHandler(evPhase[j], this, e) && retValue;
}
}
}
return retValue;
}
/**
* return interface
*
* @public add
* @public remove
*/
return {
add : function (obj, evType, fn, useCapture)
{
if (fn != Function) {
throw new TypeError("Function expected!");
}
// make useCapture a Boolean
useCapture = !!useCapture;
// W3C
if (obj.addEventListener) {
obj.addEventListener(evType, fn, useCapture);
}
else {
var evTypeRef = '__' + evType,
phase = useCapture ? "capture" : "bubble";
// create ".__event" property
if (!obj[evTypeRef]) {
obj[evTypeRef] = {};
}
// search in ".__event.bubble"/".__event.capture"
// if function is already registered
if (obj[evTypeRef][phase]) {
if (array_search(fn, obj[evTypeRef][phase]) > -1) {
return;
}
}
// create ".__event.bubble"/".__event.capture" property
else {
obj[evTypeRef][phase] = [];
if (!useCapture && obj['on' + evType] && obj['on' + evType] != IEHandler) {
// add any previous function assigned to .onevent
obj[evTypeRef][phase][0] = obj['on' + evType];
}
}
// add function to stack
obj[evTypeRef][phase].push(fn);
// set "global" handler
obj['on' + evType] = IEHandler;
}
},
remove : function (obj, evType, fn, useCapture)
{
useCapture = !!useCapture;
if (obj.removeEventListener) {
obj.removeEventListener(evType, fn, useCapture);
}
else {
var evTypeRef = '__' + evType,
phase = useCapture ? "capture" : "bubble",
evPhase, i;
if (obj[evTypeRef] && obj[evTypeRef][phase]) {
evPhase = obj[evTypeRef][phase];
i = array_search(fn, evPhase);
if (i > -1) {
try {
delete evPhase[i];
}
catch (e) {
evPhase[i] = null;
}
}
}
}
}
}
})();
Zuletzt bearbeitet: