Skip to content

Instantly share code, notes, and snippets.

@clodal
Created January 20, 2017 03:23
Show Gist options
  • Save clodal/61a3f95b80b22b976f339248612ae387 to your computer and use it in GitHub Desktop.
Save clodal/61a3f95b80b22b976f339248612ae387 to your computer and use it in GitHub Desktop.
Create jQuery plugin via prototype inheritance
/**
* Generate a jQuery plugin
* @param {String} name - Plugin name
* @param {{}} object - Class of the plugin
*
* @example
* import setPlugin from 'plugin';
*
* /// 1. Design an object representing the concept/behaviours to model
* // @type {{}}
* const myObject = {
*
* init(options, element) {
*
* // Mix in the passed-in options with the default options
* this.options = $.extend({}, this.options, options);
*
* // Save the element reference, both as a jQuery
* // reference and a normal reference
* this.element = element
* this.$element = $(element)
*
* // Run custom methods on init here
* this.myCustomMethod()
*
* // Return `this` so that* we can chain and use the bridge with less code.
* return this
* },
*
* options {
* ...
* },
*
* myCustomMethod() {
* ...
* },
*
* ...
*
* }
*
* /// 2. Create the plugin with the constructor function
* setPlugin('myObjectNameSpace', MyPlugin);
*
* /// 3. Create DOM-Object Bridge via Data-API
* // Define the options we want and attach it to the targeted element to create the bridge
* $('#elem').myObjectNameSpace({
* name: 'John'
* })
*
* // Save the bridge to a variable for easy access
* var myObjectNameSpaceActions = $('#elem').data('myObjectNameSpace')
*
* // Use this bridge to access the object's methods
* myObjectNameSpaceActions.myCustomMethod()
*
*/
export default function setPluginHandler(name, object, $ = jQuery) {
// Object.create support test, and fallback for browsers without it
if (typeof Object.create !== "function") {
Object.create = o => {
function F() {
}
F.prototype = o;
return new F();
};
}
// Create a plugin based on a defined object
$.fn[name] = function (options) {
return this.each(function () {
if (!$.data(this, name)) {
$.data(this, name, Object.create(object).init(options, this));
}
});
};
// No conflict
$.fn[name].noConflict = () => $.fn[name] = $.fn[name]
}
import setPlugin from 'es6/base/_plugin.js'
(($) => {
/**
* @type {string}
*/
const pluginName = 'coolio'
/**
* @type {{}}
*/
const defaults = {
activeClass: 'stage-open', // toggle class name to activate the plugin
contentClass: 'stage-content',
asideClass: 'stage-aside'
}
/**
* @type {string}
*/
const dataApi = `[data-toggle="${pluginName}"]`
/**
* An object representing the concept/behaviours to model
* @type {{}}
*/
const pluginObject = {
init(options, element) {
// Mix in the passed-in options with the default options
this.options = $.extend({}, defaults, options)
// Save the element reference, both as a jQuery
// reference and a normal reference
this.element = element
this.$element = $(element)
// Run custom methods on init here
// Return `this` so that we can chain and use the bridge with less code.
return this;
},
isOpen() {
return $(this.element).hasClass(this.options.activeClass)
},
toggle() {
if (this.isOpen()) {
this.close()
} else {
this.open()
}
},
open() {
return $(this.element).addClass(this.options.activeClass)
},
close() {
return $(this.element).removeClass(this.options.activeClass)
}
};
/**
* Create the plugin with the constructor function
*/
setPlugin(pluginName, pluginObject)
/**
* Create DOM-Object Bridge via Data-API
*
* Attach the plugin to the DOM element with
* the dataApi attribute
*/
$(document).on('click', dataApi, function () {
// 1. Get the DOM element to install the plugin to
const $target = $(`.${this.getAttribute('data-target')}`)
// 2. Find the targeted element and skip bridge creation if it already exists
if (!$target.data(`${pluginName}`)) {
// 3. Get the options set from the other data attributes to override defaults
const options = $(this).data()
// 4. Define the options we want and attach it to the targeted element to create the bridge
$target[`${pluginName}`](options)
}
// 5a. Save the bridge to a variable for easy access
let pluginActions = $target.data(`${pluginName}`)
// 5b. Use this bridge to access the object's methods
pluginActions.toggle()
})
})(jQuery)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment