dean.edwards.name/weblog/2005/10/add-event/

addEvent() – My Solution

PPK’s addEvent() Recoding Contest produced a number of very similar solutions. The eventual winner was chosen because of its simplicity. All of the solutions relied on object detection to some degree.

My solution is very different.

Here it is:

function addEvent(element, type, handler) {
	// assign each event handler a unique ID
	if (!handler.$$guid) handler.$$guid = addEvent.guid++;
	// create a hash table of event types for the element
	if (!element.events) element.events = {};
	// create a hash table of event handlers for each element/event pair
	var handlers = element.events[type];
	if (!handlers) {
		handlers = element.events[type] = {};
		// store the existing event handler (if there is one)
		if (element["on" + type]) {
			handlers[0] = element["on" + type];
		}
	}
	// store the event handler in the hash table
	handlers[handler.$$guid] = handler;
	// assign a global event handler to do all the work
	element["on" + type] = handleEvent;
};
// a counter used to create unique IDs
addEvent.guid = 1;

function removeEvent(element, type, handler) {
	// delete the event handler from the hash table
	if (element.events && element.events[type]) {
		delete element.events[type][handler.$$guid];
	}
};

function handleEvent(event) {
	// grab the event object (IE uses a global event object)
	event = event || window.event;
	// get a reference to the hash table of event handlers
	var handlers = this.events[event.type];
	// execute each event handler
	for (var i in handlers) {
		this.$$handleEvent = handlers[i];
		this.$$handleEvent(event);
	}
};

You can download it here: /my/events.js

Update. I’ve posted a follow-up to this post with some improvements suggested in the comments below.

Comments (96)

Leave a comment

Pretty smart code, as always. Would it be possible to add a little more inline comments? (Or provide an alternative documented version that explains the rationale?) – Thanks!

  • Comment by: Niko Klaric
  • Posted:

all i can say is, ‘freaking awesome’
so, it’s 27 lines of code – and not 15
big whoop – it kicks booty

  • Comment by: Harley Jones
  • Posted:

Niko – I’ve now updated the posted code to include some inline comments. Good enough?

  • Comment by: -dean
  • Posted:

Excellent! (I knew you had it somewhere.)

  • Comment by: Niko Klaric
  • Posted:

Hmm. I think the line

 if (!handler.$$guid) handler.$$guid = addEvent.guid++;

should rather read

if (!handler.$$guid) handler.$$guid = ++addEvent.guid;

alternatively initialize addEvent.guid with 1, otherwise you’ll assign handler.$$guid = 0, and the test of handler.$$guid still results in false.

As I’ve already pointed out at the QuirksBlog we should make it good pythonesque practice to write such tests more explicit, i.e.

if (typeof(handler.$$guid) == "undefined")
  • Comment by: Niko Klaric
  • Posted:

Niko – Fixed. Thanks!

  • Comment by: -dean
  • Posted:

Neato. Just curious, is object detection a bad thing, or you just wanted to create something that works everywhere, regardless of whether somebody somewhere feeds you a crappy implementation of attachEvent/addEventListener?

Dimitri – I was trying to create a generic solution. This will work on browsers that don’t implement attachEvent/addEventListener.

  • Comment by: -dean
  • Posted:

Object.prototype.foo = function() { alert(‘oops’); }

furthermore I would also check for existance of handler.$$guid before doing the delete.

I like the idea of adding an ID to the function reference itself to simplify removeEvent, for the rest the idea looks very simular to my entry

  • Comment by: Tino Zijdel
  • Posted:

Tino – your solution seems very different to mine.

And why check for something before you delete it? If it doesn’t exist nothing will happen.

  • Comment by: -dean
  • Posted:

Tino – Apologies. After a second look I can see the similarity for IE event handling. Perhaps we should have declared you the winner of the contest?

  • Comment by: -dean
  • Posted:

Finally a sane script to come from all this addEvent stuff! A couple of problems the big one is the inability to return a result from the script including the inline event that’s stored – easily modifiable just return the and’d result of the inital handleEvents

Then there’s the non-truly isolated nature of it, if someone new starts editing a page on the script and adds a element.onmouseup=chicken; (or equivalent) then the handleEvents message is lost, but the error isn’t immediately obvious (or even noticeable) this can be enforced with coding conventions and documentation, so probably won’t be much of a concern, My very old http://groups.google.com/group/comp.lang.javascript/msg/58201030de38c517?ic=1 even proposed a silly solution to that problem…

and the script error if the IE user has a user script with document.expando=false in, but that’s probably silly no-one ever bothers protecting against that script error…

  • Comment by: Jim Ley
  • Posted:

Tino, the delete operator will return false both in MSIE and Mozilla if the property doesn’t exist.

  • Comment by: Niko Klaric
  • Posted:

Dean,

I wonder why you wrote

this.$$handleEvent = handlers[i];
this.$$handleEvent(event);

instead of

handlers[i](event);

Is the scope of “this” implicitly passed to the function call?

  • Comment by: Niko Klaric
  • Posted:

Niko – No. If I called handlers[i](event); the this keyword would point to the window object.

  • Comment by: -dean
  • Posted:

The problem is not in the delete operator itself, but accessing handler.$$guid when that property doesn’t exist raises a strict warning.

And Dean: you really should look into that prototype line I posted – for-in also iterates prototyped methods, and obviously these should not be executed in handleEvent.

And yes, I was referring to the handling for IE in my script; basically if I strip all the not-so-essential stuff what’s left is very simular. The storing of the function references in a hash map within the DOM space of the element (I actually use an array), and iterating through those using a helper function. (here’s an example of a stripped down version of my entry with some modifications I made later when I realised I had to ditch the for-in constructs: http://therealcrisp.xs4all.nl/upload/addEvent3.html )

The $$guid thing is different and like I said a good idea, but it leaves you with the problem with prototyped methods – you will need to check for those in your for-in and skip them, or iterate in a different way.

  • Comment by: Tino Zijdel
  • Posted:

Tino – extending Object.prototype is considered extremely bad practice. If a script does this then it is likely to break a lot more things than the event handling methods.

  • Comment by: -dean
  • Posted:

Dean: I agree with you that prototyping the Object object is bad practice, but I like to nitpick;) Speaking of nitpicking: also note that the enumeration order for for-in is undefined. Most browsers will enumerate the properties in the order the properties where assigned, but I know of at least one browser that does not (Opera). That for me was also a reason to use an array instead of an object/hashtable.

  • Comment by: Tino Zijdel
  • Posted:

Event firing in MSIE and Mozilla is not in-order anyway.

  • Comment by: Niko Klaric
  • Posted:

Event firing in IE seems to be LIFO when using attachEvent, in other browsers it seems to be FIFO using addEventListener. But I looked it up and indeed the specification explicitly does not specify the order of handling events so it should be considered bad practice to rely on that.

  • Comment by: Tino Zijdel
  • Posted:

I almost started to accept that this is probably the best way to handle things when I noticed one more shortcoming:

addEvent(obj, 'click', function() { alert('foo'); });
removeEvent(obj, 'click', function() { alert('foo'); });

this is possible using attachEvent or addEventListener, but fails here. It also failed in my script, but I updated it to accomodate this: http://therealcrisp.xs4all.nl/upload/addEvent3.html

Also I feel Jim Ley has a point about returnvalues, someting I also don’t take into account and will need to look into.

  • Comment by: Tino Zijdel
  • Posted:

Tino – this is correct behavior. Functions in JavaScript are unique objects. Just because they do the same thing does not mean that they are not different. If your code said the following:

function click() {
    alert('foo');
};
addEvent(obj, 'click', click);
removeEvent(obj, 'click', click);

then we would have a problem.;-)

Try it using the standard methods and you will see what I mean.

  • Comment by: -dean
  • Posted:

Tino/Jim – you are right. The handleEvent function should and the return values and return the composite result.

  • Comment by: -dean
  • Posted:

Dean: I guess you’re right; my testcase must’ve been faulty. It implies that removing anonymous functions as eventhandlers is just not possible, but that can be accepted (if you want to remove it at some point – store it and use a reference).

  • Comment by: Tino Zijdel
  • Posted:

