Created
January 20, 2017 03:23
-
-
Save clodal/61a3f95b80b22b976f339248612ae387 to your computer and use it in GitHub Desktop.
Create jQuery plugin via prototype inheritance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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