Last active
March 10, 2019 19:25
-
-
Save chaance/61795fe6d3cae2f09013f7c10aca5094 to your computer and use it in GitHub Desktop.
Random collection of utility functions. Because we could all use fewer dependencies.
This file contains hidden or 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
// Camel case a thing! | |
export const camelCase = str => `${str.charAt( 0 ).toLowerCase()}${str.replace( /[\W_]/g, '|' ).split( '|' ) | |
.map( part => `${part.charAt( 0 ).toUpperCase()}${part.slice( 1 )}` ) | |
.join( '' ) | |
.slice( 1 )}`; | |
// Debounce a thing! | |
export const debounce = ( func, wait, immediate ) => { | |
let timeout; | |
return function() { | |
const context = this; | |
const args = arguments; | |
const later = () => { | |
timeout = null; | |
if ( ! immediate ) { | |
func.apply( context, args ); | |
} | |
}; | |
const callNow = immediate && ! timeout; | |
clearTimeout( timeout ); | |
timeout = setTimeout( later, wait ); | |
if ( callNow ) { | |
func.apply( context, args ); | |
} | |
}; | |
}; | |
// Check if a thing is in the viewport! | |
export const inViewport = ( el, h ) => { | |
const docElem = window.document.documentElement; | |
function getViewportH() { | |
const client = docElem.clientHeight; | |
const inner = window.innerHeight; | |
if ( client < inner ) { | |
return inner; | |
} else { | |
return client; | |
} | |
} | |
function scrollY() { | |
return window.pageYOffset || docElem.scrollTop; | |
} | |
// http://stackoverflow.com/a/5598797/989439 | |
function getOffset( el ) { | |
let offsetTop = 0; | |
let offsetLeft = 0; | |
do { | |
if ( ! isNaN( el.offsetTop ) ) { | |
offsetTop += el.offsetTop; | |
} | |
if ( ! isNaN( el.offsetLeft ) ) { | |
offsetLeft += el.offsetLeft; | |
} | |
} while ( el = el.offsetParent ); // eslint-disable-line no-cond-assign | |
return { | |
top: offsetTop, | |
left: offsetLeft, | |
}; | |
} | |
const elH = el.offsetHeight; | |
const scrolled = scrollY(); | |
const viewed = scrolled + getViewportH(); | |
const elTop = getOffset( el ).top; | |
const elBottom = elTop + elH; | |
// if 0, the element is considered in the viewport as soon as it enters. | |
// if 1, the element is considered in the viewport only when it's fully inside | |
// value in percentage (1 >= h >= 0) | |
h = h || 0; | |
return ( elTop + ( elH * h ) ) <= viewed && ( elBottom ) >= scrolled; | |
}; | |
/** | |
* Check if a thing's CSS transition is done transitioning. | |
* Example usage: | |
* const transitionEnd = onTransitionEnd( element ); | |
* element.addEventListener( transitionEnd, func, false ); | |
* | |
* @param {HTMLElement} el - The DOM element the listener will be attached to. | |
* @returns {string} - The event to be emitted when the transition ends. | |
*/ | |
export const onTransitionEnd = el => { | |
const transitions = { | |
'transition': 'transitionend', | |
'OTransition': 'oTransitionEnd', | |
'MozTransition': 'transitionend', | |
'WebkitTransition': 'webkitTransitionEnd', | |
}; | |
for ( const t in transitions ) { | |
if ( el.style[ t ] !== undefined ) { | |
return transitions[ t ]; | |
} | |
} | |
}; | |
/** | |
* Generate a query string given a simple JSON object with key/value pairs. | |
* Assumes keys and values are primitive types. | |
* For nested values and added security, use https://www.npmjs.com/package/qs | |
* | |
* @param {Object.<string, (string|number)>} params - Query parameters. | |
* @returns {string} - Formatted query string. | |
*/ | |
export const queryString = params => { | |
const qs = Object.keys( params ).reduce( ( str, key ) => { | |
if ( params[ key ] ) { | |
return `${ str }&${ key }=${ encodeURIComponent( | |
params[ key ], | |
) }`; | |
} | |
return str; | |
}, '' ); | |
return qs ? `?${ qs }` : ''; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment