Return to Snippet

Revision: 25395
at December 8, 2012 11:14 by freelancephp


Updated Code
/**
 * SimpleSelector ($$)
 *
* @fileOverview
 *    SimpleSelector is a small DOM selector object with support for the
 *    most used selectors, like:
 *     - By id:        $$('#wrap')
 *     - By class:     $$('.special')
 *     - By tag:       $$('p')
 *     - Mulitple:     $$('#id, .cls')
 *     - Give context: $$('a', '#wrap') or $$('#wrap a')
 *    Released under MIT license.
 * @version 1.1.0
 * @author Victor Villaverde Laan
 * @link http://www.freelancephp.net/simple-css-selector-function/
 * @link https://github.com/freelancephp/SimpleSelector
 */
(function (window) {

var SimpleSelector = window.SimpleSelector = {

	/**
	 * Selector function
	 * @param {String} selector
	 * @param {String|DOMElement|DOMElement[]} [context=window.document]
	 * @return {DOMElement[]}
	 */
	select: function (selector, context) {
		var s = selector,
			c = context,
			els = [];

		// prepare selector
		s = s.split(',');

		// prepare context
		c = isObjType(c, 'String') ? $$(c) : c && c.length ? c : window.document;

		// make array
		if (!isObjType(c, 'Array'))
			c = [c];

		// loop through given contexts
		for (var i in c) {
			// loop through given selectors
			for ( var j in s) {
				var strim = s[j].replace(/\s+/g, ''),
					sp = s[j].split(' '),
					op = strim.substr(0, 1),
					name = strim.substr(1),
					tels = [],
					nextContext;

				if (sp.length > 1) {
				// make recursive call to handle f.e. "body div p strong"
					nextContext = $$(sp[0], c[i]);
					tels = $$(sp.slice(1).join(' '), nextContext);
					els = els.concat(tels);
				} else if (op == '#') {
				// by id
					tels[0] = c[i].getElementById ? c[i].getElementById(name) : window.document.getElementById(name);

					// check if founded array is part of context
					if (tels[0] && SimpleSelector.isDescendant(tels[0], c[i]))
						els.push(tels[0]);
				} else if (op == '.') {
				// by className
					var expr = new RegExp('(^|\\s)'+ name +'(\\s|$)'),
						all = c[i].getElementsByTagName('*');

						// filter all elements that contain the given className
						for (var v = 0, w = all.length; v < w; v++) {
							if (expr.test(all[v].className))
								els.push(all[v]);
						}
				} else {
				// by tagName
					tels = c[i].getElementsByTagName(strim);

					// add all founded elements
					for (var y = 0, z = tels.length; y < z; y++)
						els.push(tels[y]);
				}
			}
		}

		// return array of elements
		return SimpleSelector.clearDuplicates(els);
	},

	/**
	 * Check if node is part of root element
	 * @param {DOMElement} descendant
	 * @param {DOMElement} ancestor
	 * @return {Boolean}
	 */
	isDescendant: function (descendant, ancestor) {
		return descendant.parentNode == ancestor || descendant.tagName.toUpperCase() != 'HTML' && SimpleSelector.isDescendant(descendant.parentNode, ancestor);
	},

	/**
	 * Check if item exists in array
	 * @param {Array} arr
	 * @param {Mixed} item
	 * @return {Boolean}
	 */
	itemExists: function (arr, item) {
		for (var j = 0, max = arr.length; j < max; j++) {
			if (arr[j] === item)
				return true;
		}

		return false;
	},

	/**
	 * Clear duplicate items out of array
	 * @param {Array} arr
	 * @return {Array} Cleared array
	 */
	clearDuplicates: function (arr) {
		var a = [];

		for (var i = 0, max = arr.length; i < max; i++) {
			if (!SimpleSelector.itemExists(a, arr[i]))
				a.push(arr[i]);
		}

		return a;
	}

};

/**
 * @private
 */
function isObjType (o, type) {
	return Object.prototype.toString.call(o) === '[object '+ type +']';
};

if (!window.$$) {
	/**
	* Add short name for SimpleSelector method
	* @function
	*/
	window.$$ = SimpleSelector.select;
}

})(window);

Revision: 25394
at March 30, 2010 04:53 by freelancephp


Initial Code
/*!
 * $imple$elector
 *
 * Selector by id, className or tagName, f.e.:
 * $$( '#wrap' ) or $$( '.special' ) or $$( 'p' )
 *
 * Mulitple selectors seperated by comma, f.e.:
 * $$( '#id, .cls' )
 *
 * Give context as second param, f.e.:
 * $$( 'a', '#wrap' ) or $$( 'a', wrapNode ) or $$( 'a', [node1, node2] )
 *
 * @version   0.2
 * @author    Victor Villaverde Laan
 * @link      http://www.freelancephp.net/simpleselector-javascript-dom-selector/
 * @license   MIT license
 */
var SimpleSelector = {

	/**
	 * Find elements with the given selector within the context
	 * @param selector [string]
	 * @param context  [string | DOM node | array of DOM nodes]
	 * @return [DOM node | array of DOM nodes | empty array]
	 */
	find: function ( selector, context ) {
		var selectors = selector.split( ',' ),
			elements = [],
			wrappers = [];

		// set wrappers
		if ( typeof context == 'string' ) {
			var wraps = SimpleSelector.find( context );
			// set array to wrappers
			wrappers = ( wraps.constructor == Array ) ? wraps : [ wraps ];
		} else if ( context && context.constructor == Array ) {
			wrappers = context;
		} else {
			// document is default context
			wrappers.push( context || document );
		}

		// find matching elements within the wrappers (context)
		for ( var a = 0, b = wrappers.length; a < b; a++ ) {
			for ( var x = 0, y = selectors.length; x < y; x++ ) {
				// selector: trim spaces
				var s = selectors[x].replace( / /g, '' ),
					// get operator
					operator = s.substr( 0, 1 ),
					// get key
					key = s.substr( 1 ),
					els = [];

				// get matching elements
				if ( operator == '#' ) {
					// get element by id
					els[0] = document.getElementById( key );
					// check if element is part of context
					if ( els[0] && SimpleSelector.isDescendant( els[0], wrappers[ a ] ) )
						elements.push( els[0] );
				} else if ( operator == '.' ) {
					// get element by className
					els = SimpleSelector.getByClass( key, wrappers[ a ] );
					// convert type to array
					els = [].slice.call( els, 0 );
					// add to elements collection
					elements = elements.concat( els );
				} else {
					// get element by tagName
					els = wrappers[ a ].getElementsByTagName( s );
					// add to elements collection
					// in this case [].slice.call( els, 0 ) does not work
					// in IE, says constructor is undefined??
					for ( var i = 0, j = els.length; i < j; i++ )
						elements.push( els[ i ] );
				}
			}
		}

		// return single element or array of elements
		return ( elements.length == 1 ) ? elements[0] : elements;
	},

	/**
	 * Check wether an element is a descendant of the given ancestor
	 * @param descendant [DOM node]
	 * @param ancestor   [DOM node]
	 * @return [boolean]
	 */
	isDescendant: function ( descendant, ancestor ) {
		return ( ( descendant.parentNode == ancestor )
					|| ( descendant.parentNode != document )
				&& arguments.callee( descendant.parentNode, ancestor ) );
	},

	/**
	 * Cross browser function for getting elements by className
	 * @param className [string]
	 * @param context   [DOM node]
	 * @return [array of DOM nodes]
	 */
	getByClass: function ( className, context ) {
		var elements = [],
			expr = new RegExp('\\b' + className + '\\b'),
			wrapper = context || document,
			allElements = wrapper.getElementsByTagName( '*' );

		// filter all elements that contain the given className
		for ( var x = 0, y = allElements.length; x < y; x++ ) {
			if ( expr.test( allElements[ x ].className ) )
				elements.push( allElements[ x ] );
		}

		return elements;
	}

};

// if global $$ is not set
if ( ! window.$$ )
	window.$$ = SimpleSelector.find;

Initial URL
http://www.freelancephp.net/simpleselector-javascript-dom-selector/

Initial Description
SimpleSelector is a small DOM selector object with support for the most used selectors. It's also the default selector for the jLim JavaScript framework.

Why use SimpleSelector?
- very small, less than 2kb minified
- easy to use with $$()
- no overhead, no functions you hardly ever use
- ideal for smaller websites

Initial Title
SimpleSelector, Javascript DOM selector

Initial Tags
js, object, DOM

Initial Language
JavaScript