Assigning DOM Elements to a Plugin

After writing hundreds of jQuery plugins, I found this pattern for assigning DOM elements to a plugin using data attributes. Here goes:

Markup

In the markup, add data attributes that follow this pattern: data-plugin-elem-mypluginname

<div class="carousel-container">
	<div class="carousel-wrap" data-plugin-elem-mypluginname="carouselWrap">
		<div class="carousel" data-plugin-elem-mypluginname="carousel">
			<div class="carouselTile" data-plugin-elem-mypluginname="carouselTile"></div>
			<div class="carouselTile" data-plugin-elem-mypluginname="carouselTile"></div>
			<div class="carouselTile" data-plugin-elem-mypluginname="carouselTile"></div>
			<div class="carouselTile" data-plugin-elem-mypluginname="carouselTile"></div>
			<div class="carouselTile" data-plugin-elem-mypluginname="carouselTile"></div>
			<div class="carouselTile" data-plugin-elem-mypluginname="carouselTile"></div>
		</div>
	</div>

	<div class="controls">
		<a class="prev" href="#todo-prev" data-direction="prev" data-plugin-elem-mypluginname="controlPrev">
			&laquo;Prev
		</a>

		<a class="next" href="#todo-next" data-direction="next" data-plugin-elem-mypluginname="controlNext">
			&raquo;Next
		</a>
	</div>
</div>

Having the assignment in a data attribute accomplishes two things:

  1. The attribute name includes the plugin name so the markup clearly defines the association between the element and the plugin
  2. The classes are left to be used only by CSS as they were intended. If you’re working with a web designer, they can rename and reorganize the CSS classes as they see fit without disabling your plugin’s functionality and throwing Javascript errors.

Javascript Plugin

In the plugin, pull all the elements into one object for easy access:

$.fn.myPluginName = function( options ) {

	var getPluginElements = function() {

		var $pluginEls 	= _$elem.find('[data-plugin-elem-mypluginname]');
		var $els 		= {};

		$.each($pluginEls, function(i, el) {

			var $el 	= $(el);
			var elKey 	= $el.data('plugin-elem-mypluginname');

			if (typeof $els[elKey] == 'object') {
				$els[elKey] 	= $els[elKey].add($el);
			} else {
				$els[elKey] 	= $el;
			}
		});

		return $els;
	};

	var _$elem 	= $(this);
	var _$els 	= getPluginElements();

	// Your code goes here!
};

Then you can access the object properties directly as a jQuery element:

_$els.controlPrev.click();

_$els.carousel.animate(
	{ 'left': -1000 },
	{
		'duration': 1500,
		'easing': 'easeInOutQuint',
		'queue': false
	}
);

$.each(_$els.carouselTile, function(i, el) {
	// Your code goes here!
});