1

I've written a really basic jQuery plugin that should log the value of a button clicked.

While it basically works, it unfortunately logs the same value for each button on the page. So if there are three buttons on the page, the value of the button clicked is logged three times.

The plugin code looks like this:

(function($) {

  $.fn.content = function() {
    return this.each(function() {
      $('button').click(function() {
        console.log($(this).html());
      });
    });
  };

}(jQuery));


$('button').content();

Fiddle

Although I am quite puzzled right now, I am pretty sure that it has something to do with the context of this inside the each loop, but I can't really figure it out.

Sven
  • 12,997
  • 27
  • 90
  • 148

2 Answers2

4

There are several issues going on here. The this inside of the fn.content function is actually the composed jQuery object. That object was $('button') so it will contain how ever many buttons there are in the DOM at that moment.

Then you iterate that set, and for each item in that set, you attach a click handler again to the $('button') group explicitly. Unfortunately this means that you have assigned a click event handler to that group n times where n is how many buttons there were. 3 buttons, 3 events; 6 buttons, 6 events.

In order to not do that, simply assign the click handler to the original jQuery object.

(function($) {

    $.fn.content = function() {
        return this.click(function() {
            console.log($(this).html());
        });
    });

}(jQuery));

Keep in mind that click will internally call .each, and that this in our example is $('button') already.

For more information on creating jQuery plugins, please see my post on the utility of jQuery.fn

Community
  • 1
  • 1
Travis J
  • 81,153
  • 41
  • 202
  • 273
  • haha you wrote it before I had a chance! Here's a fiddle additionally: https://jsfiddle.net/ft5jenwp/ – jonode Sep 01 '15 at 20:46
0

I'm not sure which scope you actually need access to, but scope of this is different for each function, including anonymous functions that you created. To access this of an outer scope, try something like the following:

function foo() {
    this.someVal = 1;
    var that = this;
    function bar() {
        console.log(that.someVal); // you have access to foo's this
    } 
}
yyx
  • 1