Skip to content

Instantly share code, notes, and snippets.

@aristath
Last active September 10, 2019 21:31
Show Gist options
  • Save aristath/3cc6628091b4c85c6ba46dc553686203 to your computer and use it in GitHub Desktop.
Save aristath/3cc6628091b4c85c6ba46dc553686203 to your computer and use it in GitHub Desktop.
jQuery replacement for WordPress themes. Contains the most widely-used functions.
/**
* Find an element.
*
* @param {string|Object} selector - The css selector of the element.
* If object then it can either be document or an element.
* @param {Object} parent - The parent element, or undefined for document.
* @return {Object} - returns the _lm object to allow chaining methods.
*/
var _lm = function( selector, parent ) {
parent = parent || document;
if ( 'object' === typeof selector ) {
this.el = ( selector[0] && selector[0] instanceof Element ) ? selector : [ selector ];
} else if ( 'string' === typeof selector ) {
this.el = parent.querySelectorAll( selector );
}
return this;
};
_lm.prototype.cloneInstance = function() {
var self = this,
props = Object.getOwnPropertyDescriptors(self);
for ( var prop in props ) {
props[ prop ].value = deepClone( props[ prop ].value );
}
return Object.create(
Object.getPrototypeOf( self ),
props
);
};
/**
* Find a selector inside elements inited via findEl.
*
* @param {string} selector - The css selector of the element.
* @return {Object} - returns the _lm object to allow chaining methods.
*/
_lm.prototype.find = function( selector ) {
let parents = this.el, children = [];
for ( var i = 0; i < parents.length; i++ ) {
let item = new _lm( selector, parents[ i ] );
for ( var t = 0; t < item.el.length; t++ ) {
children.push( item.el[ t ] );
}
}
return new _lm( children );
};
/**
* Get the direct parent of elements.
*
* @return {Object} - Returns the _lm object to allow chaining methods.
*/
_lm.prototype.parent = function( selector ) {
var children = [];
for ( var i = 0; i < this.el.length; i++ ) {
let parent = ( selector ) ? _lm.findParent( this.el[ i ], selector ) : selector.parentNode;
if ( parent && -1 === children.indexOf( parent ) ) {
children.push( parent );
}
}
return new _lm( children );
};
/**
* Get the parent based of an element based on a selector.
*
* @param {Element} el - The element (instance of Element).
* @param {string} selector - The CSS selector.
* @return {Object} - returns the _lm object to allow chaining methods.
*/
_lm.prototype.findParent = function( el, selector ) {
return ( el.parentNode.matches( selector ) ) ? el.parentNode : _lm.findParent( el.parentNode, selector );
};
/**
* Figure out if the element has a class or not.
*
* @param {string} className - The class-name we're looking for.
* @return {boolean} - Whether the element has the class we need or not.
*/
_lm.prototype.hasClass = function( className ) {
for ( var i = 0; i < this.el.length; i++ ) {
if ( this.el[ i ].classList && this.el[ i ].classList.contains( className ) ) {
return true;
}
}
return false;
};
/**
* Add a class to elements.
*
* @param {string} className - The class-name we want to add to element(s).
* @return {Object} - Returns the _lm object to allow chaining methods.
*/
_lm.prototype.addClass = function( className ) {
for ( var i = 0; i < this.el.length; i++ ) {
this.el[ i ].classList.add( className );
}
return this;
};
/**
* Remove a class from elements.
*
* @param {string} className - The class-name we want to add to element(s).
* @return {Object} - Returns the _lm object to allow chaining methods.
*/
_lm.prototype.removeClass = function( className ) {
for ( var i = 0; i < this.el.length; i++ ) {
this.el[ i ].classList.remove( className );
}
return this;
};
/**
* Hide the element(s).
*
* @return {Object} - returns the _lm object to allow chaining methods.
*/
_lm.prototype.hide = function() {
for ( var i = 0; i < this.el.length; i++ ) {
this.el[ i ].style.display = 'none';
}
return this;
};
/**
* Show the element(s)
*
* @param {string} display - The css-display mode. Defaults to "block".
* @return {Object} - returns the _lm object to allow chaining methods.
*/
_lm.prototype.show = function( display ) {
display = display || 'block';
for ( var i = 0; i < this.el.length; i++ ) {
if ( 'none' === this.el[ i ].style.display ) {
this.el[ i ].style.display = display;
}
}
return this;
};
/**
* Get the styles for a property, or change the value if one is defined.
*
* @param {string} property - The CSS property we're referencing.
* @param {string|undefined} value - The value we want to assign, or undefined if we want to get the value.
* @return {Object|string} - returns the _lm object to allow chaining methods, OR the value if 2nd arg is undefined.
*/
_lm.prototype.css = function( property, value ) {
if ( 'undefined' === typeof value ) {
return getComputedStyle( this.el[ 0 ] )[ property ];
}
for ( var i = 0; i < this.el.length; i++ ) {
this.el[ i ].style[ this.camelCase( property ) ] = value;
}
return 'undefined' === typeof value ? '' : this;
};
/**
* Convert a string to camelCase.
*
* @param {string} string The string we want to convert.
* @return {string} - Returns the string formatted in camelCase.
*/
_lm.prototype.camelCase = function( string ) {
return string.replace( /-([a-z])/g, function( _all, letter ) {
return letter.toUpperCase();
} );
};
/**
* Handle events.
*
* @param {Function} method - for example addEventListener.
* @param {string} events - The JS event we want to add a listener for.
* @param {Function} listener - The function to add to the listener.
* @return {Object} - returns the _lm object to allow chaining methods.
*/
_lm.prototype.eventsHandler = function( method, events, listener ) {
events = events.split( ' ' );
for ( var i = 0; i < events.length; i++ ) {
for ( var l = 0; l < this.el.length; l++ ) {
if ( 'ready' === events[ i ] ) {
this.ready( listener );
} else {
method.call( this.el[ l ], events[ i ], listener, false );
}
}
}
return this;
};
/**
* Run a callback against located elements.
*
* @param {function} callback - The callback we want to run on each element.
* @return {Object} - returns the _lm object to allow chaining methods.
*/
_lm.prototype.each = function( callback ) {
var self = this;
for ( var i = 0; i < this.el.length; i++ ) {
callback( self.el[ i ] );
}
return this;
};
/**
* Similar to jQuery.on().
*
* @param {string} event - The JS event we want to add a listener for.
* @param {Function} listener - The function to add to the listener.
* @return {Object} - returns the _lm object to allow chaining methods.
*/
_lm.prototype.on = function( event, listener ) {
this.eventsHandler( addEventListener, event, listener );
return this;
};
/**
* Similar to jQuery.off().
*
* @param {string} event - The JS event we want to add a listener for.
* @param {Function} listener - The function to add to the listener.
* @return {void}
*/
_lm.prototype.off = function( event, listener ) {
this.eventsHandler( removeEventListener, event, listener );
};
/**
* Equivalent to jQuery's ready() function.
*
* @see https://gomakethings.com/a-native-javascript-equivalent-of-jquerys-ready-method/
* @param {function} fn - The callback function.
* @return {void}
*/
_lm.prototype.ready = function( fn ) {
if ( 'function' !== typeof fn ) { // Sanity check
return;
}
// If document is already loaded, run method
if ( document.readyState === 'complete' ) {
return fn();
}
// Otherwise, wait until document is loaded
document.addEventListener( 'DOMContentLoaded', fn, false );
};
var poop = function( selector, parent ) {
return new _lm( selector, parent )
}
@aristath
Copy link
Author

jQuery:

jQuery( '.foo' ).addClass( 'bar' ).css( 'color', '#c00' ).hide();

Poop:
Just replace jQuery with poop and you're done.


Differences:

jQuery:

jQuery( document ).ready( function() {
} );

poop:

poop().ready( function() {
} );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment