Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Eacher

EACHER

Micro Loop Utility

eacher(collection,callback);

Execute a callback for each item of an Array or Object. If a string is provided, document.querySelectorAll is used to find DOM elements and make a jQuery-like collection with DOM manipulation functionality added by extensions using eacher.fn.extend.

Examples:

eacher([0,1,2],function(index,item){ console.log(index,item); }); // returns: 0 0 \n 1 1 \n 2 2
eacher({ test: true, color: 'red'  },function(key,value){ console.log(key,value); }); // returns: test true \n color red

// DOM Collections
eacher('ul li',function(index){ this.classList.add('item item--' + index); }); // adds `item` class to each li with enumerated classes, eg: `item--0`
eacher('div').addClass('myDiv');
eacher('.active').removeClass('active');

A Pen by Shaw on CodePen.

License.

(function(){
// EACHER
// Micro Loop Utility
// Loop through each item of an object or Array or use `querySelectorAll` to find DOM elements and loop through them.
// Allows jQuery-like functionality with extensions via eacher.fn.extend
function eacher(obj,callback) {
// Makes using 'new' instance calls optional.
if ( !(this instanceof eacher) ) { return new eacher(obj,callback); }
// If obj is a string, find elements with `querySelectorAll`, otherwise wrap in array if single element.
obj = ( typeof obj === 'string' ? document.querySelectorAll(obj) :
obj instanceof Node ? [obj] : obj );
var length,
i = 0;
if ( obj.length > -1 ) {
length = this.length = obj.length;
for ( ; i < length; i++ ) { this[i] = obj[i]; }
}
return this.each(obj,callback);
}
var fn = eacher.fn = eacher.prototype = {
constructor: eacher,
splice: Array.prototype.splice
};
eacher.each = fn.each = function(obj,callback){
if ( !callback ) {
if ( typeof obj !== 'function' ) { return this; }
callback = obj;
obj = this;
}
var length = obj.length,
likeArray = ( length === 0 || ( length > 0 && (length - 1) in obj ) ),
i = 0;
if ( likeArray ) {
for ( ; i < length; i++ ) {
if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { break; }
}
} else {
for ( i in obj ) {
if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { break; }
}
}
return this;
};
eacher.extend = fn.extend = function() {
var a = arguments,
target = a[0],
length = a.length,
i = 1,
key;
if ( length === 1 ) {
target = this;
i = 0;
}
for ( ; i < length; i++ ) {
if ( !a[i] ) { continue; }
for ( key in a[i] ) {
if ( a[i].hasOwnProperty(key) ) { target[key] = a[i][key]; }
}
}
return target;
}
// Expose eacher to window
this.eacher = eacher;
}());
(function(){
// Adds simple `addClass`, `removeClass`, `toggleClass` and `hasClass` functionality to Eacher DOM Collections.
function modifyClass(obj,act,c) {
if ( !c ) { return obj; }
var classes = c.split(' ');
eacher.each(classes,function(i,c){
obj.each(function(){
if ( this.classList ) { this.classList[act](c); }
else if ( act === 'add' ) { this.className += ' ' + c; }
else { this.className = this.className.replace(c,''); }
});
});
return obj;
}
eacher.fn.extend({
addClass: function(c){ return modifyClass(this,'add',c); },
removeClass: function(c){ return modifyClass(this,'remove',c); },
toggleClass: function(c, state){
if ( state !== undefined ) { return modifyClass(this,state ? 'add' : 'remove' ,c); }
return this.each(function(){
if ( this.classList && this.classList.toggle ) { this.classList.toggle(c); }
else { modifyClass(this,this.className.indexOf(c) >= 0 ? 'remove' : 'add',c); }
});
},
hasClass: function(c){
var check = false;
if ( !c ) { return check; }
this.each(function(){
check = ( this.classList ? this.classList.contains(c) : new RegExp('(^|\s)' + c + '(\s|$)', 'gi').test(this.className) );
return !check; // We only need one to be true, so break the loop if true.
});
return check;
}
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.