简体   繁体   中英

Pure Javascript plugin development

I need to develop a pure javascript plugin wich can be accessed like jquery typed plugins ( $('.pluginWrapper').pluginInit();

However i need to to use pure javascript and i was thinking maybe about 2 supported formats:

document.getElementById('pluginWrapper').pluginInit();
pluginInit(document.getElementById('pluginWrapper'));

I know that you have to do an IIFE to wrap it and call it via object methods but i do not know how i can bind that to an element.

I am mentioning that i am a begginer so please can someone please explain something about this. Cheers!

You would be safer developing a plugin interface that simply exposes plugins as functions which take an element as an argument.

function MyPlugin(element) {
  // do stuff with element
  element.setAttribute('data-plugin-id', 'pluginName');
}

The other approach involves extending Element.prototype . Which could potentially be a dangerous action in production software.

However, it is still possible.

Element.prototype.pluginInit = function() {
  // the element is accessible as `this`
  this.setAttribute('data-plugin-id', 'pluginName');
}

A function is easy for everyone to understand. Plugin writers don't have to understand any interfaces for creating and registering plugins, they just need to know that they should write functions that take elements as arguments.

There's a great talk from Rich Hickey (the creator of Clojure) called Simplicity Matters in which he stresses that the worst thing you can do is add additional complexity when simple solutions will do.

In this case, you don't need anything more complex than a function which takes an element as an argument.


If it is completely essential that you have control of the function, you could write a simple interface for registering and initiating plugins.

function Plugin(element) {
  if(element === null) {
    throw new TypeError("Element must not be null!");
  }

  // get all the plugin names from the store
  var pluginNames = Object.keys(Plugin.store);

  // make sure `this` is set to the element for each plugin
  var availablePlugins = pluginNames.reduce(function(plugins, name) {
    plugins[name] = Plugin.store[name].bind(element);
    return plugins;
  }, {});

  // return an object containing all plugins
  return availablePlugins;
}

// we'll store the plugins in this object
Plugin.store = {};

// we can register new plugins with this method
Plugin.register = function(name, pluginFn) {
  Plugin.store[name] = pluginFn;
};

Which you could use like this.

Plugin.register('myPlugin', function() {
  this.setAttribute('data-plugin-id', 'myPlugin');
});

Plugin(document.getElementById('pluginWrapper')).myPlugin();

If you want the plugin function to take a selector, the same way as jQuery, then you can use document.querySelectorAll inside your definition for Plugin .

function Plugin(selector) {
  var element = document.querySelectorAll(selector);

  if(element === null) {
    throw new TypeError("Element must not be null!");
  }

  // get all the plugin names from the store
  var pluginNames = Object.keys(Plugin.store);

  // make sure `this` is set to the element for each plugin
  var availablePlugins = pluginNames.reduce(function(plugins, name) {
    plugins[name] = Plugin.store[name].bind(element);
    return plugins;
  }, {});

  // return an object containing all plugins
  return availablePlugins;
}

Then you would use it like this instead.

Plugin.register('myPlugin', function() {
  this.setAttribute('data-plugin-id', 'myPlugin');
});

Plugin('#pluginWrapper').myPlugin();

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