I like your code a lot Dean, I’ve taken a similar approach and emulated event propagation, but you seem to be emulating for all browsers.

The code is beautiful, but its just not as fast or as scaleable as it could be if you did an object detect and used addEventListener where available.

Since everybody else is asking, “What if a developer does something stupid,” here’s my question:

function click() {
    alert('foo');
};
addEvent(obj, 'click', click);
addEvent(obj, 'click', click);
removeEvent(obj, 'click', click);

Are you checking to see if the same handler has been added? Which handler gets removed? How does IE or W3C address this?

  • Comment by: Harley Jones
  • Posted:

Harley: the second addEvent will be ignored – in fact in this script the click function will already have an guid that is registered for this event on this object. The W3C spec for the DOM level 2 event model is very clear on this:

http://www.w3.org/TR/DOM-Level-2-Events/events.html:
“If multiple identical EventListeners are registered on the same EventTarget with the same parameters the duplicate instances are discarded. They do not cause the EventListener to be called twice and since they are discarded they do not need to be removed with the removeEventListener method.”

And because the second addEvent is ignored the removeEvent will remove the first eventlistener after which no more events are attached to the object.

  • Comment by: Tino Zijdel
  • Posted:

Ah – I see, Tino. You are correct. But I also noticed two bugs:

addEvent(obj, 'click', click);
removeEvent(obj, 'click', click);
addEvent(obj, 'click', click);
addEvent(obj1, 'click', click);
addEvent(obj2, 'click', click);

Neither of these situations will work.
The first one is easy enough to fix (delete handler.$$guid;), but the second requires that the handler function contain a hashtable of elements and guids (or some such).

  • Comment by: Harley Jones
  • Posted:

Harley: I don’t know how you tested that, but both those situations work just fine here…

The $$guid is just created to uniquely identify a function that has been used as a handler. These id’s are stored in a seperate hashtable for each object and each eventtype as a key to the function reference. The helper function loops through the hastable of a particular object and a particular eventtype and calls each function in the scope of the object. To remove a handler all we need to do is remove the entry identified by the id in that particular hasmap. It doesn’t matter if that same id is used in another hasmap (eg for another object and/or another eventtype). There is no need to remove the id from the function itself – in fact that would break the script.

  • Comment by: Tino Zijdel
  • Posted:

Regarding memory leaks and circular references (which I think could still occur with this script as well as the winner of the contest), perhaps you could prevent the leak by removing the event on window unload, by adding the following:

addEvent(window, "unload", function(){removeEvent(obj,type,fn)});

Just thought it would be logical to do that after adding the event – and rather than add it in you main script, have it as part of the addEvent function.

On second thoughts, that looks like it would cause an issue, so perhaps this would be better:

var unload = function()
{
	removeEvent(obj,type,fn);
}
if(fn != unload)
{
	addEvent(window, "unload", unload);
}

Sam: the only way I can think of that this script will leak memory is when you attach a function that contains a closure to a DOM object. That can only be an anonymous function, and anonymous functions cannot be detached. Your suggestion in #30 will actually only create a problem since it contains exactly such closure, and you do not detach the unload function itself (which is also impossible because it is an anonymous function). Your suggestion in #31 cannot work because obj, type and fn are undefined at the time this function is triggered.

  • Comment by: Tino Zijdel
  • Posted:

Tino: I stand corrected. I now stand by my original statement: ‘freaking awesome.’

  • Comment by: Harley Jones
  • Posted:

Can the addEvent function automatically add something that removes the event from the object it when the window unloads (which is what I was trying to do with the script)?

I’m no JavaScript expert (as I would think you should not have to worry about memory leaks), but I thought that there would be a simple solution without having to write your own garbage collector.

How about:

var unload = function()
{
    removeEvent(this.obj,this.type,this.fn);
}
unload.obj = obj;
unload.type = type;
unload.fn = fn;

Sam, I’m pretty sure that this script does not leak memory. What makes you think that it does?

  • Comment by: -dean
  • Posted:

