├── splitAnchor.js ├── scrollToTop.js ├── getComputedStyle.js ├── .DS_Store ├── getPageName.js ├── toggleElem.js ├── README.md ├── add-array-values.js ├── forEachLoop.js ├── get-widths-from-list.js ├── objectPropLoop.js ├── transforms.js ├── parallaxOpacity.js ├── removeHyphens.js ├── uppercaseFirstLetter.js ├── removeElem.js ├── getCurrentScroll.js ├── mediaQueryTest.js ├── replaceNoJS.js ├── hasClass.js ├── toggleNav.js ├── addEventListenerFallback.js ├── get-anchor.js ├── getClosestAlt.js ├── stringToHTML.js ├── getViewportSize.js ├── removeQuotes.js ├── supportsSvg.js ├── DOMready.js ├── matchMediaListener.js ├── cssSupports.js ├── delegate-event.js ├── removeClass.js ├── supports.js ├── resetActiveClass.js ├── pointerEvents.js ├── throttle.js ├── checkUrlHash.js ├── eventBinding.js ├── getSvgSprite.js ├── getAbsoluteUrl.js ├── iife.js ├── bind.js ├── remove-array-duplicates.js ├── titleCase.js ├── classList.js ├── capitalizeEachWord.js ├── lazyLoadImages.js ├── loadSVG.js ├── getIndex.js ├── once.js ├── prefixedEvent.js ├── addEvent-loop.js ├── onetime.js ├── getHeight.js ├── matchesSelector.js ├── nodelist.forEach.js ├── add-remove-class.js ├── requestAnimThrottle.js ├── getDocumentHeight.js ├── animationEventListener.js ├── getSupportedPropertyName.js ├── getNextSibling.js ├── stickyElement.js ├── getPreviousSibling.js ├── isInViewport.js ├── manipulateDom.js ├── traverse.js ├── getNextUntil.js ├── getPreviousUntil.js ├── isValidEmail.js ├── getSiblings.js ├── insertRule.js ├── ready.js ├── svg.js ├── optimizedScrollEvent.js ├── checkMedia.js ├── getElemDistance.js ├── getMaxWidth.js ├── handleEvent.js ├── loadScript.js ├── getElemInfo.js ├── closestParent.js ├── on.js ├── truncate.js ├── whichTransitionEvent.js ├── loops.js ├── bindPolyfill.js ├── getQueryString.js ├── skip-link-focus-fix.js ├── debounce.js ├── reverseHeader.js ├── revealing-module-pattern.js ├── nextUntil.js ├── prevUntil.js ├── animate.js ├── getJSONP.js ├── autoHideSticky.js ├── poll.js ├── checkActiveCategory.js ├── cross-bowser-class-handlers.js ├── checkVisibility.js ├── getClosest.js ├── parallaxPosition.js ├── cutsMustard.js ├── show-nav-desc.js ├── getParents.js ├── iconsFallback.js ├── forEach.js ├── getParentsUntil.js ├── extend.js ├── onAnimationEnd.js ├── getURL.js ├── fluidVids.js ├── revealing-module-pattern-options.js ├── loadCSS.js ├── navigation.js ├── revealing-module-pattern-constructor.js ├── event-polyfill.js ├── addEventListenerPolyfill.js ├── isVisible.js ├── stickyFooter.js └── classList-polyfill.js /splitAnchor.js: -------------------------------------------------------------------------------- 1 | anchor.href.split('#')[1] -------------------------------------------------------------------------------- /scrollToTop.js: -------------------------------------------------------------------------------- 1 | // Scroll window to top 2 | window.scrollTop = 0; -------------------------------------------------------------------------------- /getComputedStyle.js: -------------------------------------------------------------------------------- 1 | window.getComputedStyle(header,null).getPropertyValue('top') -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonyablonski/javascript-toolbox/HEAD/.DS_Store -------------------------------------------------------------------------------- /getPageName.js: -------------------------------------------------------------------------------- 1 | var pageName = window.location.pathname.substring(1).split(/[/.]+/g)[0]; -------------------------------------------------------------------------------- /toggleElem.js: -------------------------------------------------------------------------------- 1 | var toggleElem = function( elem ) { 2 | elem.classList.toggle( activeClass ); 3 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | javascript-toolbox 2 | ================== 3 | 4 | A collection of useful javascript snippets. 5 | -------------------------------------------------------------------------------- /add-array-values.js: -------------------------------------------------------------------------------- 1 | let sum = item.reduce((accumulator, value) => { 2 | return accumulator + value; 3 | }, 0); -------------------------------------------------------------------------------- /forEachLoop.js: -------------------------------------------------------------------------------- 1 | [].forEach.call(element, function(el) { 2 | el.addEventListener('click', fnName, false); 3 | }); -------------------------------------------------------------------------------- /get-widths-from-list.js: -------------------------------------------------------------------------------- 1 | let itemWidths = Array.from(item).map(function (item) { 2 | return item.offsetWidth; 3 | }); -------------------------------------------------------------------------------- /objectPropLoop.js: -------------------------------------------------------------------------------- 1 | Object.keys(coordinates).forEach(function(key) { 2 | console.log(key, coordinates[key]); 3 | }); -------------------------------------------------------------------------------- /transforms.js: -------------------------------------------------------------------------------- 1 | var transforms = [ 2 | "transform", 3 | "msTransform", 4 | "webkitTransform", 5 | "mozTransform", 6 | "oTransform"]; -------------------------------------------------------------------------------- /parallaxOpacity.js: -------------------------------------------------------------------------------- 1 | var parallaxOpacity = function(element) { 2 | element.style.opacity = 1-Math.floor(latestKnownScrollY)/1000; 3 | }; -------------------------------------------------------------------------------- /removeHyphens.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Remove Hyphens 3 | */ 4 | var removeHyphens = function(string) { 5 | return string.replace(/-/g, ' '); 6 | }; -------------------------------------------------------------------------------- /uppercaseFirstLetter.js: -------------------------------------------------------------------------------- 1 | var uppercaseFirstLetter = function( string ) { 2 | return string.charAt(0).toUpperCase() + string.slice(1); 3 | }; -------------------------------------------------------------------------------- /removeElem.js: -------------------------------------------------------------------------------- 1 | var removeElement = function( element ) { 2 | if ( element.parentNode ) { 3 | element.parentNode.removeChild( element ); 4 | } 5 | }; -------------------------------------------------------------------------------- /getCurrentScroll.js: -------------------------------------------------------------------------------- 1 | var getCurrentScroll = function() { 2 | return { 3 | x: window.pageXOffset, 4 | y: window.pageYOffset 5 | }; 6 | }; -------------------------------------------------------------------------------- /mediaQueryTest.js: -------------------------------------------------------------------------------- 1 | // Test for CSS media query support 2 | if ( window.matchMedia("only all").matches ) { 3 | // Media Queries are natively supported 4 | } -------------------------------------------------------------------------------- /replaceNoJS.js: -------------------------------------------------------------------------------- 1 | // Replace 'no-js' w/ 'js' on document el 2 | document.documentElement.className = document.documentElement.className.replace('no-js', 'js' ); -------------------------------------------------------------------------------- /hasClass.js: -------------------------------------------------------------------------------- 1 | // hasClass, takes two params: element and classname 2 | function hasClass(el, cls) { 3 | return el.className && new RegExp("(\\s|^)" + cls + "(\\s|$)").test(el.className); 4 | } -------------------------------------------------------------------------------- /toggleNav.js: -------------------------------------------------------------------------------- 1 | var toggleNav = function(e) { 2 | body.classList.contains(toggledNavClass) ? body.classList.remove(toggledNavClass) : body.classList.add(toggledNavClass); 3 | e.preventDefault(); 4 | }; -------------------------------------------------------------------------------- /addEventListenerFallback.js: -------------------------------------------------------------------------------- 1 | if (document.addEventListener) { 2 | el.addEventListener('click', modifyText, false); 3 | } else if (document.attachEvent) { 4 | el.attachEvent('onclick', modifyText); 5 | } -------------------------------------------------------------------------------- /get-anchor.js: -------------------------------------------------------------------------------- 1 | var anchor = event.target; 2 | 3 | // Go up in the nodelist until we find a node with .href (HTMLAnchorElement) 4 | while ( anchor && !anchor.href ) { 5 | anchor = anchor.parentNode; 6 | } -------------------------------------------------------------------------------- /getClosestAlt.js: -------------------------------------------------------------------------------- 1 | const getClosest = function (elem, selector) { 2 | for (; elem && elem !== document; elem = elem.parentNode) { 3 | if (elem.matches(selector)) return elem; 4 | } 5 | return null; 6 | }; -------------------------------------------------------------------------------- /stringToHTML.js: -------------------------------------------------------------------------------- 1 | // Turn strings into HTML 2 | const stringToHTML = (str) => { 3 | let parser = new DOMParser(); 4 | let doc = parser.parseFromString(str, 'text/html'); 5 | return doc.body.firstChild; 6 | } -------------------------------------------------------------------------------- /getViewportSize.js: -------------------------------------------------------------------------------- 1 | var getViewportSize = function() { 2 | return { 3 | width: window.document.documentElement.clientWidth, 4 | height: window.document.documentElement.clientHeight 5 | }; 6 | }; -------------------------------------------------------------------------------- /removeQuotes.js: -------------------------------------------------------------------------------- 1 | function removeQuotes(string) { 2 | if (typeof string === 'string' || string instanceof String) { 3 | string = string.replace(/^['"]+|\s+|\\|(;\s?})+|['"]$/g, ''); 4 | } 5 | return string; 6 | } -------------------------------------------------------------------------------- /supportsSvg.js: -------------------------------------------------------------------------------- 1 | var supportsSvg = function() { 2 | var div = document.createElement('div'); 3 | div.innerHTML = ''; 4 | return (div.firstChild && div.firstChild.namespaceURI) === 'http://www.w3.org/2000/svg'; 5 | }; -------------------------------------------------------------------------------- /DOMready.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Document Ready 3 | * Same as jQuery .ready method 4 | * ! Putting JS at the bottom of the page does the same thing 5 | */ 6 | document.addEventListener("DOMContentLoaded", function() { 7 | // Code 8 | }, false); -------------------------------------------------------------------------------- /matchMediaListener.js: -------------------------------------------------------------------------------- 1 | window.matchMedia( "(min-width: 45em)" ).addListener( function( mm ) { 2 | if ( mm.matches ) { 3 | // The viewport is at least 45em in width 4 | } else { 5 | // The viewport is less than 45em in width 6 | } 7 | }); -------------------------------------------------------------------------------- /cssSupports.js: -------------------------------------------------------------------------------- 1 | // CSS Supports normalization 2 | var cssSupports = window.CSS && window.CSS.supports || window.supportsCSS; 3 | 4 | // Usage 5 | if ( cssSupports && cssSupports ('(transition: none)') ) { 6 | // CSS transitions are supported! 7 | } -------------------------------------------------------------------------------- /delegate-event.js: -------------------------------------------------------------------------------- 1 | var functionName = function () { 2 | element.addEventListener( 'click', function( event ) { 3 | if( event.target && event.target.nodeName === 'A' ) { 4 | // Do Something 5 | } 6 | }); 7 | }; 8 | 9 | functionName(); -------------------------------------------------------------------------------- /removeClass.js: -------------------------------------------------------------------------------- 1 | // removeClass, takes two params: element and classname 2 | function removeClass(el, cls) { 3 | var reg = new RegExp("(\\s|^)" + cls + "(\\s|$)"); 4 | el.className = el.className.replace(reg, " ").replace(/(^\s*)|(\s*$)/g,""); 5 | } -------------------------------------------------------------------------------- /supports.js: -------------------------------------------------------------------------------- 1 | var supports = !!document.querySelector && !!window.addEventListener; 2 | 3 | var cutMustard = (function(){ 4 | if ( !supports ) { 5 | document.documentElement.className += ' ' + 'cuts-mustard'; 6 | } else { 7 | return; 8 | } 9 | })(); -------------------------------------------------------------------------------- /resetActiveClass.js: -------------------------------------------------------------------------------- 1 | var resetActiveClass = function ( elem ) { 2 | var siblings = getSiblings( elem ); 3 | forEach( siblings, function ( value ) { 4 | if (value.classList.contains( activeClass )) { 5 | value.classList.remove( activeClass ); 6 | } 7 | }); 8 | }; -------------------------------------------------------------------------------- /pointerEvents.js: -------------------------------------------------------------------------------- 1 | function pointerEvents() { 2 | var element = document.createElement('x'); 3 | element.style.cssText = 'pointer-events:auto'; 4 | return element.style.pointerEvents === 'auto'; 5 | } 6 | if (pointerEvents()) { 7 | document.documentElement.className += ' pointer-events'; 8 | } -------------------------------------------------------------------------------- /throttle.js: -------------------------------------------------------------------------------- 1 | var throttle = function(callback, limit) { 2 | var wait = false; 3 | return function () { 4 | if (!wait) { 5 | callback.call(); 6 | wait = true; 7 | setTimeout(function () { 8 | wait = false; 9 | }, limit); 10 | } 11 | }; 12 | }; -------------------------------------------------------------------------------- /checkUrlHash.js: -------------------------------------------------------------------------------- 1 | var checkURL = (function() { 2 | if ( window.location.hash ) { 3 | var hash = window.location.hash.substring(1); 4 | if ( hash === 'newsletter' ) { 5 | var trigger = document.querySelector( '.intro__news' ).querySelector( 'a' ); 6 | trigger.click(); 7 | } 8 | } 9 | })(); -------------------------------------------------------------------------------- /eventBinding.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This gives us simple dollar function and event binding 3 | */ 4 | var $ = document.querySelectorAll.bind(document); 5 | Element.prototype.on = Element.prototype.addEventListener; 6 | 7 | // This is how you use it 8 | $(".element")[0].on("touchstart", handleTouch, false); -------------------------------------------------------------------------------- /getSvgSprite.js: -------------------------------------------------------------------------------- 1 | var ajax = new XMLHttpRequest(); 2 | ajax.open("GET", "svg/sprite.svg", true); 3 | ajax.send(); 4 | ajax.onload = function(e) { 5 | var div = document.createElement("div"); 6 | div.innerHTML = ajax.responseText; 7 | document.body.insertBefore(div, document.body.childNodes[0]); 8 | } -------------------------------------------------------------------------------- /getAbsoluteUrl.js: -------------------------------------------------------------------------------- 1 | var getAbsoluteUrl = (function() { 2 | var a; 3 | 4 | return function(url) { 5 | if(!a) a = document.createElement('a'); 6 | a.href = url; 7 | 8 | return a.href; 9 | }; 10 | })(); 11 | 12 | // Usage 13 | getAbsoluteUrl('/something'); // https://davidwalsh.name/something -------------------------------------------------------------------------------- /iife.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Immediately Invoked Function Expression Boilerplate 3 | * (c) 2017 Chris Ferdinandi, MIT License, https://gomakethings.com 4 | */ 5 | ;(function (window, document, undefined) { 6 | 7 | 'use strict'; 8 | 9 | // Code goes here... 10 | 11 | })(window, document); 12 | -------------------------------------------------------------------------------- /bind.js: -------------------------------------------------------------------------------- 1 | var elem = document.querySelector('.some-class'); 2 | var someFunction = function (var1, var2, var3, event) { 3 | // Do stuff 4 | } 5 | elem.addEventListener('click', someFunction.bind(null, var1, var2, var3), false); 6 | elem.addEventListener('mouseover', someFunction.bind(null, var1, var2, var3), false); -------------------------------------------------------------------------------- /remove-array-duplicates.js: -------------------------------------------------------------------------------- 1 | var sandwiches = ['turkey', 'ham', 'turkey', 'tuna', 'pb&j', 'ham', 'turkey', 'tuna']; 2 | 3 | var deduped = sandwiches.filter(function (sandwich, index) { 4 | return sandwiches.indexOf(sandwich) === index; 5 | }); 6 | 7 | // Logs ["turkey", "ham", "tuna", "pb&j"] 8 | console.log(deduped); -------------------------------------------------------------------------------- /titleCase.js: -------------------------------------------------------------------------------- 1 | var titleCase = function(str) { 2 | var splitStr = str.toLowerCase().split(' '); 3 | for (var i = 0; i < splitStr.length; i++) { 4 | splitStr[i] = splitStr[i].charAt(0).toUpperCase() + splitStr[i].substring(1); 5 | } 6 | return splitStr.join(' '); 7 | }; 8 | 9 | // Usage 10 | titleCase(stringName); -------------------------------------------------------------------------------- /classList.js: -------------------------------------------------------------------------------- 1 | /** 2 | * classList class methods 3 | */ 4 | 5 | // Adding a class 6 | element.classList.add("bar"); 7 | 8 | // Removing a class 9 | element.classList.remove("foo"); 10 | 11 | // Checking if has a class 12 | element.classList.contains("foo"); 13 | 14 | // Toggle a class 15 | element.classList.toggle("active"); -------------------------------------------------------------------------------- /capitalizeEachWord.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Capitalize Each Word 3 | */ 4 | var capitalizeEachWord = function(string) { 5 | var splitStr = string.toLowerCase().split(' '); 6 | for (var i = 0; i < splitStr.length; i++) { 7 | splitStr[i] = splitStr[i].charAt(0).toUpperCase() + splitStr[i].substring(1); 8 | } 9 | return splitStr.join(' '); 10 | }; -------------------------------------------------------------------------------- /lazyLoadImages.js: -------------------------------------------------------------------------------- 1 | [].forEach.call(document.querySelectorAll('noscript'), function(noscript) { 2 | var img = new Image(); 3 | img.setAttribute('data-src', ''); 4 | img.parentNode.insertBefore(img, noscript); 5 | img.onload = function() { 6 | img.removeAttribute('data-src'); 7 | }; 8 | img.src = noscript.getAttribute('data-src'); 9 | }); -------------------------------------------------------------------------------- /loadSVG.js: -------------------------------------------------------------------------------- 1 | var loadSVG = function() { 2 | var ajax = new XMLHttpRequest(); 3 | ajax.open('GET', svgSymbols, true); 4 | ajax.send(); 5 | ajax.onload = function() { 6 | var div = document.createElement('div'); 7 | div.style.display = 'none'; 8 | div.innerHTML = ajax.responseText; 9 | document.body.insertBefore(div, document.body.childNodes[0]); 10 | }; 11 | }; -------------------------------------------------------------------------------- /getIndex.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Element} el 3 | * @param {string} [selector] 4 | * @return {number} 5 | */ 6 | 7 | getIndex = function(el, selector) { 8 | var i = 0; 9 | 10 | while ((el = el.previousElementSibling) !== null) { 11 | if (!selector || el.matches(selector)) { 12 | ++i; 13 | } 14 | } 15 | 16 | return i; 17 | }; -------------------------------------------------------------------------------- /once.js: -------------------------------------------------------------------------------- 1 | function once(fn, context) { 2 | var result; 3 | 4 | return function() { 5 | if(fn) { 6 | result = fn.apply(context || this, arguments); 7 | fn = null; 8 | } 9 | 10 | return result; 11 | }; 12 | } 13 | 14 | // Usage 15 | var canOnlyFireOnce = once(function() { 16 | console.log('Fired!'); 17 | }); 18 | 19 | canOnlyFireOnce(); // "Fired!" 20 | canOnlyFireOnce(); // nada -------------------------------------------------------------------------------- /prefixedEvent.js: -------------------------------------------------------------------------------- 1 | var pfx = ["webkit", "moz", "MS", "o", ""]; 2 | 3 | var prefixedEventListener = function( element, type, callback ) { 4 | for ( var p = 0; p < pfx.length; p++ ) { 5 | if ( !pfx[p] ) { 6 | type = type.toLowerCase(); 7 | } 8 | element.addEventListener( pfx[p]+type, callback, false ); 9 | } 10 | }; 11 | 12 | // Usage 13 | prefixedEvent(entry, "AnimationEnd", deleteElem); -------------------------------------------------------------------------------- /addEvent-loop.js: -------------------------------------------------------------------------------- 1 | /** 2 | * addEventListener to collection 3 | */ 4 | 5 | // Select all links 6 | var links = document.querySelectorAll("a"); 7 | 8 | // For each link element 9 | [].forEach.call(links, function(el) { 10 | 11 | // Add event listener 12 | el.addEventListener("click", function(event) { 13 | event.preventDefault(); 14 | alert("You clicked"); 15 | }, false); 16 | 17 | }); -------------------------------------------------------------------------------- /onetime.js: -------------------------------------------------------------------------------- 1 | // create a one-time event 2 | var onetime = function (node, type, callback) { 3 | 4 | // create event 5 | node.addEventListener(type, function(e) { 6 | // remove event 7 | e.target.removeEventListener(e.type, arguments.callee); 8 | // call handler 9 | return callback(e); 10 | }); 11 | 12 | }; 13 | 14 | //onetime(document.getElementById("myelement"), "click", handler); -------------------------------------------------------------------------------- /getHeight.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Get the height of an element 3 | * @param {Node} elem The element 4 | * @return {Number} The height 5 | */ 6 | var getHeight = function ( elem ) { 7 | return Math.max( elem.scrollHeight, elem.offsetHeight, elem.clientHeight ); 8 | }; 9 | 10 | var elem = document.querySelector( '#some-element' ); 11 | var height = getHeight( elem ); // Get height 12 | elem.style.height = '200px'; // Set height -------------------------------------------------------------------------------- /matchesSelector.js: -------------------------------------------------------------------------------- 1 | function matchesSelector(el, selector) { 2 | var p = Element.prototype; 3 | var f = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || function(s) { 4 | return [].indexOf.call(document.querySelectorAll(s), this) !== -1; 5 | }; 6 | return f.call(el, selector); 7 | } 8 | 9 | // Usage 10 | matchesSelector(document.getElementById('myDiv'), 'div.someSelector[some-attribute=true]') -------------------------------------------------------------------------------- /nodelist.forEach.js: -------------------------------------------------------------------------------- 1 | /** 2 | * NodeList.prototype.forEach() polyfill 3 | * https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach#Polyfill 4 | */ 5 | if (window.NodeList && !NodeList.prototype.forEach) { 6 | NodeList.prototype.forEach = function (callback, thisArg) { 7 | thisArg = thisArg || window; 8 | for (var i = 0; i < this.length; i++) { 9 | callback.call(thisArg, this[i], i, this); 10 | } 11 | }; 12 | } -------------------------------------------------------------------------------- /add-remove-class.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Various ways to add/remove classes 3 | */ 4 | 5 | // Select an element 6 | var element = document.querySelector(".some-class"); 7 | 8 | // Give class "foo" to the element 9 | element.className = "foo"; 10 | 11 | // Adding a class without replacing the current classes 12 | element.className += " foo"; 13 | 14 | // Removing "no-js" class from html-element and replacing it with "js" 15 | document.documentElement.className = "js"; -------------------------------------------------------------------------------- /requestAnimThrottle.js: -------------------------------------------------------------------------------- 1 | function throttle(action) { 2 | let isRunning = false; 3 | return function() { 4 | if (isRunning) return; 5 | isRunning = true; 6 | window.requestAnimationFrame(() => { 7 | action(); 8 | isRunning = false; 9 | }); 10 | } 11 | } 12 | 13 | //Usage 14 | 15 | window.addEventListener('scroll', throttle(() => { 16 | const scrollTop = window.scrollY; 17 | /* doSomething with scrollTop */ 18 | })); 19 | 20 | -------------------------------------------------------------------------------- /getDocumentHeight.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Get the height of the `document` element 3 | * @return {Number} The height 4 | */ 5 | var getDocumentHeight = function () { 6 | return Math.max( 7 | document.body.scrollHeight, 8 | document.documentElement.scrollHeight, 9 | document.body.offsetHeight, 10 | document.documentElement.offsetHeight, 11 | document.body.clientHeight, 12 | document.documentElement.clientHeight 13 | ); 14 | }; -------------------------------------------------------------------------------- /animationEventListener.js: -------------------------------------------------------------------------------- 1 | var pfx = ["webkit", "moz", "MS", "o", ""]; 2 | function prefixedEventListener(element, type, callback) { 3 | for (var p = 0; p < pfx.length; p++) { 4 | if (!pfx[p]) type = type.toLowerCase(); 5 | element.addEventListener(pfx[p]+type, callback, false); 6 | } 7 | } 8 | 9 | // var monkey = document.querySelector("#monkey"); 10 | // prefixedEventListener(monkey,"AnimationStart",function(e){ 11 | // console.log("log at beginning of monkey animation"); 12 | // }); -------------------------------------------------------------------------------- /getSupportedPropertyName.js: -------------------------------------------------------------------------------- 1 | var getSupportedPropertyName = function(properties) { 2 | for (var i = 0; i < properties.length; i++) { 3 | if (typeof document.body.style[properties[i]] !== 'undefined') { 4 | return properties[i]; 5 | } 6 | } 7 | return null; 8 | }; 9 | 10 | var transform = ['transform', 'msTransform', 'webkitTransform', 'mozTransform', 'oTransform']; 11 | 12 | // Usage 13 | elem.style[getSupportedPropertyName(transform)] = 'translate3d(0px,' + Math.round(wScrollCurrent * rate) + 'px, 0px)'; -------------------------------------------------------------------------------- /getNextSibling.js: -------------------------------------------------------------------------------- 1 | const getNextSibling = function (elem, selector) { 2 | 3 | // Get the next sibling element 4 | let sibling = elem.nextElementSibling; 5 | 6 | // If there's no selector, return the first sibling 7 | if (!selector) return sibling; 8 | 9 | // If the sibling matches our selector, use it 10 | // If not, jump to the next sibling and continue the loop 11 | while (sibling) { 12 | if (sibling.matches(selector)) return sibling; 13 | sibling = sibling.nextElementSibling 14 | } 15 | 16 | }; -------------------------------------------------------------------------------- /stickyElement.js: -------------------------------------------------------------------------------- 1 | var stickyElement = function(element, offsetElement, spacing) { 2 | var distanceFromTop = getElemDistance(element), 3 | offsetDistance = offsetElement.clientHeight + spacing; 4 | if ( latestKnownScrollY > (distanceFromTop - offsetDistance) ) { 5 | element.classList.add('is-sticky'); 6 | } else if (latestKnownScrollY < (distanceFromTop - offsetDistance) && element.classList.contains('is-sticky') ) { 7 | element.classList.remove('is-sticky'); 8 | } else { 9 | return; 10 | } 11 | }; -------------------------------------------------------------------------------- /getPreviousSibling.js: -------------------------------------------------------------------------------- 1 | const getPreviousSibling = function (elem, selector) { 2 | 3 | // Get the next sibling element 4 | let sibling = elem.previousElementSibling; 5 | 6 | // If there's no selector, return the first sibling 7 | if (!selector) return sibling; 8 | 9 | // If the sibling matches our selector, use it 10 | // If not, jump to the next sibling and continue the loop 11 | while (sibling) { 12 | if (sibling.matches(selector)) return sibling; 13 | sibling = sibling.previousElementSibling; 14 | } 15 | 16 | }; -------------------------------------------------------------------------------- /isInViewport.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Determine if an element is in the visible viewport 3 | */ 4 | var isInViewport = function ( elem ) { 5 | var distance = elem.getBoundingClientRect(); 6 | return ( 7 | distance.top >= 0 && 8 | distance.left >= 0 && 9 | distance.bottom <= (window.innerHeight || document.documentElement.clientHeight) && 10 | distance.right <= (window.innerWidth || document.documentElement.clientWidth) 11 | ); 12 | }; 13 | var elem = document.querySelector('#some-element'); 14 | isInViewport(elem); // Boolean: returns true/false -------------------------------------------------------------------------------- /manipulateDom.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Manipulate DOM 3 | */ 4 | 5 | // Select an element 6 | var element = document.querySelector(".class"); 7 | 8 | // Clone it 9 | var clone = element.cloneNode(true); 10 | 11 | // Do some manipulation off the DOM 12 | clone.style.background = "#000"; 13 | 14 | // Replaces the original element with the new cloned one 15 | element.parentNode.replaceChild(clone, element); 16 | 17 | // Don't replace anything in the DOM 18 | // Instead append the newly created div inside the
19 | document.body.appendChild(clone); -------------------------------------------------------------------------------- /traverse.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Traversing the DOM 3 | */ 4 | 5 | // Getting the parent node 6 | var parent = document.querySelector("div").parentNode; 7 | 8 | // Getting the next node 9 | var next = document.querySelector("div").nextSibling; 10 | 11 | // Getting the previous node 12 | var next = document.querySelector("div").previousSibling; 13 | 14 | // Getting the first child element 15 | var child = document.querySelector("div").children[0]; 16 | 17 | // Getting the last child 18 | var last = document.querySelector("div").lastElementChild; 19 | -------------------------------------------------------------------------------- /getNextUntil.js: -------------------------------------------------------------------------------- 1 | const getNextUntil = function (elem, selector) { 2 | 3 | // Setup siblings array and get next sibling 4 | var siblings = []; 5 | var next = elem.nextElementSibling; 6 | 7 | // Loop through all siblings 8 | while (next) { 9 | 10 | // If the matching item is found, quit 11 | if (selector && next.matches(selector)) break; 12 | 13 | // Otherwise, push to array 14 | siblings.push(next); 15 | 16 | // Get the next sibling 17 | next = next.nextElementSibling 18 | 19 | } 20 | 21 | return siblings; 22 | 23 | }; -------------------------------------------------------------------------------- /getPreviousUntil.js: -------------------------------------------------------------------------------- 1 | var getPreviousUntil = function (elem, selector) { 2 | 3 | // Setup siblings array and get previous sibling 4 | var siblings = []; 5 | var prev = elem.previousElementSibling; 6 | 7 | // Loop through all siblings 8 | while (prev) { 9 | 10 | // If the matching item is found, quit 11 | if (selector && prev.matches(selector)) break; 12 | 13 | // Otherwise, push to array 14 | siblings.push(prev); 15 | 16 | // Get the previous sibling 17 | prev = prev.previousElementSibling 18 | 19 | } 20 | 21 | return siblings; 22 | 23 | }; -------------------------------------------------------------------------------- /isValidEmail.js: -------------------------------------------------------------------------------- 1 | function isValidEmail(string) { 2 | string = string||''; 3 | var lastseg = (string.split('@')[1]||'').split('.')[1]||'', 4 | input = document.createElement('input'); 5 | input.type = 'email'; 6 | 7 | input.required = true; 8 | input.value = string; 9 | return !!(string && (input.validity && input.validity.valid) && lastseg.length); 10 | } 11 | 12 | console.log(isValidEmail('')); // -> false 13 | console.log(isValidEmail('asda')); // -> false 14 | console.log(isValidEmail('asda@gmail')); // -> false 15 | console.log(isValidEmail('asda@gmail.com')); // -> true -------------------------------------------------------------------------------- /getSiblings.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Get all siblings of an element 3 | * @param {Node} elem The element 4 | * @return {Array} The siblings 5 | */ 6 | var getSiblings = function ( elem ) { 7 | var siblings = []; 8 | var sibling = elem.parentNode.firstChild; 9 | for ( ; sibling; sibling = sibling.nextSibling ) { 10 | if ( sibling.nodeType === 1 && sibling !== elem ) { 11 | siblings.push( sibling ); 12 | } 13 | } 14 | return siblings; 15 | }; 16 | 17 | var elem = document.querySelector( '#some-element' ); 18 | var siblings = getSiblings( elem ); -------------------------------------------------------------------------------- /insertRule.js: -------------------------------------------------------------------------------- 1 | var sheet = (function() { 2 | // Create the '; 52 | head.appendChild(div.childNodes[1]); 53 | }; 54 | 55 | fluidvids.render = function () { 56 | var nodes = document.querySelectorAll(fluidvids.selector.join()); 57 | var i = nodes.length; 58 | while (i--) { 59 | fluid(nodes[i]); 60 | } 61 | }; 62 | 63 | fluidvids.init = function (obj) { 64 | for (var key in obj) { 65 | fluidvids[key] = obj[key]; 66 | } 67 | fluidvids.render(); 68 | addStyles(); 69 | }; 70 | 71 | return fluidvids; 72 | 73 | }); -------------------------------------------------------------------------------- /revealing-module-pattern-options.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Revealing Module Pattern with User Options Boilerplate 3 | * (c) 2017 Chris Ferdinandi, MIT License, https://gomakethings.com 4 | */ 5 | var myPlugin = (function () { 6 | 7 | 'use strict'; 8 | 9 | // 10 | // Variables 11 | // 12 | 13 | var publicAPIs = {}; 14 | var defaults = {}; 15 | var settings; 16 | 17 | 18 | // 19 | // Methods 20 | // 21 | 22 | /*! 23 | * Merge two or more objects together. 24 | * (c) 2017 Chris Ferdinandi, MIT License, https://gomakethings.com 25 | * @param {Boolean} deep If true, do a deep (or recursive) merge [optional] 26 | * @param {Object} objects The objects to merge together 27 | * @returns {Object} Merged values of defaults and options 28 | */ 29 | var extend = function () { 30 | 31 | // Variables 32 | var extended = {}; 33 | var deep = false; 34 | var i = 0; 35 | 36 | // Check if a deep merge 37 | if ( Object.prototype.toString.call( arguments[0] ) === '[object Boolean]' ) { 38 | deep = arguments[0]; 39 | i++; 40 | } 41 | 42 | // Merge the object into the extended object 43 | var merge = function (obj) { 44 | for (var prop in obj) { 45 | if (obj.hasOwnProperty(prop)) { 46 | // If property is an object, merge properties 47 | if (deep && Object.prototype.toString.call(obj[prop]) === '[object Object]') { 48 | extended[prop] = extend(extended[prop], obj[prop]); 49 | } else { 50 | extended[prop] = obj[prop]; 51 | } 52 | } 53 | } 54 | }; 55 | 56 | // Loop through each object and conduct a merge 57 | for (; i < arguments.length; i++) { 58 | var obj = arguments[i]; 59 | merge(obj); 60 | } 61 | 62 | return extended; 63 | 64 | }; 65 | 66 | /** 67 | * A private method 68 | */ 69 | var somePrivateMethod = function () { 70 | // Code goes here... 71 | }; 72 | 73 | /** 74 | * A public method 75 | */ 76 | publicAPIs.doSomething = function () { 77 | somePrivateMethod(); 78 | // Code goes here... 79 | }; 80 | 81 | /** 82 | * Another public method 83 | */ 84 | publicAPIs.init = function (options) { 85 | 86 | // Merge options into defaults 87 | settings = extend(defaults, options || {}); 88 | 89 | // Code goes here... 90 | 91 | }; 92 | 93 | 94 | // 95 | // Return the Public APIs 96 | // 97 | 98 | return publicAPIs; 99 | 100 | })(); 101 | 102 | myPlugin.init({ 103 | mayo: true, 104 | bread: 'rye', 105 | }); -------------------------------------------------------------------------------- /loadCSS.js: -------------------------------------------------------------------------------- 1 | /*! 2 | loadCSS: load a CSS file asynchronously. 3 | [c]2015 @scottjehl, Filament Group, Inc. 4 | Licensed MIT 5 | */ 6 | (function(w){ 7 | "use strict"; 8 | /* exported loadCSS */ 9 | var loadCSS = function( href, before, media ){ 10 | // Arguments explained: 11 | // `href` [REQUIRED] is the URL for your CSS file. 12 | // `before` [OPTIONAL] is the element the script should use as a reference for injecting our stylesheet before 13 | // By default, loadCSS attempts to inject the link after the last stylesheet or script in the DOM. However, you might desire a more specific location in your document. 14 | // `media` [OPTIONAL] is the media type or query of the stylesheet. By default it will be 'all' 15 | var doc = w.document; 16 | var ss = doc.createElement( "link" ); 17 | var ref; 18 | if( before ){ 19 | ref = before; 20 | } 21 | else { 22 | var refs = ( doc.body || doc.getElementsByTagName( "head" )[ 0 ] ).childNodes; 23 | ref = refs[ refs.length - 1]; 24 | } 25 | 26 | var sheets = doc.styleSheets; 27 | ss.rel = "stylesheet"; 28 | ss.href = href; 29 | // temporarily set media to something inapplicable to ensure it'll fetch without blocking render 30 | ss.media = "only x"; 31 | 32 | // Inject link 33 | // Note: the ternary preserves the existing behavior of "before" argument, but we could choose to change the argument to "after" in a later release and standardize on ref.nextSibling for all refs 34 | // Note: `insertBefore` is used instead of `appendChild`, for safety re: http://www.paulirish.com/2011/surefire-dom-element-insertion/ 35 | ref.parentNode.insertBefore( ss, ( before ? ref : ref.nextSibling ) ); 36 | // A method (exposed on return object for external use) that mimics onload by polling until document.styleSheets until it includes the new sheet. 37 | var onloadcssdefined = function( cb ){ 38 | var resolvedHref = ss.href; 39 | var i = sheets.length; 40 | while( i-- ){ 41 | if( sheets[ i ].href === resolvedHref ){ 42 | return cb(); 43 | } 44 | } 45 | setTimeout(function() { 46 | onloadcssdefined( cb ); 47 | }); 48 | }; 49 | 50 | // once loaded, set link's media back to `all` so that the stylesheet applies once it loads 51 | ss.onloadcssdefined = onloadcssdefined; 52 | onloadcssdefined(function() { 53 | ss.media = media || "all"; 54 | }); 55 | return ss; 56 | }; 57 | // commonjs 58 | if( typeof module !== "undefined" ){ 59 | module.exports = loadCSS; 60 | } 61 | else { 62 | w.loadCSS = loadCSS; 63 | } 64 | }( typeof global !== "undefined" ? global : this )); -------------------------------------------------------------------------------- /navigation.js: -------------------------------------------------------------------------------- 1 | /** 2 | * navigation.js 3 | * 4 | * Handles toggling the navigation menu for small screens and enables tab 5 | * support for dropdown menus. 6 | */ 7 | ( function() { 8 | var container, button, menu, links, subMenus; 9 | 10 | container = document.getElementById( 'site-navigation' ); 11 | if ( ! container ) { 12 | return; 13 | } 14 | 15 | button = container.getElementsByTagName( 'button' )[0]; 16 | if ( 'undefined' === typeof button ) { 17 | return; 18 | } 19 | 20 | menu = container.getElementsByTagName( 'ul' )[0]; 21 | 22 | // Hide menu toggle button if menu is empty and return early. 23 | if ( 'undefined' === typeof menu ) { 24 | button.style.display = 'none'; 25 | return; 26 | } 27 | 28 | menu.setAttribute( 'aria-expanded', 'false' ); 29 | if ( -1 === menu.className.indexOf( 'nav-menu' ) ) { 30 | menu.className += ' nav-menu'; 31 | } 32 | 33 | button.onclick = function() { 34 | if ( -1 !== container.className.indexOf( 'toggled' ) ) { 35 | container.className = container.className.replace( ' toggled', '' ); 36 | button.setAttribute( 'aria-expanded', 'false' ); 37 | menu.setAttribute( 'aria-expanded', 'false' ); 38 | } else { 39 | container.className += ' toggled'; 40 | button.setAttribute( 'aria-expanded', 'true' ); 41 | menu.setAttribute( 'aria-expanded', 'true' ); 42 | } 43 | }; 44 | 45 | // Get all the link elements within the menu. 46 | links = menu.getElementsByTagName( 'a' ); 47 | subMenus = menu.getElementsByTagName( 'ul' ); 48 | 49 | // Set menu items with submenus to aria-haspopup="true". 50 | for ( var i = 0, len = subMenus.length; i < len; i++ ) { 51 | subMenus[i].parentNode.setAttribute( 'aria-haspopup', 'true' ); 52 | } 53 | 54 | // Each time a menu link is focused or blurred, toggle focus. 55 | for ( i = 0, len = links.length; i < len; i++ ) { 56 | links[i].addEventListener( 'focus', toggleFocus, true ); 57 | links[i].addEventListener( 'blur', toggleFocus, true ); 58 | } 59 | 60 | /** 61 | * Sets or removes .focus class on an element. 62 | */ 63 | function toggleFocus() { 64 | var self = this; 65 | 66 | // Move up through the ancestors of the current link until we hit .nav-menu. 67 | while ( -1 === self.className.indexOf( 'nav-menu' ) ) { 68 | 69 | // On li elements toggle the class .focus. 70 | if ( 'li' === self.tagName.toLowerCase() ) { 71 | if ( -1 !== self.className.indexOf( 'focus' ) ) { 72 | self.className = self.className.replace( ' focus', '' ); 73 | } else { 74 | self.className += ' focus'; 75 | } 76 | } 77 | 78 | self = self.parentElement; 79 | } 80 | } 81 | } )(); 82 | -------------------------------------------------------------------------------- /revealing-module-pattern-constructor.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Revealing Module Pattern with Constructor Boilerplate 3 | * (c) 2017 Chris Ferdinandi, MIT License, https://gomakethings.com 4 | */ 5 | var myPlugin = (function () { 6 | 7 | 'use strict'; 8 | 9 | // 10 | // Shared Variables 11 | // 12 | 13 | var defaults = {}; 14 | 15 | 16 | // 17 | // Shared Methods 18 | // 19 | 20 | /*! 21 | * Merge two or more objects together. 22 | * (c) 2017 Chris Ferdinandi, MIT License, https://gomakethings.com 23 | * @param {Boolean} deep If true, do a deep (or recursive) merge [optional] 24 | * @param {Object} objects The objects to merge together 25 | * @returns {Object} Merged values of defaults and options 26 | */ 27 | var extend = function () { 28 | 29 | // Variables 30 | var extended = {}; 31 | var deep = false; 32 | var i = 0; 33 | 34 | // Check if a deep merge 35 | if ( Object.prototype.toString.call( arguments[0] ) === '[object Boolean]' ) { 36 | deep = arguments[0]; 37 | i++; 38 | } 39 | 40 | // Merge the object into the extended object 41 | var merge = function (obj) { 42 | for (var prop in obj) { 43 | if (obj.hasOwnProperty(prop)) { 44 | // If property is an object, merge properties 45 | if (deep && Object.prototype.toString.call(obj[prop]) === '[object Object]') { 46 | extended[prop] = extend(extended[prop], obj[prop]); 47 | } else { 48 | extended[prop] = obj[prop]; 49 | } 50 | } 51 | } 52 | }; 53 | 54 | // Loop through each object and conduct a merge 55 | for (; i < arguments.length; i++) { 56 | var obj = arguments[i]; 57 | merge(obj); 58 | } 59 | 60 | return extended; 61 | 62 | }; 63 | 64 | 65 | // 66 | // Constructor 67 | // Can be named anything you want 68 | // 69 | 70 | var Constructor = function (options) { 71 | 72 | // 73 | // Unique Variables 74 | // 75 | 76 | var publicAPIs = {}; 77 | var settings; 78 | 79 | 80 | // 81 | // Unique Methods 82 | // 83 | 84 | /** 85 | * A private method 86 | */ 87 | var somePrivateMethod = function () { 88 | // Code goes here... 89 | }; 90 | 91 | /** 92 | * A public method 93 | */ 94 | publicAPIs.doSomething = function () { 95 | somePrivateMethod(); 96 | // Code goes here... 97 | }; 98 | 99 | /** 100 | * Another public method 101 | */ 102 | publicAPIs.init = function (options) { 103 | 104 | // Merge options into defaults 105 | settings = extend(defaults, options || {}); 106 | 107 | // Code goes here... 108 | 109 | }; 110 | 111 | // Initialize the plugin 112 | publicAPIs.init(options); 113 | 114 | // Return the public APIs 115 | return publicAPIs; 116 | 117 | }; 118 | 119 | 120 | // 121 | // Return the constructor 122 | // 123 | 124 | return Constructor; 125 | 126 | })(); 127 | 128 | var myPluginInstance = new myPlugin({ 129 | mayo: true, 130 | bread: 'rye', 131 | }); 132 | -------------------------------------------------------------------------------- /event-polyfill.js: -------------------------------------------------------------------------------- 1 | // Polyfill event.preventDefault & event.addEventListener 2 | if (!window.addEventListener) { 3 | (function() { 4 | if (!Event.prototype.preventDefault) { 5 | Event.prototype.preventDefault=function() { 6 | this.returnValue=false; 7 | }; 8 | } 9 | if (!Event.prototype.stopPropagation) { 10 | Event.prototype.stopPropagation=function() { 11 | this.cancelBubble=true; 12 | }; 13 | } 14 | if (!Element.prototype.addEventListener) { 15 | var eventListeners=[]; 16 | var addEventListener=function(type,listener /*, useCapture (will be ignored) */) { 17 | var self=this; 18 | var wrapper=function(e) { 19 | e.target=e.srcElement; 20 | e.currentTarget=self; 21 | if (listener.handleEvent) { 22 | listener.handleEvent(e); 23 | } else { 24 | listener.call(self,e); 25 | } 26 | }; 27 | if (type=="DOMContentLoaded") { 28 | var wrapper2=function(e) { 29 | if (document.readyState=="complete") { 30 | wrapper(e); 31 | } 32 | }; 33 | document.attachEvent("onreadystatechange",wrapper2); 34 | eventListeners.push({object:this,type:type,listener:listener,wrapper:wrapper2}); 35 | if (document.readyState=="complete") { 36 | var e=new Event(); 37 | e.srcElement=window; 38 | wrapper2(e); 39 | } 40 | } else { 41 | this.attachEvent("on"+type,wrapper); 42 | eventListeners.push({object:this,type:type,listener:listener,wrapper:wrapper}); 43 | } 44 | }; 45 | var removeEventListener=function(type,listener /*, useCapture (will be ignored) */) { 46 | var counter=0; 47 | while (counter