Wednesday, 15 February 2012

javascript - Removing wrapped event handlers -



javascript - Removing wrapped event handlers -

i have function wraps function around one, attaches element.

function addcustomevent(element, eventname, handler, usecapture) { var wrappedhandler = function () { // here. handler.call(); }; element.addeventlistener(eventname, wrappedhandler, usecapture); }

this works great , want implement function:

removecustomevent(element, eventname, handler, usecapture)

so want this.

var clickhandler= function () { /* ... */ }; addcustomevent(someelement, "click", clickhandler, false); removecustomevent(someelement, "click", clickhandler, false);

there problem because don't have reference wrappedhandler in removecustomevent.

the way can think of maintain track of handlers , corresponding wrappedhandlers in dictionary can find wrappedhandler handler within function, , remove it.

but i'm not fond of approach because browser must have info handlers attached, creating new dictionary seems redundant , waste of memory.

is there better, , much cleaner way?

personally, i'd wrap addcustomevent , removecustomevent single module, , maintain object tracks bound handlers. consider "a waste of resources", really, impact of approach negligible. upsides are: have origin of module can expanded on, handle more complex event handlers (like simulating tab event mobile devices using touchstart , touchend events).

an alternative approach unbind event handler internally, depending on event object itself. then, you'll have re-write removecustomevent function trigger special event, lets bound handler know want remove event listener.

//in wrappedhandler: var wrappedhandler = function(e) { e = e || window.event; if (e.synthetic === true) { e.preventdefault(); e.stoppropagation(); element.removeeventlistener(eventname, wrappedhandler, usecapture);//<-- utilize closure vars homecoming e;//or homecoming false. } //do normal event handler.apply(this, [e]);//pass event object, , phone call handler in same context! }; var removecustomevent = function(event, node, capture) { var e, eclass, doc = node.ownerdocument || (node.nodetype === (document.document_node || 9) ? node : document); if (node.dispatchevent) { if (event === 'click' || event.indexof('mouse') >= 0) eclass = 'mouseevents'; else eclass = 'htmlevents'; e = doc.createevent(eclass); e.initevent(event, !(event === 'change'), true); //this trick: e.synthetic = true; node.dispatchevent(e, true); homecoming true; } if (node.fireevent) { e = doc.createeventobject(); e.synthetic = true; node.fireevent('on' + event, e); homecoming true; } event = 'on' + event; homecoming node[event](); };

here's version of code documented

i've set synthetic property on event object passed event handler. handler checks property, , if it's set true, unbind listener , return. doesn't require maintain dom references , handlers in object, is, think you'll agree, quite lot of work, too. feels quite hacky, if don't mind saying so...

compared to:

var bindermodule = (function() { var module = {}, eventmap = {}, addevent = function (elem, eventname, handler, capture) { var i, wrappedhandler; if (!eventmap.hasownproperty(eventname)) eventmap[eventname] = []; (i=0;i<eventmap[eventname].length;++i) {//look elem reference if (eventmap[eventname][i].node === elem) break; } if (i>= eventmap[eventname].length) { = eventmap[eventname].length;//set key eventmap[eventname].push({ node: elem, handlers: []//keep handlers here, in array multiple handlers }); } wrappedhandler = function(e) { //stuff homecoming handler.apply(this, [e || window.event]);//pass arguments! }; eventmap[eventname][i].handlers.push(wrappedhandler); homecoming elem.addeventlistener(eventname, wrappedhandler, capture); }, removeevent(elem, eventname, capture) { var i, temp; if (!eventmap.hasownproperty(eventname)) return;//no handlers bound, end here (i=0;i<eventmap[eventname].length;++i) if (eventmap[eventname][i].node === elem) break; if (i < eventmap[eventname].length) {//found element, remove listeners! //get handlers temp = eventmap[eventname][i].handlers; //remove element + handlers eventmap: eventmap[evetnname][i] = undefined; (i=0;i<temp.length;++i) elem.removeeventlistener(eventname, temp[i], capture); } }; module.addcustomevent = addevent; module.removecustomevent = removeevent; //or, perhaps better: object.defineproperty(module, 'addcustomevent', {value: addevent});//read-only object.defineproperty(module, 'removecustomevent', {value: removeevent}); homecoming module; }());

note basic setup maintain track of event handlers bound particular dom nodes, , how mangage them. code not finished , not tested. contains typo's, syntax errors , consistency issues. should more plenty started.

javascript

No comments:

Post a Comment