Joseph Khella
Joseph Khella

Reputation: 715

Get the element calling a function in JQuery?

I have two JQuery elements like $("myDiv1") and $("myDiv2") and I defined a proto for it called SetText() ,, In SetText Implementation, How can I know that myDiv1 is the one who called it if I did $("myDiv1").SetText() ? Thank you,

Upvotes: 0

Views: 96

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074445

You use this:

  • Within your plugin code, it will refer to the jQuery object your plugin was called on
  • Within event handlers and such, it refers to the DOM element

Quick example of a simple plugin with options and a couple of methods:

// Our "nifty" plugin.
// Note this is an ES5 and earlier example, no ES2015+ features used.
(function($) {
  // Convenient access to Array#slice
  var slice = Array.prototype.slice;
  
  // Our event namespace
  var eventNS = ".nifty";
  
  // Our data name for options
  var optionsName = "options.nifty";
  
  // Some default options
  var niftyDefaults = {
    color: "green",
    text: "default text"
  };
  
  // Our methods
  var methods = {
    init: nifty$init,
    destroy: nifty$destroy,
    options: nifty$options,
    settext: nifty$settext
  };
  
  // Main plugin function
  $.fn.nifty = function(options) {
    // Note that here, `this` is the jQuery object our plugin was called on.
    var method, args;
    
    // Determine the method to call and arguments to it
    if (typeof options === "string") {
      // Method call
      method = options;
      args = slice.call(arguments, 1); // 1 = skip the method name
    } else {
      // Init
      method = "init";
      args = slice.call(arguments, 0); // 0 = copy all
    }
    
    // Call the method, return the result
    return methods[method].apply(this, args);
  };
  
  // Because of the way we call them, `this` in all of our methods below
  // is the jQuery object we were called on
  
  // Init
  function nifty$init(options) {
    // Initialize each element individually
    this.each(function() {
      // Note that here, `this` is the DOM element for this iteration of
      // the `each` loop. Save the options; each element gets its own copy.
      $(this).data(optionsName, $.extend({}, niftyDefaults, options));
      // If we had other per-element init, we'd do it here.
    });
    
    // Let's have our "nifty" set up an event handler when initialized.
    // We do it here because we don't need a separate handler for each
    // individual element.
    this.on("click.nifty", function() {
      // Resond by setting the color according to this specific
      // element's options.
      var $this = $(this);
      $this.css("color", $this.data(optionsName).color);
    });
    
    // The main init of a plugin should almost always return `this`
    // for chaining
    return this;
  }

  // Plugins should always have a "destroy" method that undoes what they do
  // in init. It should handle it gracefully if init hasn't been called on
  // the elements.
  function nifty$destroy() {
    // Remove our event handler
    this.off("click" + eventNS);

    // Remove the event data
    return this.each(function() {
      $(this).removeData(optionsName);
    });
  }
  
  // Our "options" method
  function nifty$options(newOptions) {
    // For each element in the matched set, update the options.
    // Note how we're returning the return value from `this.each`, which is
    // `this`. A method should always return `this` unless it has a good
    // reason for doing something else.
    return this.each(function() {
      var $this = $(this);
      var opts = $this.data(optionsName);
      checkForInit("options", opts);
      $this.data(optionsName, $.extend({}, opts, newOptions));
    });
  }

  // Our "settext" method
  function nifty$settext() {
    // Set the text on each matched element individually, according to its
    // options.
    return this.each(function() {
      var $this = $(this);
      var opts = $this.data(optionsName);
      checkForInit("settext", opts);
      $this.text(opts.text);
    });
  }

  // Worker function, throws exception if a method is called on an
  // un-initialized element.
  function checkForInit(method, opts) {
    if (typeof opts === "undefined") {
      throw new Error(method + " cannot be called until `nifty` has been initialized on the element");
    }
  }
})(jQuery);

// Using it -- init
$(".foo").nifty({color: "blue"});
$(".bar").nifty({text: "bar text"});

// Calling methods - give different texts to each of the foos, override
// the color we use on the last one
$(".foo")
  .first()
  .nifty("options", {text: "I'm the first foo"})
  .end()
  .last()
  .nifty("options", {text: "I'm the last foo", color: "orange"});
         
// Call "settext" on all the foos and bars
$(".foo, .bar").nifty("settext");

// Destroy "nifty" on bar
$(".bar").nifty("destroy");

// Prove that we did and that methods complain
try {
  $(".bar").nifty("options", {color: "blue"});
  console.log("Shouldn't get here");
} catch (e) {
  console.log("Correctly got error: " + e.message);
}
<div>Click each of the three divs below.</div>
<div style="padding: 8px; border: 1px solid #ddd">
  <div class="foo">foo1</div>
  <div class="foo">foo2</div>
  <div class="bar">bar</div>
</div>
<div>Note that clicking the 'bar' element doesn't change its color, because we destroyed the nifty plugin on it after using nifty to set its text</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Upvotes: 1

Related Questions