0

A couple of weeks ago I was working on my project and wrote some code to make a table row clickable (been there, done that). This code had been used before without a problem. A day was wasted trying to get the code to work (even though I had done it multiple times before) - some of the things I tried to get it working were a - change id to class on everything, b - move code from bottom of script section to top, c - rename variables, d - add 'var' in front of variables, subtract var from in front of variables, e - change all single quotes to double quotes, change all double quotes to single quotes, f - change the name of the table, g - try to click the table instead of the row, h - put the table in a div, take the table out of a div, etc etc etc.

Nothing was successful, so as a last resort, late at night, I switched the .click to .on(click - and surprise surprise - everything worked fine.

The same thing happened yesterday, but instead of doing a - h , I jumped right to changing the .click to on(click.

Here are the two code snippets:

$("#mdtable tr").click(function() { 
    var localmdid = $(this).find("#mdid").html();
    alert("mdid =" + localmdid);
});

$(document).on('click', '#mdtable tr', function(e) {
    var localmdid = $(this).find("#mdid").html();
    alert("mdid =" + localmdid);
           });

The upper one NEVER works, the lower one ALWAYS works (I comment them in and out).

Here is a code snippet from another page that works just fine:

$("#patienttable tr").click(function() {
       var passthis = $(this).find("#localid").html();
       $.post("php/setsessionvariable.php",
              {sessionval: passthis},
              function(e) {window.location.href = "root.php"}
              );
});

I've read the jQuery documentation and it says that the .click function is somehow directly related to the .on(click, and therefore to me, if one works, then other should work.

Being a noob, I would like to become a better programmer, and even though my code works with .on(click, I'd like to know why my .clicks don't work (an intellectual exercise).

So my questions are:

  1. Are .click and .on(click really related?

  2. Is there something obvious I'm missing in the click snippet that makes it non-functional?

  3. Is there a different way to this about this issue?

Again, I thank you in advance

TimSPQR
  • 2,964
  • 3
  • 20
  • 29
  • 2
    http://api.jquery.com/on/ Read the bit about direct and delegated events. – James Montagne Jul 16 '13 at 13:57
  • Are the elements you're trying to bind the click event to added dynamically to the page? – j08691 Jul 16 '13 at 13:57
  • 2
    @j08691 i would say yes because the first one doesn't work – A. Wolff Jul 16 '13 at 13:58
  • Useful information: http://stackoverflow.com/questions/8018760/jquery-difference-between-click-and-onclick and http://stackoverflow.com/questions/9122078/difference-between-onclick-vs-click – Pieter Jul 16 '13 at 13:58
  • 1
    `$('foo').click(...)` is *equivalent* to `$('foo').on('click, ...)`. But you are using a different selector/element to bind the handler to (`#mdtable tr` in the first case, `document` in the second), so they are not equivalent in your case. You are making using of *event delegation* which is explained well in the jQuery learning center: http://learn.jquery.com/events/event-delegation/. – Felix Kling Jul 16 '13 at 13:58
  • 1
    @roasted - I'm pretty sure I know the answer, I just want confirmation from the OP. – j08691 Jul 16 '13 at 13:58
  • `$(document).on('click', '#foo', ...)` is **not** the same as `$('#foo').click(...)`. That'd be `$('#foo').on('click', ...)` – millimoose Jul 16 '13 at 13:58
  • @j08691 i'm sure you know the answer :) – A. Wolff Jul 16 '13 at 13:59
  • if it is a dynamically loaded via ajax or js `click` event will not work `on` will work in all cases – Kathiravan Jul 16 '13 at 14:00
  • 1
    Aside: delegating events from `$(document)` isn't very good practice for performance if there's a lot of them or if the document tree is any deep. Essentially it means that jQuery has to consider all such event handlers for every event fired. Just delegate from the closest non-dynamic ancestor. – millimoose Jul 16 '13 at 14:00
  • 2
    @Kathiravan That is patently wrong. The distinction isn't between `click()` or `on()`, it's whether or not the event is *delegated*. `on()` allows you to create direct and delegated events, where `click()` only allows the former. – millimoose Jul 16 '13 at 14:01
  • Oh, my goodness! The Eureka! lightbulb has gone off! In retrospect, ALL of the .click events that work are on tables that are php generated server-side while the DOM is being constructed. All of the problems I've had have been with tables generated by javascript AFTER the initial page has loaded. I cannot thank you ALL enough for your excellent comments, and providing me with the "lightbulb"! – TimSPQR Jul 16 '13 at 14:15
  • I'm also going to spend some time on "delegation" and on the $(document) question. I've only used $(document). in the past, so I'll see if I can use $(#tablename). or other stuff. Again, I thank you all very much! – TimSPQR Jul 16 '13 at 14:16

1 Answers1

5

The .click will bind click event to elements that are present at that time in the DOM whereas the on() will delegate the event and will bind the click (event) which are dynamically added later on.

Delegated events

Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers, Reference.

Adil
  • 146,340
  • 25
  • 209
  • 204
  • 2
    More specifically, in the code supplied, `on` is binding the event to `document`. The events aren't added later. – James Montagne Jul 16 '13 at 13:59
  • Yes...that's my problem...as noted above, the stuff that is not working is loaded by a click and ajax call AFTER the DOM is loaded. Thanks VERY much! – TimSPQR Jul 16 '13 at 14:17