Dean: I have made some small changes and summarized some possible points and suggestions: http://therealcrisp.xs4all.nl/upload/addEvent_dean.html I’d appreciate it if you would have a look at it and share your opinion:)

  • Comment by: Tino Zijdel
  • Posted:

One improvement i added for my own page, in the handleEvent function:

var returnval = true;
for (var i in handlers) {
	this.$$handleEvent = handlers[i];
	returnval = returnval && this.$$handleEvent(event);
}
return returnval;

So that return false; can be used to stop a submit button from submitting.

Perhaps it is my code that is causing the leak (but it is only minor).

What I have found is that “return false” does not work with the addEvent scripts I have tried, yet when I do link.onclick = function() {… it does. So addEvent actually seems to mean you have to write more code, i.e..

var fn = function(e) { 
	this.className = "active";
	doSomething(somevar);
	e = e || window.event;
	if(e.preventDefault)
	{
		e.preventDefault();
	}
	else
	{
		e.returnValue = false;
	}
};
addEvent(link,"click",myfn);

vs

link.onclick = function()
{
	this.className = "active";
	doSomething(somevar);
	return false;
}

My ideal addEvent would be one where you can use it, but perhaps that is not possible. So at the moment I don’t see what benefit addEvent offers over foo.onevent = function() {…

Last bit should have been:

link.onclick = function() { alert('foo') };
var oldclick = link.onclick;
link.onclick = function()
{
    oldclick();
    this.className = "active";
    doSomething(somevar);
    return false;
}

Sam – I intend to issue an update to this function which will provide cross-browser support for preventDefault and stopPropagation. Stay tuned. I will also include a way to return a value from the handleEvent function. I originally wrote it like this but removed support in order to simplify the code. The advantage of addEvent() is that it allows you to add more than one function as an event handler. This is very important for large projects and web applications.

Tino – looking good! My final version will include a lot of the changes you suggest. I’ll also credit you as co-author.

  • Comment by: -dean
  • Posted:

Leszek – that is not quite right. An event handler must explicitly return false for the event to be cancelled. The default return value is true. Stay tuned for an update to my function to cater for this.

  • Comment by: -dean
  • Posted:

Looking forward to the next version. Pity you have to write so much code just to get it working cross browser (I guess if it weren’t for IE we wouldn’t have the issues we have – hope IE 7 supports the W3C event model in the future).

I don’t really consider this ‘so much code’, and if we can greatly enhance this function (e.g. by adding proper event cancellation support) it’d be worth the extra 10-or-so lines. The shortest possible code shouldn’t be the first priority; readability, possibilities to improve upon the code and preventing breakage in some odd situations (eg when someone does prototype a method on the Object object) are imho far more important than bytesize. Offcourse performance does matter, but smaller size doesn’t necessarily mean it’s faster;)

Otoh for presenting some idea or concept it is quite normal to minimize your example to the bare essentials.

From what I have read about IE7 it won’t support the W3C event model, so there will still be a need for a script such as this when IE7 comes out (and otherwise that need would probably still be there for years to come since unfortunately older version browsers tend to die out rather slowly).

  • Comment by: Tino Zijdel
  • Posted:

Sam – from what I can see it is you that is writing lots of code. Why not wait until see you see what I publish before making your remarks?

  • Comment by: -dean
  • Posted:

Dean, this looks almost similar (!?) to my entry — recoding contest entry #21. The thing I’m not happy with (in my submitted entry) is the hid thing: I should make it a property of addEvent to keep recomputing it each time addEvent is invoked. Also I used Array.splice to remove handlers ’cause using delete would most often make IE5 crash (!?) on my Windows 98 setup.

Dean – your probably right. I think you know a lot more than me (I certainly couldn’t write the IE7 script).

Sam – now I feel guilty for being hard on you.;-)

  • Comment by: -dean
  • Posted:

Your code seems to work fine. No leaks. Most are created unintentionally (more often by those less skilled in the art of javascripting) and hard to track down/fix.

It looks like execution order is preserved as well. Using addEvent from the code contest I get the alerts ‘two’, ‘three’, ‘four’, ‘one’. With yours it is in the correct order. So IMHO yours/Tino’s code is the better of the two (despite it not using the ‘correct’ W3C method)

