0

Learning jQuery and I have a couple of questions. I am wondering why this won't work:

$('li').html(function(){
  return '<em>' + this.text() + '</em>';
});

But this will:

$('li').html(function(){
  return '<em>' + $(this).text() + '</em>';
});

And also, why is this working:

$(document).on('load', alert('done'));

But not this:

$(document).on('load', function(){alert('done');
});

Thanks,

Paul
  • 1,277
  • 5
  • 28
  • 56
  • 2
    `this` is the plain DOM object - `$(this)` is the jQuery wrapper around the DOM object. – Sirko Apr 16 '17 at 11:27
  • 2
    For the second one, define "working". I don't think that first example is doing what you think it's doing. – David Apr 16 '17 at 11:30
  • If you use the web browser console and set breakpoint for these instructions you can dump on the console the different values and you will see the difference between the element and the jQuery objects. – Juan Apr 16 '17 at 11:32

1 Answers1

1

this and $(this):

In the first example, this is a node element, and since node elements don't have a function called text, the code will throw an error!

In the second example, you're wrapping your node element this in a jQuery object, jQuery objects does have a function called text that return the text content of the first wrapped element in that jQuery object wrap, so the code works fine.

Callback:

When you want to listen to an event you have to pass in a reference to a function that will be executed later when the event happens (hence the name callback).

In the first example, you are not passing a reference to a function, you're passing the returned value of the call to alert which is undefined. The first example is the same as:

var alertResult = alert('done');
// alertResult === undefined
$(document).on('load', alertResult);

which is wrong, because when the event occurs, the event listener will try to call the function passed in only to find that what got passed in is undefined.

In the second example, you are defining a function and passing a reference to it to the event listener. Because in JS you can do this:

var referenceToAFunction = function() {

}

and the code is then equivalent to this:

$(document).on('load', referenceToAFunction);

Edit:

Why is the first example working, and the second not?

Well in the first example a popup will show up whatever the event is, even this:

$(document).on('MrChocolatIsDeadOrCaptured', alert('done'));

because it's as I said equivalent to this:

var alertResult = alert('done'); // this executed right away
$(document).on('MrChocolatIsDeadOrCaptured', alertResult); // the alert is already poped up and closed now we are setting an event listener using the alert result

so the alert will pop up anyway!

The second doesn't work because of this. There is no such event called load that happens on the document. Use one of these alternatives:

$(document).on("DOMContentReady", function() { ... }); // the right event
$(document).ready(function() { ... });                 // shortcut of the above
$(function() { ... });                                 // shortcut of the shortcut (only for the ready event)

Just note that in the first example, the alert execution is not bound to any event. Depending on where it is in the DOM, I'd say that 99% it is executed before the DOM is actually ready (so the whole point of event listenening is missing). It happens so fast that you think that it showed up right before the DOM is loaded, but it doesn't!

Community
  • 1
  • 1
ibrahim mahrir
  • 31,174
  • 5
  • 48
  • 73
  • thanks this is helpful. About the second question. If, as you say the first example is wrong because I am passing a returned value but the second is right, why is the first working and not the second? Thanks – Paul Apr 17 '17 at 09:55
  • @Paul Check out the section **Edit:** above! – ibrahim mahrir Apr 17 '17 at 10:43