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 handler
s , corresponding wrappedhandler
s 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