addEvent(window,"load", function(){alert('one')});
addEvent(window,"load", function(){alert('two')});
addEvent(window,"load", function(){alert('three')});
addEvent(window,"load", function(){alert('four')});

Planning on setting up a /my/events/ page so people can link to and download the code (plus an example/demo of how it works)?

Sam: execution order is irrelevant since the spec explicitly doesn’t define it;)

  • Comment by: Tino Zijdel
  • Posted:

I know the following relies on Javascript 1.2, but you could avoid assigning the function to the element in the handleEvent method by using apply.

function handleEvent(event) {
    // grab the event object (IE uses a global event object)
    event = event || window.event;
    // get a reference to the hash table of event handlers
    var handlers = this.events[event.type];
    // execute each event handler
    for (var i in handlers) {
        handlers[i].apply(this,[event]);
    }
};

apply tells the function to refer to the first parameter as this within the function’s call scope. That way, you needn’t add members to the element that become cruft after the following one time use.

  • Comment by: Lucas Smith
  • Posted:

Lucas – IE5.0 does not support Function.apply.

  • Comment by: -dean
  • Posted:

Well that’s good to know!

If you’ll excuse me, I have some refactoring to do:)

Kudos on the elegant solution.

  • Comment by: Lucas Smith
  • Posted:

Standardista Table Sorting Standardista Table Sorting is a JavaScript module that lets you sort an HTML data table by any column. The module has the following advantages: It works. The codebase has been tested across a large number of web browsers, and in…

I’d like to point out that this code still easily leaks memory. To avoid this their should be no reference from the element to the handler. I took the liberty to adjust your code to this:

function addEvent(element, type, handler) {
    // assign each event handler a unique ID
    if (!handler.$$guid) handler.$$guid = addEvent.guid++;
	// assign each element a unique ID
	if (!element.$$guid) element.$$guid = addEvent.guid++;
    // create a hash table of event types for the element
	if (!addEvent.handlers[element.$$guid]) addEvent.handlers[element.$$guid] = {};
    // create a hash table of event handlers for each element/event pair
    var handlers = addEvent.handlers[element.$$guid][type];
    if (!handlers) {
        handlers = addEvent.handlers[element.$$guid][type] = {};
        // store the existing event handler (if there is one)
        if (element["on" + type]) {
            handlers[0] = element["on" + type];
        }
    }
    // store the event handler in the hash table
    handlers[handler.$$guid] = handler;
    // assign a global event handler to do all the work
    element["on" + type] = handleEvent;
};
// a counter used to create unique IDs
addEvent.guid = 1;
// a global hash table containing all handlers
addEvent.handlers = {};

function removeEvent(element, type, handler) {
	// check if the element has a guid
	if (!element.$$guid) return;
    // delete the event handler from the hash table
    if (addEvent.handlers[element.$$guid] && addEvent.handlers[element.$$guid][type]) {
        delete addEvent.handlers[element.$$guid][type][handler.$$guid];
    }
};
function handleEvent(event) {
    // grab the event object (IE uses a global event object)
    event = event || window.event;
    // get a reference to the hash table of event handlers
    var handlers = addEvent.handlers[this.$$guid][event.type];
    // execute each event handler
    for (var i in handlers) {
        this.$$handleEvent = handlers[i];
        this.$$handleEvent(event);
    }
};

As you can see I’ve added a unique ID to the element the event is attached to. Instead of referencing to the handler from the element, the handleEvent function can lookup the right handlers in the hash table using the unique ID in the element. This way no circular references are possible through the addEvent functions.

  • Comment by: Taco van den Broek
  • Posted:

@Taco – this solution does not leak memory. There are no circular references that I can see.

  • Comment by: -dean
  • Posted:

@Dean – The function itself isn’t leaking memory, but it does allow events to easily leak memory. Try the following code with your addEvent code and my altered code:

<html>
<head>
<script>
...addEvent code here...
function init()
{
	var elem = document.createElement('span');
	for (var i = 0; i < 5000; i++) {
		addEvent(elem, 'bogus_'+i, function(){elem['foo'] = 'bar';});
	}
}
</script>
</head>
<body onload='init()'>
</body>
</html>
  • Comment by: Taco van den Broek
  • Posted:

