/*! * Stroll v1.0.0: Scroll progress bar and anchor points * (c) 2016 Nathan Querido * MIT License * http://github.com/nfq/stroll */ (function (root, factory) { if ( typeof define === 'function' && define.amd ) { define([], factory(root)); } else if ( typeof exports === 'object' ) { module.exports = factory(root); } else { root.stroll = factory(root); } })(typeof global !== 'undefined' ? global : this.window || this.global, function (root) { //'use strict'; // // Variables // var stroll = {}; // Object for public APIs var supports = 'querySelector' in document && 'addEventListener' in root && 'classList' in document.createElement('_'); // Feature test var settings; // Default settings var defaults = { wrapper: '.progress_indicator', progress: '.progress_bar', highlight: '.progress_bar_highlight', position: 'right', section: "section", pagination: true, initClass: 'js-stroll', callback: function () {} }; // // Methods // /** * A simple forEach() implementation for Arrays, Objects and NodeLists. * @private * @author Todd Motto * @link https://github.com/toddmotto/foreach * @param {Array|Object|NodeList} collection Collection of items to iterate * @param {Function} callback Callback function for each iteration * @param {Array|Object|NodeList} scope Object/NodeList/Array that forEach is iterating over (aka `this`) */ var forEach = function ( collection, callback, scope ) { if ( Object.prototype.toString.call( collection ) === '[object Object]' ) { for ( var prop in collection ) { if ( Object.prototype.hasOwnProperty.call( collection, prop ) ) { callback.call( scope, collection[prop], prop, collection ); } } } else { for ( var i = 0, len = collection.length; i < len; i++ ) { callback.call( scope, collection[i], i, collection ); } } }; /** * Merge two or more objects. Returns a new object. * @private * @param {Boolean} deep If true, do a deep (or recursive) merge [optional] * @param {Object} objects The objects to merge together * @returns {Object} Merged values of defaults and options */ var extend = function () { // Variables var extended = {}; var deep = false; var i = 0; var length = arguments.length; // Check if a deep merge if ( Object.prototype.toString.call( arguments[0] ) === '[object Boolean]' ) { deep = arguments[0]; i++; } // Merge the object into the extended object var merge = function (obj) { for ( var prop in obj ) { if ( Object.prototype.hasOwnProperty.call( obj, prop ) ) { // If deep merge and property is an object, merge properties if ( deep && Object.prototype.toString.call(obj[prop]) === '[object Object]' ) { extended[prop] = extend( true, extended[prop], obj[prop] ); } else { extended[prop] = obj[prop]; } } } }; // Loop through each object and conduct a merge for ( ; i < length; i++ ) { var obj = arguments[i]; merge(obj); } return extended; }; /** * Create DOM elements which graphically represent the progress * @method _createElements * @private */ var _createElements = function () { var wrapper = document.querySelector( settings.wrapper ); var progress = document.querySelector( settings.progress ); var highlight = document.querySelector( settings.highlight ); progress = document.createElement('div'); highlight = document.createElement('div'); progress.classList.add( settings.progress ); highlight.classList.add( settings.highlight ); progress.appendChild( highlight ); wrapper.appendChild( progress ); // Progress bar highlight // A links // Dots // Labels }; /** Set styles on DOM elements * @method _elementStyles * @private */ var _elementStyles = function () { }; /** Section dots * @method _sectionDots * @private */ var _sectionDots = function () { var body = document.body; var sections = document.querySelectorAll( settings.section ); var item = JSON.parse(this.getAttribute('data-stroll')); paginationList = ""; // Get all sections for( var i = 0; i < sections.length; i++){ sections[i].dataset.index = i + 1; if(settings.pagination == true) { paginationList += "<li><a data-index='" + (i + 1) + "' href='#" + (item.id) + "' data-scroll><span class=\"dot\"></span><span class=\"label\">"+ (item.label) +"</span></a></li>"; } } // This should go in _createElements if(settings.pagination == true) { var pagination = document.createElement("nav"); pagination.setAttribute("class", "progress_indicator"); body.appendChild(pagination); pagination.innerHTML = paginationList; //var posTop = (document.querySelector(".onepage-pagination").offsetHeight / 2) * -1; //document.querySelector(".onepage-pagination").style.marginTop = posTop; } }; /** * Scroll method * @method _scrollMethod * @private */ var _scrollMethod = function () { var body = document.body; var highlight = document.querySelector( settings.highlight ); if (body.scrollTop) { percent = (body.scrollTop/(body.scrollHeight - document.documentElement.clientHeight))*100 + '%'; } else { percent = (window.pageYOffset/(body.scrollHeight - document.documentElement.clientHeight))*100 + '%'; } if (settings.position === 'top' || settings.position === 'bottom') { highlight.style.width = percent; } if (settings.position === 'left' || settings.position === 'right') { highlight.style.height = percent; } }; /** * Handle scroll event methods * @method _eventHandler * @private */ var _eventHandler = function ( event ) { if ( event.type === 'scroll' ) { _scrollMethod(); } }; /** * Destroy the current initialization. * @public */ stroll.destroy = function () { // If plugin isn't already initialized, stop if ( !settings ) return; document.documentElement.classList.remove( settings.initClass ); // Remove event listeners document.removeEventListener('scroll', _eventHandler, false); // Reset variables settings = null; }; /** * Initialize Stroll * @public * @param {Object} options User settings */ stroll.init = function ( options ) { // Feature test if ( !supports ) return; // Destroy any existing initializations stroll.destroy(); // Merge user options with defaults settings = extend( defaults, options || {} ); // Merge user options with defaults //_createElements(); _sectionDots(); // Add class to HTML element to activate conditional CSS document.documentElement.classList.add( settings.initClass ); // Listen for scroll events and run event handler document.addEventListener('scroll', _eventHandler, false); }; // // Public APIs // return stroll; });