PDA

View Full Version : List of registered events



pman
05-20-2007, 03:53 PM
Hi there,

I have two questions to ask.

1. How do I check which events are registered with a specific element.
2. How do I check which event handler is registered with a specific event on an element.

Basically, what I'm trying to do is allow the user to add events on an element. This part I was able to do. But now, I would like to give them an option to be able to remove events. I know that I will have to use removeEventListener and detachEvent for this. But when the user tries to remove an event, I would like to check two things:

i) if that event is registered with this element

ii) if it is, then check if the provided function / event handler was registered with the given event

Please let me know if there's a better way to achieve this. Thanks so much in advance.
__________________

With Regards
Pman
http://www.pmansLab.com

Trinithis
05-21-2007, 05:26 AM
(**RE-EDITED for substrings, to rename one function, and to give the optional useCapture bool for add/removeEventListeners**)

If the event is not registered with the element and you use either removeEventListener or detachEvent then nothing happens and you do not get an error. So you don't even need to check if the event and/or event function that is associated with the element is there to begin with. To sum things up, use the removeEventListener and the detachEvent as they are without any issues. If you want to see if the event and/or event function exists within the element without removing it, that is a different question and requires a little work...




//specifying the event type as "onevent" or "event" does not matter. The code accepts either.

function registerEvent(el, eventType, eventFunction, bool) {
if(eventType.indexOf("on")==0) eventType = eventType.substring(2,eventType.length);
if(bool==undefined) bool = false;
if(window.addEventListener) el.addEventListener(eventType, eventFunction, bool);
else el.attachEvent("on"+eventType, eventFunction);
if(!el.eventHolder) el.eventHolder = [];
el.eventHolder[el.eventHolder.length] = new Array(eventType, String(eventFunction));
}

function hasEvent(el, eventType, eventFunction) {
if(eventType.indexOf("on")==0) eventType = eventType.substring(2,eventType.length);
if(!el.eventHolder) return false;
for(var i=0; i<el.eventHolder.length; i++) {
if(el.eventHolder[i][0]==eventType && el.eventHolder[i][1]==String(eventFunction)) return true;
}
return false;
}

function unregisterEvent(el, eventType, eventFunction, bool) {
if(eventType.indexOf("on")==0) eventType = eventType.substring(2,eventType.length);
if(bool==undefined) bool = false;
if(!hasEvent(el, eventType, eventFunction)) return;
if(window.addEventListener) el.removeEventListener(eventType, eventFunction, bool);
else el.detachEvent("on"+eventType, eventFunction);
for(var i=0; i<el.eventHolder.length; i++) {
if(el.eventHolder[i][0]==eventType && el.eventHolder[i][1]==String(eventFunction)) {
el.eventHolder.splice(i, 1);
break;
}
}
}


Example:


var el = document.getElementById("myElement")
alert(hasEvent(el, "click", _1337n355)); //false
registerEvent(el, "click", _1337n355);
alert(hasEvent(el, "click", _1337n355)); //true
alert(hasEvent(el, "click", _notLeetness)); //false
alert(hasEvent(el, "mousedown", _1337n355)); //false
unregisterEvent(el, "click", _1337n355);
alert(hasEvent(el, "click", _1337n355)); //false

function _1337n355() {alert(1337+"!"+1+"11");}
function _notLeetness() {alert("!1337");}

Bob90
05-21-2007, 07:54 AM
LOL, we are so 'leet'.

Just a quick question. How does the script handle mousedowns as you split the string by 'n' which to me seems very !1337 :D

maybe substrings would be better?

Bob90
05-21-2007, 08:00 AM
//specifying the event type as "onevent" or "event" now does not matter (RG). The code accepts either.

function registerEvent(el, eventType, eventFunction) {
if(eventType.indexOf("on")==0) eventType = eventType.substring(2,eventType.length);
if(window.addEventListener) el.addEventListener(eventType, eventFunction, false);
else el.attachEvent("on"+eventType, eventFunction);
if(!el.eventHolder) el.eventHolder = [];
el.eventHolder[el.eventHolder.length] = new Array(eventType, String(eventFunction));
}

function isEventRegistered(el, eventType, eventFunction) {
if(eventType.indexOf("on")==0) eventType = eventType.substring(2,eventType.length);
if(!el.eventHolder) return false;
for(var i=0; i<el.eventHolder.length; i++) {
if(el.eventHolder[i][0]==eventType && el.eventHolder[i][1]==String(eventFunction)) return true;
}
return false;
}

function unregisterEvent(el, eventType, eventFunction) {
if(eventType.indexOf("on")==0) eventType = eventType.substring(2,eventType.length);
if(!isEventRegistered(el, eventType, eventFunction)) return;
if(window.addEventListener) el.removeEventListener(eventType, eventFunction, false);
else el.detachEvent("on"+eventType, eventFunction);
for(var i=0; i<el.eventHolder.length; i++) {
if(el.eventHolder[i][0]==eventType && el.eventHolder[i][1]==String(eventFunction)) {
el.eventHolder.splice(i, 1);
break;
}
}
}

