diff options
Diffstat (limited to 'uikit/static/js/core/scrollspy.js')
-rw-r--r-- | uikit/static/js/core/scrollspy.js | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/uikit/static/js/core/scrollspy.js b/uikit/static/js/core/scrollspy.js new file mode 100644 index 0000000..9b8349e --- /dev/null +++ b/uikit/static/js/core/scrollspy.js @@ -0,0 +1,208 @@ +/*! UIkit 2.21.0 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */ +(function(UI) { + + "use strict"; + + var $win = UI.$win, + $doc = UI.$doc, + scrollspies = [], + checkScrollSpy = function() { + for(var i=0; i < scrollspies.length; i++) { + window.requestAnimationFrame.apply(window, [scrollspies[i].check]); + } + }; + + UI.component('scrollspy', { + + defaults: { + "target" : false, + "cls" : "uk-scrollspy-inview", + "initcls" : "uk-scrollspy-init-inview", + "topoffset" : 0, + "leftoffset" : 0, + "repeat" : false, + "delay" : 0 + }, + + boot: function() { + + // listen to scroll and resize + $doc.on("scrolling.uk.document", checkScrollSpy); + $win.on("load resize orientationchange", UI.Utils.debounce(checkScrollSpy, 50)); + + // init code + UI.ready(function(context) { + + UI.$("[data-uk-scrollspy]", context).each(function() { + + var element = UI.$(this); + + if (!element.data("scrollspy")) { + var obj = UI.scrollspy(element, UI.Utils.options(element.attr("data-uk-scrollspy"))); + } + }); + }); + }, + + init: function() { + + var $this = this, inviewstate, initinview, togglecls = this.options.cls.split(/,/), fn = function(){ + + var elements = $this.options.target ? $this.element.find($this.options.target) : $this.element, + delayIdx = elements.length === 1 ? 1 : 0, + toggleclsIdx = 0; + + elements.each(function(idx){ + + var element = UI.$(this), + inviewstate = element.data('inviewstate'), + inview = UI.Utils.isInView(element, $this.options), + toggle = element.data('ukScrollspyCls') || togglecls[toggleclsIdx].trim(); + + if (inview && !inviewstate && !element.data('scrollspy-idle')) { + + if (!initinview) { + element.addClass($this.options.initcls); + $this.offset = element.offset(); + initinview = true; + + element.trigger("init.uk.scrollspy"); + } + + element.data('scrollspy-idle', setTimeout(function(){ + + element.addClass("uk-scrollspy-inview").toggleClass(toggle).width(); + element.trigger("inview.uk.scrollspy"); + + element.data('scrollspy-idle', false); + element.data('inviewstate', true); + + }, $this.options.delay * delayIdx)); + + delayIdx++; + } + + if (!inview && inviewstate && $this.options.repeat) { + + if (element.data('scrollspy-idle')) { + clearTimeout(element.data('scrollspy-idle')); + } + + element.removeClass("uk-scrollspy-inview").toggleClass(toggle); + element.data('inviewstate', false); + + element.trigger("outview.uk.scrollspy"); + } + + toggleclsIdx = togglecls[toggleclsIdx + 1] ? (toggleclsIdx + 1) : 0; + + }); + }; + + fn(); + + this.check = fn; + + scrollspies.push(this); + } + }); + + + var scrollspynavs = [], + checkScrollSpyNavs = function() { + for(var i=0; i < scrollspynavs.length; i++) { + window.requestAnimationFrame.apply(window, [scrollspynavs[i].check]); + } + }; + + UI.component('scrollspynav', { + + defaults: { + "cls" : 'uk-active', + "closest" : false, + "topoffset" : 0, + "leftoffset" : 0, + "smoothscroll" : false + }, + + boot: function() { + + // listen to scroll and resize + $doc.on("scrolling.uk.document", checkScrollSpyNavs); + $win.on("resize orientationchange", UI.Utils.debounce(checkScrollSpyNavs, 50)); + + // init code + UI.ready(function(context) { + + UI.$("[data-uk-scrollspy-nav]", context).each(function() { + + var element = UI.$(this); + + if (!element.data("scrollspynav")) { + var obj = UI.scrollspynav(element, UI.Utils.options(element.attr("data-uk-scrollspy-nav"))); + } + }); + }); + }, + + init: function() { + + var ids = [], + links = this.find("a[href^='#']").each(function(){ ids.push(UI.$(this).attr("href")); }), + targets = UI.$(ids.join(",")), + + clsActive = this.options.cls, + clsClosest = this.options.closest || this.options.closest; + + var $this = this, inviews, fn = function(){ + + inviews = []; + + for (var i=0 ; i < targets.length ; i++) { + if (UI.Utils.isInView(targets.eq(i), $this.options)) { + inviews.push(targets.eq(i)); + } + } + + if (inviews.length) { + + var navitems, + scrollTop = $win.scrollTop(), + target = (function(){ + for(var i=0; i< inviews.length;i++){ + if(inviews[i].offset().top >= scrollTop){ + return inviews[i]; + } + } + })(); + + if (!target) return; + + if ($this.options.closest) { + links.closest(clsClosest).removeClass(clsActive); + navitems = links.filter("a[href='#"+target.attr("id")+"']").closest(clsClosest).addClass(clsActive); + } else { + navitems = links.removeClass(clsActive).filter("a[href='#"+target.attr("id")+"']").addClass(clsActive); + } + + $this.element.trigger("inview.uk.scrollspynav", [target, navitems]); + } + }; + + if (this.options.smoothscroll && UI.smoothScroll) { + links.each(function(){ + UI.smoothScroll(this, $this.options.smoothscroll); + }); + } + + fn(); + + this.element.data("scrollspynav", this); + + this.check = fn; + scrollspynavs.push(this); + + } + }); + +})(UIkit); |