3

In my answer to the following SO question: What does event binding mean?, I made a passing remark that the use of inline-JavaScript/Early-Binding to bind JavaScript Events was 'often misguided'

For example:

<input id="MyButton" type="button" value="clickme" onlick="Somefunction()" />

I was arguing for the 'late-binding' approach where there is no JavaScript referenced in the markup, which I understand to be established best-practice. However, the commenters asserted that there were occasions that necessitated its use, and I wondered what these might be.

Without engaging in a discussion on the relative merits of either, can anyone think of any circumstances that dictate that you use the (e.g.) onclick attribute over a late-binding approach.

4
  • Google uses them, and so do people fiddling around. I use them when I'm making bookmarklets Commented Jun 13, 2011 at 13:07
  • @qwertymk: Care to expand on the bookmarklets example in an answer? I have a funny feeling it'll attract an up-vote ;-) Commented Jun 13, 2011 at 13:20
  • When you control the HTML there is no valid use case for inline binding. Commented Jun 13, 2011 at 13:50
  • Raynos - I think you have that backwards. Why depend on client-side scripting to add listeners that can be added at the server more efficiently (particularly using cached or static pages), especially when you control the HTML? Also avoids onload/DOMReady issues with dynamic addition - listeners are available as soon as the element is. Commented Jun 14, 2011 at 6:48

3 Answers 3

2

commenters asserted that there were occasions that necessitated its use

I suppose I'm one of those commentors. What I actually said was that inline listeners "are a reasonable option in certain circumstances". I don't think there are any cases where it is "necessitated" (which I understand in this context to mean required).

Adding inline listeners is simply applying the same logic on the server to add listeners as would be applied on the client and has advantages in that:

  1. Markup can be created and cached or used as static pages, listeners aren't added by every client over and over again when pages are downloaded
  2. Issues related to delay between the element being available and the listener being added by DOMReady or onload functions or "bottom scripts" are completely removed
  3. The vagaries of various "cross browser" DOMReady functions with onload fallback are removed - there is no opportunity for such functions to fail to add listeners if they aren't used

Of course this doesn't mean that all listeners should be added inline and that dynamic addition of listeners is rubbish, I'm just point out that it is a viable method that solves certain issues and is a perfectly reasonable solution in many cases.

If you believe "early binding" of listeners is good, then make it as early as possible - put them inline. :-)

PS. I also think I said I didn't like the use of "binding" in this context as listeners aren't bound to elements in any real sense. They are simply functions that are called when an element receives a related event. The only type of binding is that the listener's this keyword may be set to reference the related element (which is consistent in all browsers for inline listeners but not necessarily for those added later).

Sign up to request clarification or add additional context in comments.

7 Comments

"1. Markup can be created and cached or used as static pages, listeners aren't added by every client over and over again when pages are downloaded" JavaScript files that attach listeners are cached. Listeners are added by every client over and over again. This happens when the browser parses the DOM and attaches the listeners for you.
"2. Issues related to delay between the element being available and the listener being added by DOMReady or onload functions or "bottom scripts" are completely removed" The delay should be small. Clients should not be encouraged to interact with the page before it has finished loading as this requires you to code significantly more defensively and guard against "partial loaded state bugs". If the delay is noticeable then your doing your loading wrong i.e. not enough caching / lazy loading.
"3 The vagaries of various "cross browser" DOMReady functions with onload fallback are removed - there is no opportunity for such functions to fail to add listeners if they aren't used" If a particular developer does not use a DOMReady utility library then they are shooting themself in the foot for no reason. domReady is just 0.5kb. There is no reason to not use it.
+1 for showing solid reasoning for using inline events though!
+1 From me as well. This sort of discussion is exactly why I like SO.
|
2

Reasons why onclick attributes are bad :

onclick="foo()"

  • Your passing in a string of code that get's evalled at runtime when the element is clicked. This is inefficient and uses the horrors of eval
  • Your forced to store the function foo in global scope thus polluting global scope with all your event handling logic.

1 Comment

The code is not "evalled at runtime", it is parsed as the page loads and is called by a handler (just like dynamically added listeners), in most cases it is a single function call. The "horrors of eval" are irrelevant (and much over stated). Talk of "polluting the global scope" with additional properties is scare mongering, the only issue is name collisons and they are easily avoided.
1

I think many developers will do this either due to ignorance or lack of knowledge (which is, of course, common) and the remaining developers will do it because it's simply more convenient to use HTML-JS attributes than late binding, if you know that certain objects and functions are always loaded on every page and they will simply 'be there'.

I think this is especially true when said HTML comes from an AJAX callback. Take an example where an AJAX request comes back with an HTML response and that HTML is inserted into the page. Now the naive developer would think along these lines:

  • I have no idea what elements are inside that response HTML so I don't know what late bindings I need to add.
  • Perhaps I need to add them all just in case! Or write some parsing script that detects elements and binds to the ones I find?
  • But what if I need to bind to something that doesn't already exist? Time to write some long inline JavaScript!

All of this can be eliminated by using a kind of omnipresent binding that applies to all current and future elements on the page. In jQuery, the equivalent is live(). Instead of writing:

$('.foo').click(function(){...});

You could write:

$('.foo').live('click', function(){...});

Now, all elements with class name 'foo' will execute the function when clicked, including elements that don't currently exist. Very useful for dynamic AJAX interfaces.

You may know that already, but I'm just pointing out that anything JS attributes can do, pure JS can do better, and I'd consider that best practise.

4 Comments

+1 Suberb answer. Yes, I did know, but there's nothing better than an assertion that your reality is as you perceieve :-)
.live is the devil. Use .delegate
@Raynos Nice find. I knew live() had a few issues but didn't know I could do the same thing at a lower level in the DOM. Good for performance, I guess.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.