Skip to content

Instantly share code, notes, and snippets.

@elfacht
Last active January 5, 2022 10:53
Show Gist options
  • Save elfacht/5c4d4b4f7341c67ee72f7292880f876e to your computer and use it in GitHub Desktop.
Save elfacht/5c4d4b4f7341c67ee72f7292880f876e to your computer and use it in GitHub Desktop.
JavaScript Helper Functions

JavaScript Helper Modules

  • Add classes to an element
  • Check if element has a certain class
  • Remove classes from an element
  • Toggle classes of element
  • Find closest element of given element
  • Get current date
  • Get document height
  • Get Y position of element
  • Check if checkbox is checked
  • Remove HTML from a string
  • Scroll to element with transition
/**
* Add classes to an element
*
* @param object $element – DOM element | required
* @param string className – CSS class to be added | required
* @return function|string
*/
export default function($element, className) {
if ($element.classList) {
$element.classList.add(className);
} else {
$element.className += ' ' + className;
}
}
/**
* Check if element has a certain class
*
* @param object $target – the target element | required
* @param string className – the CSS class name to check | required
* @return boolean
*/
export default function($target, className) {
return new RegExp('(\\s|^)' + className + '(\\s|$)').test($target.className);
}
/**
* Remove classes from an element
*
* @param object $element – DOM element | required
* @param string className – CSS class to be removed | required
* @return function|string
*/
export default function($element, className) {
if ($element.classList) {
$element.classList.remove(className);
} else {
$element.className = $element.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
}
}
/**
* Toggle CSS classes of element
*
* @param object $el – target element | reuqired
* @param string className – CSS class name, without '.' | required
* @return function|string
*/
export default function($el, className) {
if ($el.classList) {
$el.classList.toggle(className);
} else {
const classes = $el.className.split(' ');
const existingIndex = classes.indexOf(className);
if (existingIndex >= 0) {
classes.splice(existingIndex, 1);
} else {
classes.push(className);
$el.className = classes.join(' ');
}
}
}
/**
* Find closest element (by class) of given element
*
* @param object el – given element | required
* @param string selector – closest selector to find | required
* @return object|boolean
*/
export default function($el, selector) {
var matchesFn;
// find vendor prefix
['matches', 'webkitMatchesSelector', 'mozMatchesSelector', 'msMatchesSelector', 'oMatchesSelector'].some(function (fn) {
if (typeof document.body[fn] === 'function') {
matchesFn = fn;
return true;
}
return false;
});
var parent;
// traverse parents
while ($el) {
parent = $el.parentElement;
if (parent && parent[matchesFn](selector)) {
return parent;
}
$el = parent;
}
return null;
}
/**
* Get current date
*
* @return date
*/
export default function() {
var date = new Date(),
month = date.getMonth()+1,
day = date.getDay(),
currentDate = (day<10 ? '0' : '') + day + '.' + (month<10 ? '0' : '') + month + '.' + date.getFullYear();
return currentDate;
}
/**
* Get document height
*
* @return integer
*/
export default function() {
const body = document.body;
const html = document.documentElement;
const height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
return height;
}
/**
* Get Y position of element
*
* @param string query – query selector | required
* @return integer
*/
export default function(query) {
return window.pageYOffset + document.querySelector(query).getBoundingClientRect().top;
}
/**
* Check if checkbox is checked
*
* @param object $checkbox – checkbox DOM element | required
* @return boolean
*/
export default function($checkbox) {
return $checkbox.checked ? true : false;
}
/**
* Remove HTML from a string
*
* @param string $str | required
* @return string
*/
export default function($str) {
return str.replace(/(<([^>]+)>)/ig, '');
}
/**
* Scroll to element with transition
*
* @param object $el – clicked element | required
* @param integer duration – scrolling duration | optional
* @param boolean isOption – checks if element is <option> | optional
* @return function
*/
import getElementYPos from './GetYPosition.js';
export default function($el, duration, isOption) {
const dur = duration ? duration : 300;
// check if <option> or <a>
const target = isOption ? $el.value : $el.getAttribute('href');
const startingY = window.pageYOffset;
const dataOffset = $el.dataset.scrollOffset;
const offset = dataOffset ? dataOffset : 0;
const elementY = getElementYPos(target) - offset;
// If element is close to page's bottom then window will scroll only to some position above the element.
var targetY = document.body.scrollHeight - elementY < window.innerHeight ? document.body.scrollHeight - window.innerHeight : elementY;
var diff = targetY - startingY;
// Easing function: easeInOutCubic
// From: https://gist.github.com/gre/1650294
const easing = function (t) { return t<0.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1; };
var start;
if (!diff) { return; }
// Bootstrap our animation - it will get called right before next frame shall be rendered.
window.requestAnimationFrame(function step(timestamp) {
if (!start) { start = timestamp; }
// Elapsed miliseconds since start of scrolling.
const time = timestamp - start;
// Get percent of completion in range [0, 1].
var percent = Math.min(time / dur, 1);
// Apply the easing.
// It can cause bad-looking slow frames in browser performance tool, so be careful.
percent = easing(percent);
window.scrollTo(0, startingY + diff * percent);
// Proceed with animation as long as we wanted it to.
if (time < dur) {
window.requestAnimationFrame(step);
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment