简体   繁体   中英

Adding a function to one jQuery/DOM element

I am authoring a plugin which instantiates a map. The map would then provide a function to move to another place on the earth.

The script makes the map just fine. However I can't "tack" the function on the element, to be used by another plugin in a callback.

Here's the approach I tried; in plugin:

(function($){
  $.fn.mapDo(options){
    map = new BlahMap(this.get(0));

    this.moveTheMap = function(place){
      map.moveItToThat(place);
    }; // nope.
  }
})(jQuery);

Then, in view:

$(map).mapDo();

$(otherElement).otherControl({
  callback: function(place){
    $(map).moveTheMap(place); // moveTheMap is not there on $(map)!
  }
};

The Question

How do I add a function to the map jQuery or DOM element, if possible? If not, how can I provide that kind of functionality?

More importantly, am I going the right way here by separating the things that way? I'm a bit of a neophyte to Javascript, how are these tasks usually done while still keeping the components apart?

While that's the stab I took at it, more generally, I struggled with the concept of outputting things from a jQuery plugin while maintaining chainability. In this case, what I am trying to do is to output a callback from the plugin that will work on the called element later in the execution.

You could store the map with .data method.

(function($){
  $.fn.mapDo = funciont(options) {
    this.data('map', new BlahMap(this.get(0)));
    return this;
  };
  $.fn.moveTheMap = function(place) {
      var map = this.data('map');
      if (map) {
         map.moveItToThat(place);
      }
      return this;
  };
})(jQuery);

Plugins normally only add one method to the jQuery prototype, and the method calls to the plugin's instances are done with strings.

(function($) {
    $.fn.mapDo = function(options) {
        var args = [].slice.call(arguments, 1); //Get all the arguments starting from 2nd argument as an array
        return this.each(function() {
            var $this = $(this),
                instance = $this.data("map-instance");
            if (!instance) {
                $this.data("map-instance", (instance = new BlahMap(this, options)));
            }
            if (typeof options == "string") {
                instance[options].apply(instance, args);
            }
        });
    };
})(jQuery);

$(elem).mapDo( "moveTheMap", place ); //This would also instantiate the plugin if it wasn't instantiated

Here's jsfiddle showing it in action:

http://jsfiddle.net/X8YA8/1/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM