Zephni Zephni - 4 years ago 74
Javascript Question

$(this) referring to first selector element in extended JQuery method

This was a relatively difficult one to explain in the title, so this is a further explanation.

Say I extend JQuery by doing something like the following:

$.fn.extend({
Example:function(){
$(this).html($(this).html());
}
});


And then I call that method on multiple elements with a single selector, eg:

$(document).ready(function(){
$(".element").Example();
});


Where the HTML looks like:

<div class="element">Element 1</div>
<div class="element">Element 2</div>


The final product looks like this:

Element 1
Element 1


Obviously this is just a very simple example, but what would be the proper procedure to make each element reference itself. It seems strange, because when calling $(this).html("a change"); it is applying to each one, but when calling $(this).html() it seems to be referencing the first one it came across.

Have I got this all mixed up, would someone mind helping me get my head around this. Thanks in advance for any advice!

Answer Source

The issue is because this is a collection of all the elements in the selector. Getting the html() of a collection will only return the HTML of the first element in the set. Therefore your code sets the HTML of all elements to match the first.

To fix this you can either use an each call to change the context of this to each individual element:

$.fn.extend({
  Example: function() {
    return $(this).each(function() {
      $(this).html($(this).html() + ' foo');
    });
  }
});

$(document).ready(function() {
  $(".element").Example();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="element">Element 1</div>
<div class="element">Element 2</div>

Alternatively, you can provide a function to html() which will be applied to each element in turn:

$.fn.extend({
  Example: function() {
    return $(this).html(function(i, html) {
      return html + ' foo';
    });
  }
});

$(document).ready(function() {
  $(".element").Example();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="element">Element 1</div>
<div class="element">Element 2</div>

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download