Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Properly bind Javascript events

I am looking for the most proper and efficient way to bind Javascript events; particularly the onload event (I would like the event to occur after both the page AND all elements such as images are loaded). I know there are simple ways to do this in jQuery but I would like the more efficient raw Javascript method.

like image 621
Jackie Avatar asked Nov 25 '09 10:11

Jackie


People also ask

How do you bind an event in JavaScript?

jQuery bind() MethodUse the on() method instead. The bind() method attaches one or more event handlers for selected elements, and specifies a function to run when the event occurs.

How do you bind an event?

To bind to an event you use the Angular event binding syntax. This syntax consists of a target event name within parentheses to the left of an equal sign, and a quoted template statement to the right. Create the following example; the target event name is click and the template statement is onSave() .

What is JavaScript binding?

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.


2 Answers

There are two different ways to do it. Only one will work; which one depends on the browser. Here's a utility method that uses both:

function bindEvent(element, type, handler) {
   if(element.addEventListener) {
      element.addEventListener(type, handler, false);
   } else {
      element.attachEvent('on'+type, handler);
   }
}

In your case:

bindEvent(window, 'load', function() {
    // all elements such as images are loaded here
});
like image 99
David Hedlund Avatar answered Sep 21 '22 19:09

David Hedlund


I know you did only ask about how to bind events. But Ooooo boy the fun doesn't end there. There's a lot more to getting this right cross-browser than just the initial binding.

@d.'s answer will suffice just fine for the specific case of the load event of window you're looking for. But it may give novice readers of your code a false sense of "getting it right". Just because you bound the event doesn't mean you took care to normalize it. You may be better of just fixing window.onload:

window.onload = (function(onload) {
  return function(event) {
    onload && onload(event);

    // now do your thing here
  }
}(window.onload))

But for the general case of event binding @d.'s answer is so far from satisfying as to be frustrating. About the only thing it does right is use feature-detection as opposed to browser detection.

Not to go on too much of a rant here but JavaScript event binding is probably the #1 reason to go with a JavaScript library. I don't care which one it is, other people have fixed this problem over and over and over again. Here're the issues in a home-brewed implementation once inside your handler function:

  • How do I get a hold of the event object itself?
  • How do I prevent the default action of the event (eg clicking on a link but not navigating)
  • Why does this point to the window object all the time?
  • (Re mouse events) What are the x/y coords of the event?
  • Which mouse button triggered the event?
  • Was it a Ctrl-click or just a regular click?
  • What element was the event actually triggered on?
  • What element is the event going to? (ie relatedTarget, say for blur)
  • How do I cancel the bubbling of the event up through its parent DOM?
  • (Re event bubbling) what element is actually receiving the event now? (ie currentTarget)
  • Why can't I get the freaking char code from this keydown event?
  • Why is my page leaking memory when I add all these event handlers?? Argh!
  • Why can't I Unbind this anonymous function I bound earlier?

And the list goes on...

The only good reason to roll your own in these days is for learning. And that's fine. Still, read PPK's Intro to browser events. Look at the jQuery source. Look at the Prototype source. You won't regret it.

like image 39
Crescent Fresh Avatar answered Sep 24 '22 19:09

Crescent Fresh