pman
05-21-2007, 03:53 PM
Just so I understood it properly, the eventHolder is an array that is storing the event type and the function. Am I right?

Also, I haven't had a chance to try this yet. But, will the given solution work with anonymous functions?

This is probably a novice question, but I'm not sure about it. So, here it goes. html elements doesn't have any property called eventHolder. So, when I do
element.eventHolder = [] this will just create that property for that element? If so, it's really interesting, cause I didn't know that we could do something like this.

Again, thank you so much for your reply and time.

Twey
05-21-2007, 04:06 PM
Trinithis, those functions don't apply to all Javascript objects, so they shouldn't be on Object.prototype. Also, in IE DOM nodes aren't considered to be Javascript objects, so your script won't work.

Trinithis
05-21-2007, 04:15 PM
@ Twey: Hmm, okay, I'll change it back. Is there a way to do it though?

@ pman: You are correct in that it creates a new property for that element even if it did not have it in the first place.

As for anonymous functions, I can get it to add and check to see if it has one (if it has one, it has to be typed exactly the same, or I could add regexes to it to remove whitespace), but I can't get it to remove it. The solution? Don't use anyonymous event functions. If you want to use them, try making a dummy variable array that holds the would-be anyonymous event functions. That way you can reference them.

Twey
05-21-2007, 04:48 PM
@ Twey: Hmm, okay, I'll change it back. Is there a way to do it though?Not the way you're trying to do it, no. In Firefox, Konqueror, Opera, and a lot of other browsers, you can extend HTMLElement to add a property to all DOM nodes, but not in IE.

Trinithis
05-21-2007, 06:00 PM
I redid some of the code so all the functions work properly with anyonymous functions. You do not have to make dummy arrays for the functions now.

All that is required is that the you type the specific anonymous function you want to add/test/remove from the element. Firefox allows whitespace and semi-colon use to be lax when identifying the function, but Internet Explorer thinks that "function(){alert(8)}" to be different from "function ( ){alert(8); }". To be safe, type them the same. If you need it, I can make IE accept whitespace differences, but I won't bother making it accept semi-colon differences.



function registerEvent(el, eventType, eventFunction, bool) {
if(eventType.indexOf("on")==0) eventType = eventType.substring(2,eventType.length);
if(bool==undefined) bool = false;
if(!el.eventHolder) el.eventHolder = [];
el.eventHolder[el.eventHolder.length] = new Array(eventType, eventFunction);
if(window.addEventListener) el.addEventListener(eventType, el.eventHolder[el.eventHolder.length-1][1], bool);
else el.attachEvent("on"+eventType, el.eventHolder[el.eventHolder.length-1][1]);
}

function hasEvent(el, eventType, eventFunction) {
if(eventType.indexOf("on")==0) eventType = eventType.substring(2,eventType.length);
if(!el.eventHolder) return false;
for(var i=0; i<el.eventHolder.length; i++) {
if(el.eventHolder[i][0]==eventType && String(el.eventHolder[i][1])==String(eventFunction)) return true;
}
return false;
}

function unregisterEvent(el, eventType, eventFunction, bool) {
if(eventType.indexOf("on")==0) eventType = eventType.substring(2,eventType.length);
if(bool==undefined) bool = false;
if(!hasEvent(el, eventType, eventFunction)) return;
for(var i=0; i<el.eventHolder.length; i++) {
if(el.eventHolder[i][0]==eventType && String(el.eventHolder[i][1])==String(eventFunction)) {
break;
}
}
if(window.addEventListener) el.removeEventListener(eventType, el.eventHolder[i][1], bool);
else el.detachEvent("on"+eventType, el.eventHolder[i][1]);
el.eventHolder.splice(i, 1);
}


Example:


var el = document.getElementById("myElement");

alert(hasEvent(el, "click", function(){alert("Hello from anonymous!")})); //false
registerEvent(el, "click", function(){alert("Hello from anonymous!")});
registerEvent(el, "click", function(){alert("Hello from anonymous 2!")});
alert(hasEvent(el, "click", function(){alert("Hello from anonymous!")})); //true
unregisterEvent(el, "click", function(){alert("Hello from anonymous!")})
alert(hasEvent(el, "click", function(){alert("Hello from anonymous!")})); //false

Twey
05-21-2007, 07:25 PM
Ack no! You don't want to be trying to see if two different functions do the same thing... just match references!

pman
05-21-2007, 10:39 PM
Ack no! You don't want to be trying to see if two different functions do the same thing... just match references!

Hi Twey,

Could you explain a little. Not sure what you meant by that. Thanks

Trinithis
05-21-2007, 11:13 PM
I think he's trying to say that String(el.eventHolder[i][1])==String(eventFunction) might be impractical to el.eventHolder[i][1]==eventFunction? If so, I should only resort to the former method while an anonymous function is passed as an argument and resort to the latter for other functions. But then again, I'm just guessing.