You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

nav-scroll-spy

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nav-scroll-spy - npm Package Compare versions

Comparing version

to
1.0.2

lib/nav-scroll-spy.js

19

gulpfile.js

@@ -12,2 +12,3 @@ 'use strict';

babelify = require('babelify'),
babel = require('gulp-babel'),
pug = require('gulp-pug'),

@@ -45,4 +46,14 @@ uglify = require('gulp-uglify');

// Lib folder with module
gulp.task('bundle-js', () => {
return gulp.src([src + 'js/nav-scroll-spy.js', src + 'js/throttle.js'])
.pipe(babel({
presets: ['es2015']
}))
.pipe(gulp.dest('./lib'))
.pipe(browserSync.stream());
});
gulp.task('bundle-js', function() {
// Demo
gulp.task('demo-js', function() {
return browserify(src + 'js/demo.js')

@@ -53,3 +64,3 @@ .transform('babelify', { presets: ['es2015', 'stage-1'] })

.pipe(buffer())
// .pipe(uglify())
.pipe(uglify())
.pipe(gulp.dest(build + 'js/'))

@@ -69,6 +80,6 @@ .pipe(browserSync.stream());

gulp.watch([src + 'pug/**/*.pug', src + 'pug/includes/*.pug'], gulp.series('pug'));
gulp.watch(src + 'js/**/*.js', gulp.series('bundle-js'));
gulp.watch(src + 'js/**/*.js', gulp.series('demo-js'));
});
// default
gulp.task('default', gulp.series(gulp.parallel('pug', 'sass', 'bundle-js'), 'watch'));
gulp.task('default', gulp.series(gulp.parallel('pug', 'sass', 'bundle-js', 'demo-js'), 'watch'));

@@ -1,338 +0,1 @@

(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
// Animation function with requestAnimationFrame()
module.exports = function animate( draw, duration ) {
let start = performance.now();
requestAnimationFrame(function animate( time ) {
let timePassed = time - start;
if (timePassed > duration) timePassed = duration;
draw(timePassed);
if (timePassed < duration) requestAnimationFrame(animate);
});
};
},{}],2:[function(require,module,exports){
let animate = require('./animate.js');
class scrollToElement {
constructor(options) {
let defaults = {
anchors: 'a[href*="#"]',
duration: 350,
offset: 0,
easing: 'easeInOut'
};
options ? this.options = Object.assign(defaults, options) : this.options = defaults;
}
setClickEvent() {
let that = this,
anchors = document.querySelectorAll(this.options.anchors);
for( let anchor of anchors ){
anchor.addEventListener('click', e=> that.clickHandler(e));
}
}
makeEaseInOut(timing, progress) {
return () => {
if (progress < 0.5) {
return timing(2 * progress) / 2;
} else {
return (2 - timing(2 * (1 - progress))) / 2;
}
};
}
timingFn(progress, startVal, displace) {
if (this.easing === 'linear') {
return (progress * displace) + startVal;
} else {
// Default animation 'easeInOut'
let easeInOut = this.makeEaseInOut((progress)=> Math.pow(progress, 2), progress);
return (easeInOut() * displace) + startVal;
}
}
clickHandler(e) {
e.preventDefault();
let el = e.target,
link = el.getAttribute('href'),
elToScroll = document.querySelector(link) || document.querySelector(`*[data-section="${link.substr(1)}"]`),
offsetTop = this.elOffsetTop(elToScroll);
// Animation
let startVal = window.pageYOffset,
endVal = offsetTop + this.options.offset,
displace = endVal - startVal,
duration = this.options.duration;
if (displace === 0) return;
animate((timePassed) => {
let progress = timePassed / duration,
newVal = this.timingFn(progress, startVal, displace);
window.scrollTo(null, newVal);
}, duration);
}
elOffsetTop(el) {
let top = 0;
while (el.parentNode) {
top += el.offsetTop;
el = el.parentNode;
}
return top;
}
init() {
this.setClickEvent();
}
}
module.exports = scrollToElement;
},{"./animate.js":1}],3:[function(require,module,exports){
'use strict';
var _scrollWindowToElement = require('scroll-window-to-element');
var _scrollWindowToElement2 = _interopRequireDefault(_scrollWindowToElement);
var _navScrollSpy = require('./nav-scroll-spy');
var _navScrollSpy2 = _interopRequireDefault(_navScrollSpy);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var quarterWindowHeight = window.innerHeight / 4;
var spy = new _navScrollSpy2.default({
offset: quarterWindowHeight
});
spy.init();
// Smooth scroll to element
var scroll = new _scrollWindowToElement2.default({
anchors: '.nav a'
});
scroll.init();
},{"./nav-scroll-spy":4,"scroll-window-to-element":2}],4:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _throttle = require('./throttle.js');
var _throttle2 = _interopRequireDefault(_throttle);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var NavScrollSpy = function () {
function NavScrollSpy(options) {
_classCallCheck(this, NavScrollSpy);
var defaults = {
offset: 0,
currentClass: 'active',
selector: 'nav a',
throttle: 100
};
options ? this.options = Object.assign(defaults, options) : this.options = defaults;
this.prevCurrentSections = [];
this.navItems = {};
}
_createClass(NavScrollSpy, [{
key: 'elOffsetTop',
value: function elOffsetTop(el) {
var top = 0;
try {
while (el.parentNode) {
top += el.offsetTop;
el = el.parentNode;
}
return top;
} catch (err) {
//#####################=> TODO
console.warn('Section missing!', err);
}
}
}, {
key: 'getElements',
value: function getElements() {
// Nav Items
var navItemsNodeList = document.querySelectorAll(this.options.selector);
// Store nav items in object with hash-keys
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = navItemsNodeList[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var item = _step.value;
this.navItems[item.hash] = item;
}
// Store Sections
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
this.sections = [];
for (var key in this.navItems) {
var section = document.querySelector(key);
this.sections.push(section);
}
}
}, {
key: 'getSectionsParams',
value: function getSectionsParams() {
var _this = this;
this.sectionsParams = [];
this.sections.forEach(function (item, i) {
var top = _this.elOffsetTop(item);
_this.sectionsParams.push({ top: top, bottom: top + item.offsetHeight, id: '#' + item.id });
});
}
}, {
key: 'setCurentMenuItems',
value: function setCurentMenuItems(sectionsInScreen) {
var _this2 = this;
// prevCurrentSections not available
if (this.prevCurrentSections.length === 0) {
// No items for cleaning and no new available
if (sectionsInScreen.length === 0) {
return;
}
// No items for cleaning and new available
else {
for (var key in sectionsInScreen) {
var id = sectionsInScreen[key].id;
this.navItems[id].parentNode.classList.add(this.options.currentClass);
}
}
}
// prevCurrentSections available
else {
// Available prevNavItems and new not available. Remove old. ( this.prevCurrentSections.length !== 0 && sectionsInScreen.length === 0 )
if (sectionsInScreen.length === 0) {
for (var _key in this.prevCurrentSections) {
var _id = this.prevCurrentSections[_key].id;
this.navItems[_id].parentNode.classList.remove(this.options.currentClass);
}
}
// Available prevNavItems and new available, compare they
else {
Object.keys(this.navItems).forEach(function (key, i) {
// Remove current class
if (_this2.prevCurrentSections[i] && !sectionsInScreen[i]) {
_this2.navItems[key].parentNode.classList.remove(_this2.options.currentClass);
}
// Add current class
if (!_this2.prevCurrentSections[i] && sectionsInScreen[i]) {
_this2.navItems[key].parentNode.classList.add(_this2.options.currentClass);
}
// Else available in both arrays and already have current class
});
}
}
// Store current sections
this.prevCurrentSections = sectionsInScreen;
}
}, {
key: 'defineCurrentSection',
value: function defineCurrentSection() {
var winScrollPos = window.pageYOffset + this.options.offset;
var sectionsInScreen = [];
this.sectionsParams.forEach(function (section, i) {
if (winScrollPos > section.top && winScrollPos < section.bottom) sectionsInScreen[i] = section;
});
this.setCurentMenuItems(sectionsInScreen);
}
}, {
key: 'setEvents',
value: function setEvents() {
// Throttling to improve performance
var throttledDefineCurrentSection = (0, _throttle2.default)(this.defineCurrentSection, this.options.throttle).bind(this),
throttledGetSectionsParams = (0, _throttle2.default)(this.getSectionsParams, this.options.throttle).bind(this);
// Scroll
window.addEventListener('scroll', function () {
return throttledDefineCurrentSection();
});
// Resize
window.addEventListener('resize', function () {
throttledGetSectionsParams();
throttledDefineCurrentSection();
});
}
}, {
key: 'init',
value: function init() {
this.getElements();
this.getSectionsParams();
this.setEvents();
}
}]);
return NavScrollSpy;
}();
exports.default = NavScrollSpy;
},{"./throttle.js":5}],5:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = throttle;
function throttle(func, ms) {
var isThrottled = false,
savedArgs = void 0,
savedThis = void 0;
function wrapper() {
if (isThrottled) {
savedArgs = arguments;
savedThis = this;
return;
}
func.apply(this, arguments);
isThrottled = true;
setTimeout(function () {
isThrottled = false;
if (savedArgs) {
wrapper.apply(savedThis, savedArgs);
savedArgs = savedThis = null;
}
}, ms);
}
return wrapper;
}
},{}]},{},[3]);
!function t(e,n,r){function i(s,a){if(!n[s]){if(!e[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(o)return o(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var f=n[s]={exports:{}};e[s][0].call(f.exports,function(t){var n=e[s][1][t];return i(n?n:t)},f,f.exports,t,e,n,r)}return n[s].exports}for(var o="function"==typeof require&&require,s=0;s<r.length;s++)i(r[s]);return i}({1:[function(t,e,n){"use strict";e.exports=function(t,e){var n=performance.now();requestAnimationFrame(function r(i){var o=i-n;o>e&&(o=e),t(o),o<e&&requestAnimationFrame(r)})}},{}],2:[function(t,e,n){"use strict";function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var i=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}(),o=t("./animate.js"),s=function(){function t(e){r(this,t);var n={anchors:'a[href*="#"]',duration:350,offset:0,easing:"easeInOut"};e?this.options=Object.assign(n,e):this.options=n}return i(t,[{key:"setClickEvent",value:function(){var t=this,e=document.querySelectorAll(this.options.anchors),n=!0,r=!1,i=void 0;try{for(var o,s=e[Symbol.iterator]();!(n=(o=s.next()).done);n=!0){var a=o.value;a.addEventListener("click",function(e){return t.clickHandler(e)})}}catch(t){r=!0,i=t}finally{try{!n&&s.return&&s.return()}finally{if(r)throw i}}}},{key:"makeEaseInOut",value:function(t,e){return function(){return e<.5?t(2*e)/2:(2-t(2*(1-e)))/2}}},{key:"timingFn",value:function(t,e,n){if("linear"===this.easing)return t*n+e;var r=this.makeEaseInOut(function(t){return Math.pow(t,2)},t);return r()*n+e}},{key:"clickHandler",value:function(t){var e=this;t.preventDefault();var n=t.target,r=n.getAttribute("href"),i=document.querySelector(r)||document.querySelector('*[data-section="'+r.substr(1)+'"]'),s=this.elOffsetTop(i),a=window.pageYOffset,u=s+this.options.offset,c=u-a,f=this.options.duration;0!==c&&o(function(t){var n=t/f,r=e.timingFn(n,a,c);window.scrollTo(null,r)},f)}},{key:"elOffsetTop",value:function(t){for(var e=0;t.parentNode;)e+=t.offsetTop,t=t.parentNode;return e}},{key:"init",value:function(){this.setClickEvent()}}]),t}();n.default=s,n.scrollToElement=s},{"./animate.js":1}],3:[function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}var i=t("scroll-window-to-element"),o=r(i),s=t("./nav-scroll-spy"),a=r(s),u=window.innerHeight/4,c=new a.default({offset:u});c.init();var f=new o.default({anchors:".nav a"});f.init()},{"./nav-scroll-spy":4,"scroll-window-to-element":2}],4:[function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var o=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}(),s=t("./throttle.js"),a=r(s),u=function(){function t(e){i(this,t);var n={offset:0,currentClass:"active",selector:'nav a[href*="#"]',throttle:100};e?this.options=Object.assign(n,e):this.options=n,this.prevCurrentSections=[],this.navItems={}}return o(t,[{key:"elOffsetTop",value:function(t){var e=0;try{for(;t.parentNode;)e+=t.offsetTop,t=t.parentNode;return e}catch(t){console.warn("Section missing!",t)}}},{key:"getElements",value:function(){var t=document.querySelectorAll(this.options.selector),e=!0,n=!1,r=void 0;try{for(var i,o=t[Symbol.iterator]();!(e=(i=o.next()).done);e=!0){var s=i.value;this.navItems[s.hash]=s}}catch(t){n=!0,r=t}finally{try{!e&&o.return&&o.return()}finally{if(n)throw r}}this.sections=[];for(var a in this.navItems){var u=document.querySelector(a);this.sections.push(u)}}},{key:"getSectionsParams",value:function(){var t=this;this.sectionsParams=[],this.sections.forEach(function(e,n){var r=t.elOffsetTop(e);t.sectionsParams.push({top:r,bottom:r+e.offsetHeight,id:"#"+e.id})})}},{key:"setCurentMenuItems",value:function(t){var e=this;if(0===this.prevCurrentSections.length){if(0===t.length)return;for(var n in t){var r=t[n].id;this.navItems[r].parentNode.classList.add(this.options.currentClass)}}else if(0===t.length)for(var i in this.prevCurrentSections){var o=this.prevCurrentSections[i].id;this.navItems[o].parentNode.classList.remove(this.options.currentClass)}else Object.keys(this.navItems).forEach(function(n,r){e.prevCurrentSections[r]&&!t[r]&&e.navItems[n].parentNode.classList.remove(e.options.currentClass),!e.prevCurrentSections[r]&&t[r]&&e.navItems[n].parentNode.classList.add(e.options.currentClass)});this.prevCurrentSections=t}},{key:"defineCurrentSection",value:function(){var t=window.pageYOffset+this.options.offset,e=[];this.sectionsParams.forEach(function(n,r){t>n.top&&t<n.bottom&&(e[r]=n)}),this.setCurentMenuItems(e)}},{key:"setEvents",value:function(){var t=(0,a.default)(this.defineCurrentSection,this.options.throttle).bind(this),e=(0,a.default)(this.getSectionsParams,this.options.throttle).bind(this);window.addEventListener("scroll",function(){return t()}),window.addEventListener("resize",function(){e(),t()})}},{key:"init",value:function(){this.getElements(),this.getSectionsParams(),this.setEvents()}}]),t}();n.default=u},{"./throttle.js":5}],5:[function(t,e,n){"use strict";function r(t,e){function n(){return r?(i=arguments,void(o=this)):(t.apply(this,arguments),r=!0,void setTimeout(function(){r=!1,i&&(n.apply(o,i),i=o=null)},e))}var r=!1,i=void 0,o=void 0;return n}Object.defineProperty(n,"__esModule",{value:!0}),n.default=r},{}]},{},[3]);
{
"name": "nav-scroll-spy",
"version": "1.0.1",
"version": "1.0.2",
"description": "Simple Scroll Spy Class",
"main": "./src/js/nav-scroll-spy.js",
"main": "./lib/nav-scroll-spy.js",
"author": "Vadim Petrov – github.com/komock",

@@ -24,3 +24,3 @@ "repository": {

"gulp-uglify": "^2.0.1",
"scroll-window-to-element": "^1.0.3",
"scroll-window-to-element": "^1.0.4",
"vinyl-buffer": "^1.0.0",

@@ -27,0 +27,0 @@ "vinyl-source-stream": "^1.1.0",

@@ -33,3 +33,3 @@ # nav-scroll-spy

| currentClass | string | 'active' | Element class for current navigation item (or items). Class will be applied to link parent. |
| selector | string (html) | 'nav a' | Selector for navigation links |
| selector | string (html) | 'nav a[href*="#"]' | Selector for navigation links |
| throttle | number | 100 | Throttling window events (scroll and resize) to improve performance |

@@ -36,0 +36,0 @@

@@ -8,3 +8,3 @@ import throttle from './throttle.js';

currentClass: 'active',
selector: 'nav a',
selector: 'nav a[href*="#"]',
throttle: 100

@@ -11,0 +11,0 @@ };