Perhaps a stupid question but I’m leaking memory mainly from objects. If i want to attach a event and pass arguments to the eventhandler + the object reference the only way i can do this is by using a closure. I’m not expert enough to see if the addEvent method offers a solution but hoping you can help me out. Consider the following example i found somewhere:

function greetingButton(greeting) {
	this.greeting = greeting;
	this.element = document.createElement('button');
	this.element.appendChild(document.createTextNode('Receive'));
	this.element.onclick = createMethodReference(this,'Greet');
}

greetingButton.prototype.greet = function(event) {
	alert(this.greeting);
};

function createMethodReference(object,methodName) {
	return function() {
		object[methodName].call(object,arguments);
	};
};

onload = function() {
	gb = new greetingButton('hello');
	document.body.appendChild(gb.element);
	gb.greet();
};

In many objectoriented situations you want to be able to pass arguments + object reference to an eventHandler. The only way I can find to do this is by closure. Anyone know how to do this without leaking memory?

  • Comment by: Taco Berentschot
  • Posted:

Hello, Question from a Javascript newbie : after reading Jeremy Keith’ book on DOM Scripting, I though the problem of event handling was handled correctly with a solution such as Simon Wilisson’s addLoadEvent … or is this a whole different thing ? Am I missing the point completely ? Please educate me ? Thank you

  • Comment by: Pierre Bourgeois
  • Posted:

[…] Eine andere Lösung, die ich ebenfalls ins Auge faßte. Dort taucht aber u.U. das Problem mit dem IE memory leak auf […]

[…] r not. This can cause serious problems and unexpected results. So imho it’s better to use Dean Edwards’ script. It provides the flexibility of addEventListener, and of course it works […]

[…] These functions allow you to add and remove javascript events with cross-browser compatibility. http://dean.edwards.name/weblog/2005/10/add-event/ // written by Dean Edwards, 2005 // http://dean.edwards.name/ function addEvent(element, type, h […]

Hi, maybe i’m guilty that i can not find the events name but if you could help i appreciate… I am in need of a change event by o tried to addevent with change as handler and it didn’t work…

  • Comment by: Luis
  • Posted:

Hi, first of thanks for this code. I found it through Dan Webb’s low pro library. Internet Explorer’s random order event firing messed my site up completely and your code saved the day. However im now seeing performance problems with it. In my site i have an event on document that fires onmousemove. With low pro moving the mouse around in internet explorer makes it hog 80% cpu on my 3.2 ghz p4. In firefox it stays around 10% which is still a lot.

Can this be fixed or is it just the unavoidable downside involved when replacing the builtin event processing?

  • Comment by: Tobias
  • Posted:

I think i fixed it, by replacing the loop in handleEvent() with this loop

for (var i in handlers) if (handlers[i](event) === false) returnValue = false;

the cpu burden dropped by at least 75%. I don’t fully understand how this code works and why it is necessary to assign the event being fired to a property on the element first. Are my changes breaking anything?

  • Comment by: Tobias
  • Posted:

[…] Dan Webb asks what are your JavaScript essentials? Those bits and pieces you can’t live without that get copy/pasted from project to project. His pragmatic list includes the $ function, getElementsByClassName, Dean’s event handling, the JS 1.6 array methods, and the DOMContentLoaded event. His full script that he guarantees he _won’t_ support is here. […]

[…] 接著是 W3C model 和 Microsoft model 的兩個重大差異,Microsoft model 不支援 event capturing,只有 bubbling(請參考 O3noBLOG addEventListener的第三個參數 ) 。另外就是 Microsoft model 把 event-handler function 當成一般 global function 來處理,也就是如果 用法四 attachEvent 來註冊事件時, event handler裡面的 this 指的是 window 而非發生事件的 object。(作者推薦 Dean Edward’s solution 可以fix) […]

[…] There are tons of problems and solutions with adding events (just look at the Advanced event registration models). Some time ago even PPK’s addEvent() Recoding Contest was over (but do not use the winner’s solution because of it’s inefficiency and memory leaks). […]

I’m new to javascript and I’m having a problem making a change. I’m using this program, but I need to perform a function before and after the onClick event because the event may take several seconds and I want to notify the user and perform some other commands. It seems like all the work is being done in handleEvent in the line:

this.$$handleEvent(event);

How can I run a function before and after this? I believe I need to put the function before and after and use the setTimeout function on the above line. However, I’m not sure how to use the setTimeout function when double dollars are used. Is there a way to have a function run before and a function run after the event occurs?

Thanks very much.

  • Comment by: Scott Hughes
  • Posted:

[…] // http://dean.edwards.name/weblog/2005/10/add-event // http://dean.edwards.name/my/events.js […]

[…] Dean Edwards写的addEvent/removeEvent库 […]

[…] Dean Edwards – addEvent() – My Solution que luego publicò este otro post addEvent() – Follow Up […]

[…] echarle un vistazo al addEvent de Dean Edwards que soluciona el problema mencionado con this en […]

Event firing in MSIE and Mozilla is not in-order anyway….

  • Comment by: Blog
  • Posted:

[…] (出自MSDN) events.js (出自Edwards) « 上一篇  所属分类: JS脚本 | RSS 2.0 | […]

Great function, allowed me to retain some of my hair. Thank you so much for providing this script to the community.

  • Comment by: Casey C.
  • Posted:

Hi all! i’m a javascript newbie and i’m getting crazy trying to understand the use of the ‘$$’ symbol used in this (great) script…

i googled it with no result and found nothing in the manuals i own…

could someone please explain me if the ‘$$’ is commonly used to reference vars and methods defined within the object?

i’m really getting a hard time here:)

anyway, thank you very much dean!

  • Comment by: Giancarlo Gerbaz
  • Posted:

[…] which case addEventListener and attachEvent would be completely unnecessary, such is the case with Dean Edwards’ solution. Ultimately, this method combined with an unobtrusive implementation will almost certainly provide […]

[…] (出自MSDN) events.js […]

the $$ meaning nothing. Simply they are characters that we can add to a variable’s names. They are acccepted!

var obj = {};
obj.$$fun = function() { alert("$$")};
obj.$$fun();
  • Comment by: joshua
  • Posted:

[…] Edwards – addEvent() – My Solution que luego publicò este otro post addEvent() – Follow […]

[…] onload handlers to a web page. You might be familiar with the original addevent script, and its numerous […]

[…] // http://dean.edwards.name/weblog/2005/10/add-event/ […]

[…] Some more efficient ways for CrossBrowser Event Handling: http://www.javascriptrules.com/2009/07/22/cross-browser-event-listener-with-design-patterns/ http://dean.edwards.name/weblog/2005/10/add-event/ […]

[…] […]

  • Pingback by: Anonymous
  • Posted:

Does the “removeEvent” force all handlers to be declared named-function? I can’t use anounymous function anymore.

  • Comment by: Steven
  • Posted:

[…] 기능만을 단독으로 갖고 있는 해결책들도 다수 존재한다. 하나 권한다면 Dean Edwards의 addEvent를 권하고 싶은데, jQuery 자바스크립트 라이브러리에서 이벤트를 다루는 […]

[…] Dean Edwards: addEvent() – My SolutionOct 20, 2005 … PPK’s addEvent() Recoding Contest produced a number of very similar …. And Dean: you really should look into that prototype line I posted … […]

[…] […]

[…] […]

[…] […]

[…] […]

[…] dollar sign in PHP (variable variables). Dean Edwards uses the double dollar sign in his famous addEvent() JavaScript function. Here is an except containing the use of the double dollar […]

[…] 说起jQuery的事件,不得不提一下Dean Edwards大神 addEvent库,很多流行的类库的基本思想从他那儿借来的 […]

[…] 绑定事件好累,封个类库(edwards的events.js): […]

[…] 绑定事件好累,封个类库(edwards的events.js): […]

[…]  17.Dean Edwards: http://dean.edwards.name/weblog/2005/10/add-event/  β.移动开发:  1.UC技术博客:http://tech.uc.cn/ […]

Comments are closed.