├── .gitignore ├── bower.json ├── package.json ├── scrollify.jquery.json ├── LICENSE ├── README.md └── jquery.scrollify.js /.gitignore: -------------------------------------------------------------------------------- 1 | demo/ 2 | node_modules/ 3 | test/ 4 | npm-debug.log 5 | new/ -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Scrollify", 3 | "version": "1.0.20", 4 | "homepage": "https://github.com/lukehaas/Scrollify", 5 | "authors": [ 6 | "Luke Haas " 7 | ], 8 | "description": "A jQuery plugin that assists scrolling and smoothly snaps to sections.", 9 | "main": "jquery.scrollify.js", 10 | "moduleType": [ 11 | "globals" 12 | ], 13 | "keywords": [ 14 | "scroll", 15 | "snap" 16 | ], 17 | "license": "MIT", 18 | "ignore": [ 19 | "**/.*", 20 | "node_modules", 21 | "bower_components", 22 | "test", 23 | "tests" 24 | ], 25 | "dependencies": { 26 | "jquery": "*" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-scrollify", 3 | "version": "1.0.22", 4 | "description": "A jQuery plugin that assists scrolling and smoothly snaps to sections.", 5 | "main": "jquery.scrollify.js", 6 | "scripts": { 7 | "test": "mocha ./test/scrollify_test.js --recursive ./test" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/lukehaas/Scrollify.git" 12 | }, 13 | "keywords": [ 14 | "scroll", 15 | "jquery-plugin", 16 | "ecosystem:jquery", 17 | "snap", 18 | "page" 19 | ], 20 | "dependencies": { 21 | "jquery": ">=1.7" 22 | }, 23 | "author": "Luke Haas", 24 | "license": "MIT", 25 | "bugs": { 26 | "url": "https://github.com/lukehaas/Scrollify/issues" 27 | }, 28 | "demo": "http://projects.lukehaas.me/scrollify", 29 | "homepage": "https://github.com/lukehaas/Scrollify", 30 | "devDependencies": { 31 | "chai": "^3.5.0", 32 | "chai-jquery": "^2.0.0", 33 | "jquery": "^3.1.1", 34 | "jsdom": "^9.8.3", 35 | "mocha": "^3.1.2" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /scrollify.jquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scrollify", 3 | "title": "jQuery Scrollify", 4 | "description": "A jQuery plugin that assists scrolling and smoothly snaps to sections.", 5 | "keywords": [ 6 | "scroll", 7 | "snap" 8 | ], 9 | "version": "1.0.22", 10 | "author": { 11 | "name": "Luke Haas", 12 | "url": "http://lukehaas.me" 13 | }, 14 | "maintainers": [ 15 | { 16 | "name": "Luke Haas", 17 | "email": "", 18 | "url": "http://lukehaas.me" 19 | } 20 | ], 21 | "licenses": [ 22 | { 23 | "type": "MIT", 24 | "url": "https://github.com/lukehaas/Scrollify/blob/master/LICENSE" 25 | } 26 | ], 27 | "bugs": "https://github.com/lukehaas/Scrollify/issues", 28 | "homepage": "http://projects.lukehaas.me/scrollify", 29 | "docs": "https://github.com/lukehaas/Scrollify", 30 | "download": "https://github.com/lukehaas/Scrollify", 31 | "dependencies": { 32 | "jquery": ">=1.7" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Luke Haas 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [jQuery Scrollify](https://lukehaas.me/projects/scrollify) 2 | 3 | A jQuery plugin that assists scrolling and snaps to sections. Touch optimised. 4 | 5 | ## Demo 6 | 7 | [http://lukehaas.me/projects/scrollify](https://lukehaas.me/projects/scrollify). 8 | 9 | ## More examples 10 | 11 | [Scroll animations](https://lukehaas.me/projects/scrollify/examples/apple) 12 | 13 | [Layered scrolling](https://lukehaas.me/projects/scrollify/examples/layered-scrolling) 14 | 15 | [Pagination](https://lukehaas.me/projects/scrollify/examples/pagination) 16 | 17 | [Full page video](https://lukehaas.me/projects/scrollify/examples/full-page-video) 18 | 19 | [Header and footer](https://lukehaas.me/projects/scrollify/examples/header-footer) 20 | 21 | [Dynamic content](https://lukehaas.me/projects/scrollify/examples/dynamic-content) 22 | 23 | ## Basic setup 24 | 25 | Scrollify requires jQuery 1.7+. 26 | 27 | The most basic setup is as follows: 28 | 29 | ```html 30 | 31 | 32 | 33 | 40 | 41 | 42 |
43 |
44 | 45 | 46 | ``` 47 | 48 | ## Configuration 49 | 50 | This is the default configuration: 51 | 52 | ```javascript 53 | $.scrollify({ 54 | section : ".example-classname", 55 | sectionName : "section-name", 56 | interstitialSection : "", 57 | easing: "easeOutExpo", 58 | scrollSpeed: 1100, 59 | offset : 0, 60 | scrollbars: true, 61 | standardScrollElements: "", 62 | setHeights: true, 63 | overflowScroll: true, 64 | updateHash: true, 65 | touchScroll:true, 66 | before:function() {}, 67 | after:function() {}, 68 | afterResize:function() {}, 69 | afterRender:function() {} 70 | }); 71 | ``` 72 | 73 | ## Options 74 | 75 | `section` 76 | A CSS selector for the sections of the page. 77 | 78 | `sectionName` 79 | Scrollify lets you define a hash value for each section. This makes it possible to permalink to particular sections. This is set as a data attribute on the sections. The name of the data attribute is defined by `sectionName`. 80 | 81 | `interstitialSection` 82 | A CSS selector for non-full-height sections, such as a header and footer. 83 | 84 | `easing` 85 | Define the easing method. 86 | 87 | `offset` 88 | A distance in pixels to offset each sections position by. 89 | 90 | `scrollbars` 91 | A boolean to define whether scroll bars are visible or not. 92 | 93 | `standardScrollElements` 94 | A CSS selector for elements within sections that require standard scrolling behaviour. For example `standardScrollElements: ".map, .frame"`. 95 | 96 | `setHeights` 97 | A boolean to define whether Scrollify assigns a height to the sections. True by default. 98 | 99 | `overflowScroll` 100 | A boolean to define whether Scrollify will allow scrolling over overflowing content within sections. True by default. (This will be false if `scrollbars` is false) 101 | 102 | `updateHash` 103 | A boolean to define whether Scrollify updates the browser location hash when scrolling through sections. True by default. 104 | 105 | `touchScroll` 106 | A boolean to define whether Scrollify handles touch scroll events. True by default. 107 | 108 | `before(index, sections)` 109 | A callback that is fired before a section is scrolled to. Arguments include the index of the section and an array of all section elements. 110 | 111 | `after(index, sections)` 112 | A callback that is fired after a new section is scrolled to. Arguments include the index of the section and an array of all section elements. 113 | 114 | `afterResize()` 115 | A callback that is fired after the window is resized. 116 | 117 | `afterRender()` 118 | A callback that is fired after Scrollify's initialisation. 119 | 120 | ## Methods 121 | 122 | `$.scrollify.move("#name");` 123 | 124 | The move method can be used to scroll to a particular section. It can be passed the index of the section, or the name of the section preceded by a hash. 125 | 126 | `$.scrollify.instantMove("#name");` 127 | 128 | The instantMove method can be used to scroll to a particular section without animation. It can be passed the index of the section, or the name of the section preceded by a hash. 129 | 130 | `$.scrollify.next()` 131 | 132 | The next method can be used to scroll to a panel that immediately follows the current panel. 133 | 134 | `$.scrollify.previous()` 135 | 136 | The previous method can be used to scroll to a panel that immediately precedes the current panel. 137 | 138 | `$.scrollify.instantNext()` 139 | 140 | The instantNext method can be used to scroll to a panel that immediately follows the current panel, without animation. 141 | 142 | `$.scrollify.instantPrevious()` 143 | 144 | The instantPrevious method can be used to scroll to a panel that immediately precedes the current panel. 145 | 146 | `$.scrollify.destroy()` 147 | 148 | The destroy method removes all Scrollify events and removes set heights from the panels. 149 | 150 | `$.scrollify.update()` 151 | 152 | The update method recalculates the heights and positions of the panels. 153 | 154 | `$.scrollify.current()` 155 | 156 | The current method returns the current section as a jQuery object. 157 | 158 | `$.scrollify.currentIndex()` 159 | 160 | The currentIndex method returns the current section index, starting at 0. 161 | 162 | `$.scrollify.disable()` 163 | 164 | The disable method turns off the scroll snap behaviour so that the page scroll like normal. 165 | 166 | `$.scrollify.enable()` 167 | 168 | The enable method resumes the scroll snap behaviour after the disable method has been used. 169 | 170 | `$.scrollify.isDisabled()` 171 | 172 | The isDisabled method returns true if Scrollify is currently disabled, otherwise false. 173 | 174 | 175 | `$.scrollify.setOptions()` 176 | 177 | The setOptions method can be used to change any of the initialisation options. Just parse it an options object. 178 | 179 | ## Issues 180 | 181 | If you're working with Scrollify and having issues, please post your questions to [Stackoverflow](http://stackoverflow.com) and tag it with 'jquery-scrollify'. 182 | 183 | If you think the issue is with Scrollify itself, please check the [open issues](https://github.com/lukehaas/Scrollify/issues) to see if it has already been logged. If it hasn't, please open a ticket with a detailed description of what you're seeing and details of the device and browser version you're seeing it on. 184 | 185 | ## FAQ 186 | 187 | - Do I have to use the section element for Scrollify sections? 188 | 189 | No, Scrollify sections have no relation to the section element. Scrollify sections can be any element you want. 190 | 191 | - Can sections receive an active class when they are scrolled to? 192 | 193 | Yes, this is something you can easily implement in either the `before` or `after` callbacks (which ever suites you best). 194 | 195 | - Can Scrollify be used for horizontal scrolling? 196 | 197 | No, this is not currently supported. 198 | 199 | - Can I disable Scrollify on mobile? 200 | 201 | Yes. Scrollify works well on mobile but if you need to disable it you can use the disable method. `$.scrollify.disable()`. 202 | 203 | - Why am I not able to scroll to the bottom of a section? 204 | 205 | You must ensure that there is no collapsed content within your sections. This often happens when you have floated content within a container that isn't cleared. All content must be properly contained in order for an accurate section height to be calculated. 206 | 207 | - Why are section heights increasing on resize? 208 | 209 | This happens when your browser is running in Quirks Mode, usually as the result of an incorrect doctype. 210 | 211 | ## Setup with SectionName 212 | 213 | Scrollify appends a hash value to the URL for each section, this allows for permalinking to particular sections. To define the hash value for each section you need to set a data-attribute on your sections. This data attribute can be called anything you like. The default is "section-name", but if you'd like something else then you'll need to define it with the `sectionName` option. 214 | 215 | ```html 216 | 217 | 218 | 219 | 227 | 228 | 229 |
230 |
231 | 232 | 233 | ``` 234 | ## Installation 235 | 236 | - [bower](http://bower.io/) - bower install Scrollify 237 | - [npm](https://www.npmjs.com/) - npm install jquery-scrollify 238 | 239 | 240 | ## Browser Support 241 | 242 | ![IE](https://github.com/alrra/browser-logos/raw/master/src/archive/internet-explorer_7-8/internet-explorer_7-8_48x48.png) | ![Chrome](https://github.com/alrra/browser-logos/raw/master/src/chrome/chrome_48x48.png) | ![Firefox](https://github.com/alrra/browser-logos/raw/master/src/firefox/firefox_48x48.png) | ![Opera](https://github.com/alrra/browser-logos/raw/master/src/opera/opera_48x48.png) | ![Safari](https://github.com/alrra/browser-logos/raw/master/src/safari/safari_48x48.png) 243 | --- | --- | --- | --- | --- | 244 | IE 8+ ✔ | Chrome ✔ | Firefox ✔ | Opera ✔ | Safari ✔ | 245 | 246 | ## Acknowledgements 247 | 248 | [![Browserstack](http://lukehaas.me/projects/scrollify/images/browserstack2.png)](https://www.browserstack.com/) 249 | 250 | Special thanks to [Browserstack](https://www.browserstack.com/) for supporting Scrollify. 251 | 252 | [![RunJS](https://raw.githubusercontent.com/lukehaas/RunJS/master/docs/icon-64.png)](https://runjs.app) 253 | 254 | Also, make sure to check out [RunJS](https://runjs.app). RunJS is a JavaScript playground that evaluates your code as you type and gives instant feedback. It's ideal for prototyping ideas or trying out new libraries. 255 | 256 | ## Contributing 257 | 258 | 1. Fork it! 259 | 2. Create your feature branch: `git checkout -b my-new-feature` 260 | 3. Commit your changes: `git commit -m 'Add some feature'` 261 | 4. Push to the branch: `git push origin my-new-feature` 262 | 5. Submit a pull request :) 263 | 264 | 265 | ## License 266 | 267 | [MIT License](https://github.com/lukehaas/Scrollify/blob/master/LICENSE) 268 | 269 | Browser testing via [![lambda test](https://www.lambdatest.com/support/img/logo.svg)](https://www.lambdatest.com/) 270 | -------------------------------------------------------------------------------- /jquery.scrollify.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Scrollify 3 | * Version 1.0.22 4 | * 5 | * Requires: 6 | * - jQuery 1.7 or higher 7 | * 8 | * https://github.com/lukehaas/Scrollify 9 | * 10 | * Copyright 2016, Luke Haas 11 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | * this software and associated documentation files (the "Software"), to deal in 13 | * the Software without restriction, including without limitation the rights to 14 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | * the Software, and to permit persons to whom the Software is furnished to do so, 16 | * subject to the following conditions: 17 | * 18 | * The above copyright notice and this permission notice shall be included in all 19 | * copies or substantial portions of the Software. 20 | * 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 23 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 24 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 25 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | 28 | 29 | 30 | if touchScroll is false - update index 31 | 32 | */ 33 | (function (global,factory) { 34 | "use strict"; 35 | if (typeof define === 'function' && define.amd) { 36 | // AMD. Register as an anonymous module. 37 | define(['jquery'], function($) { 38 | return factory($, global, global.document); 39 | }); 40 | } else if (typeof module === 'object' && module.exports) { 41 | // Node/CommonJS 42 | module.exports = factory(require('jquery'), global, global.document); 43 | } else { 44 | // Browser globals 45 | factory(jQuery, global, global.document); 46 | } 47 | }(typeof window !== 'undefined' ? window : this, function ($, window, document, undefined) { 48 | "use strict"; 49 | var heights = [], 50 | names = [], 51 | elements = [], 52 | overflow = [], 53 | index = 0, 54 | currentIndex = 0, 55 | interstitialIndex = 1, 56 | hasLocation = false, 57 | timeoutId, 58 | timeoutId2, 59 | $window = $(window), 60 | portHeight, 61 | scrollable = false, 62 | locked = false, 63 | scrolled = false, 64 | manualScroll, 65 | swipeScroll, 66 | util, 67 | disabled = false, 68 | scrollSamples = [], 69 | scrollTime = new Date().getTime(), 70 | firstLoad = true, 71 | initialised = false, 72 | destination = 0, 73 | wheelEvent = 'onwheel' in document ? 'wheel' : document.onmousewheel !== undefined ? 'mousewheel' : 'DOMMouseScroll', 74 | eventListenerOptions = { passive: false }, 75 | settings = { 76 | //section should be an identifier that is the same for each section 77 | section: ".section", 78 | sectionName: "section-name", 79 | interstitialSection: "", 80 | easing: "easeOutExpo", 81 | scrollSpeed: 1100, 82 | offset: 0, 83 | scrollbars: true, 84 | target:"html,body", 85 | standardScrollElements: false, 86 | setHeights: true, 87 | overflowScroll:true, 88 | updateHash: true, 89 | touchScroll:true, 90 | before:function() {}, 91 | after:function() {}, 92 | afterResize:function() {}, 93 | afterRender:function() {} 94 | }, 95 | top = $(settings.target).scrollTop(); 96 | function getportHeight() { 97 | return (window.innerHeight + settings.offset); 98 | } 99 | function animateScroll(index,instant,callbacks,toTop) { 100 | if(currentIndex===index) { 101 | callbacks = false; 102 | } 103 | if(disabled===true) { 104 | return true; 105 | } 106 | if(names[index]) { 107 | scrollable = false; 108 | if(firstLoad===true) { 109 | firstLoad = false; 110 | settings.afterRender(); 111 | } 112 | if(callbacks) { 113 | if( typeof settings.before == 'function' && settings.before(index,elements) === false ){ 114 | return true; 115 | } 116 | } 117 | interstitialIndex = 1; 118 | destination = (!index) ? 0 : heights[index]; 119 | if(firstLoad===false && currentIndex>index && toTop===false) { 120 | //We're going backwards 121 | if(overflow[index]) { 122 | portHeight = getportHeight(); 123 | 124 | interstitialIndex = parseInt(elements[index].outerHeight()/portHeight); 125 | 126 | destination = parseInt(heights[index])+(elements[index].outerHeight()-portHeight); 127 | } 128 | } 129 | 130 | 131 | if(settings.updateHash && settings.sectionName && !(firstLoad===true && index===0)) { 132 | if(history.pushState) { 133 | try { 134 | history.replaceState(null, null, names[index]); 135 | } catch (e) { 136 | if(window.console) { 137 | console.warn("Scrollify warning: Page must be hosted to manipulate the hash value."); 138 | } 139 | } 140 | 141 | } else { 142 | window.location.hash = names[index]; 143 | } 144 | } 145 | 146 | currentIndex = index; 147 | if(instant) { 148 | $(settings.target).stop().scrollTop(destination); 149 | if(callbacks) { 150 | settings.after(index,elements); 151 | } 152 | } else { 153 | locked = true; 154 | if( $().velocity ) { 155 | $(settings.target).stop().velocity('scroll', { 156 | duration: settings.scrollSpeed, 157 | easing: settings.easing, 158 | offset: destination, 159 | mobileHA: false 160 | }); 161 | } else { 162 | $(settings.target).stop().animate({ 163 | scrollTop: destination 164 | }, settings.scrollSpeed,settings.easing); 165 | } 166 | 167 | if(window.location.hash.length && settings.sectionName && window.console) { 168 | try { 169 | if($(window.location.hash).length) { 170 | console.warn("Scrollify warning: ID matches hash value - this will cause the page to anchor."); 171 | } 172 | } catch (e) {} 173 | } 174 | $(settings.target).promise().done(function(){ 175 | locked = false; 176 | firstLoad = false; 177 | if(callbacks) { 178 | settings.after(index,elements); 179 | } 180 | }); 181 | } 182 | 183 | } 184 | } 185 | 186 | function isAccelerating(samples) { 187 | function average(num) { 188 | var sum = 0; 189 | 190 | var lastElements = samples.slice(Math.max(samples.length - num, 1)); 191 | 192 | for(var i = 0; i < lastElements.length; i++){ 193 | sum += lastElements[i]; 194 | } 195 | 196 | return Math.ceil(sum/num); 197 | } 198 | 199 | var avEnd = average(10); 200 | var avMiddle = average(70); 201 | 202 | if(avEnd >= avMiddle) { 203 | return true; 204 | } else { 205 | return false; 206 | } 207 | } 208 | var scrollify = function(options) { 209 | initialised = true; 210 | $.easing['easeOutExpo'] = function(x, t, b, c, d) { 211 | return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; 212 | }; 213 | 214 | manualScroll = { 215 | handleMousedown:function() { 216 | if(disabled===true) { 217 | return true; 218 | } 219 | scrollable = false; 220 | scrolled = false; 221 | }, 222 | handleMouseup:function() { 223 | if(disabled===true) { 224 | return true; 225 | } 226 | scrollable = true; 227 | if(scrolled) { 228 | //instant,callbacks 229 | manualScroll.calculateNearest(false,true); 230 | } 231 | }, 232 | handleScroll:function() { 233 | if(disabled===true) { 234 | return true; 235 | } 236 | if(timeoutId){ 237 | clearTimeout(timeoutId); 238 | } 239 | 240 | timeoutId = setTimeout(function(){ 241 | scrolled = true; 242 | if(scrollable===false) { 243 | return false; 244 | } 245 | scrollable = false; 246 | //instant,callbacks 247 | manualScroll.calculateNearest(false,true); 248 | }, 200); 249 | }, 250 | calculateNearest:function(instant,callbacks) { 251 | top = $(settings.target).scrollTop(); 252 | var i =1, 253 | max = heights.length, 254 | closest = 0, 255 | prev = Math.abs(heights[0] - top), 256 | diff; 257 | for(;iindex) || atTop()) { 266 | index = closest; 267 | //index, instant, callbacks, toTop 268 | animateScroll(closest,instant,callbacks,false); 269 | } 270 | }, 271 | wheelHandler:function(e) { 272 | if(disabled===true) { 273 | return true; 274 | } else if(settings.standardScrollElements) { 275 | if($(e.target).is(settings.standardScrollElements) || $(e.target).closest(settings.standardScrollElements).length) { 276 | return true; 277 | } 278 | } 279 | if(!overflow[index]) { 280 | e.preventDefault(); 281 | } 282 | var currentScrollTime = new Date().getTime(); 283 | 284 | 285 | e = e || window.event; 286 | var value; 287 | if (e.originalEvent) { 288 | value = e.originalEvent.wheelDelta || -e.originalEvent.deltaY || -e.originalEvent.detail; 289 | } else { 290 | value = e.wheelDelta || -e.deltaY || -e.detail; 291 | } 292 | var delta = Math.max(-1, Math.min(1, value)); 293 | 294 | //delta = delta || -e.originalEvent.detail / 3 || e.originalEvent.wheelDelta / 120; 295 | 296 | if(scrollSamples.length > 149){ 297 | scrollSamples.shift(); 298 | } 299 | //scrollSamples.push(Math.abs(delta*10)); 300 | scrollSamples.push(Math.abs(value)); 301 | 302 | if((currentScrollTime-scrollTime) > 200){ 303 | scrollSamples = []; 304 | } 305 | scrollTime = currentScrollTime; 306 | 307 | 308 | if(locked) { 309 | return false; 310 | } 311 | if(delta<0) { 312 | if(index0) { 326 | if(index>0) { 327 | if(atTop()) { 328 | if(isAccelerating(scrollSamples)) { 329 | e.preventDefault(); 330 | index--; 331 | locked = true; 332 | //index, instant, callbacks, toTop 333 | animateScroll(index,false,true, false); 334 | } else { 335 | return false 336 | } 337 | } 338 | } 339 | } 340 | 341 | }, 342 | keyHandler:function(e) { 343 | if(disabled===true || document.activeElement.readOnly===false) { 344 | return true; 345 | } else if(settings.standardScrollElements) { 346 | if($(e.target).is(settings.standardScrollElements) || $(e.target).closest(settings.standardScrollElements).length) { 347 | return true; 348 | } 349 | } 350 | if(locked===true) { 351 | return false; 352 | } 353 | if(e.keyCode==38 || e.keyCode==33) { 354 | if(index>0) { 355 | if(atTop()) { 356 | e.preventDefault(); 357 | index--; 358 | //index, instant, callbacks, toTop 359 | animateScroll(index,false,true,false); 360 | } 361 | } 362 | } else if(e.keyCode==40 || e.keyCode==34) { 363 | if(indexMath.abs(swipeScroll.touches.touchstart.x-swipeScroll.touches.touchmove.x))) { 425 | //if(!overflow[index]) { 426 | event.preventDefault(); 427 | //} 428 | swipeScroll.touches.direction = "y"; 429 | if((swipeScroll.options.timeStamp+swipeScroll.options.timeGap)<(new Date().getTime()) && swipeScroll.touches.touchend == false) { 430 | 431 | swipeScroll.touches.touchend = true; 432 | if (swipeScroll.touches.touchstart.y > -1) { 433 | 434 | if(Math.abs(swipeScroll.touches.touchmove.y-swipeScroll.touches.touchstart.y)>swipeScroll.options.distance) { 435 | if(swipeScroll.touches.touchstart.y < swipeScroll.touches.touchmove.y) { 436 | 437 | swipeScroll.up(); 438 | 439 | } else { 440 | swipeScroll.down(); 441 | 442 | } 443 | } 444 | } 445 | } 446 | } 447 | break; 448 | case 'touchend': 449 | if(swipeScroll.touches[event.type]===false) { 450 | swipeScroll.touches[event.type] = true; 451 | if (swipeScroll.touches.touchstart.y > -1 && swipeScroll.touches.touchmove.y > -1 && swipeScroll.touches.direction==="y") { 452 | 453 | if(Math.abs(swipeScroll.touches.touchmove.y-swipeScroll.touches.touchstart.y)>swipeScroll.options.distance) { 454 | if(swipeScroll.touches.touchstart.y < swipeScroll.touches.touchmove.y) { 455 | swipeScroll.up(); 456 | 457 | } else { 458 | swipeScroll.down(); 459 | 460 | } 461 | } 462 | swipeScroll.touches.touchstart.y = -1; 463 | swipeScroll.touches.touchstart.x = -1; 464 | swipeScroll.touches.direction = "undetermined"; 465 | } 466 | } 467 | default: 468 | break; 469 | } 470 | } 471 | } 472 | }, 473 | down: function() { 474 | 475 | if(indexinterstitialIndex) { 485 | 486 | interstitialScroll(parseInt(heights[index])+(portHeight*interstitialIndex)); 487 | interstitialIndex += 1; 488 | 489 | } else { 490 | interstitialScroll(parseInt(heights[index])+(elements[index].outerHeight()-portHeight)); 491 | } 492 | 493 | } 494 | } 495 | }, 496 | up: function() { 497 | if(index>=0) { 498 | if(atTop() && index>0) { 499 | 500 | index--; 501 | //index, instant, callbacks, toTop 502 | animateScroll(index,false,true,false); 503 | } else { 504 | 505 | if(interstitialIndex>2) { 506 | portHeight = getportHeight(); 507 | 508 | interstitialIndex -= 1; 509 | interstitialScroll(parseInt(heights[index])+(portHeight*interstitialIndex)); 510 | 511 | } else { 512 | 513 | interstitialIndex = 1; 514 | interstitialScroll(parseInt(heights[index])); 515 | } 516 | } 517 | 518 | } 519 | }, 520 | init: function() { 521 | if (document.addEventListener && settings.touchScroll) { 522 | document.addEventListener('touchstart', swipeScroll.touchHandler, eventListenerOptions); 523 | document.addEventListener('touchmove', swipeScroll.touchHandler, eventListenerOptions); 524 | document.addEventListener('touchend', swipeScroll.touchHandler, eventListenerOptions); 525 | } 526 | } 527 | }; 528 | 529 | 530 | util = { 531 | refresh:function(withCallback,scroll) { 532 | clearTimeout(timeoutId2); 533 | timeoutId2 = setTimeout(function() { 534 | //retain position 535 | sizePanels(true); 536 | //scroll, firstLoad 537 | calculatePositions(scroll,false); 538 | if(withCallback) { 539 | settings.afterResize(); 540 | } 541 | },400); 542 | }, 543 | handleUpdate:function() { 544 | //callbacks, scroll 545 | //changed from false,true to false,false 546 | util.refresh(false,false); 547 | }, 548 | handleResize:function() { 549 | //callbacks, scroll 550 | util.refresh(true,false); 551 | }, 552 | handleOrientation:function() { 553 | //callbacks, scroll 554 | util.refresh(true,true); 555 | } 556 | }; 557 | settings = $.extend(settings, options); 558 | 559 | //retain position 560 | sizePanels(false); 561 | 562 | calculatePositions(false,true); 563 | 564 | if(true===hasLocation) { 565 | //index, instant, callbacks, toTop 566 | animateScroll(index,false,true,true); 567 | } else { 568 | setTimeout(function() { 569 | //instant,callbacks 570 | manualScroll.calculateNearest(true,false); 571 | },200); 572 | } 573 | if(heights.length) { 574 | manualScroll.init(); 575 | swipeScroll.init(); 576 | 577 | $window.on("resize",util.handleResize); 578 | if (document.addEventListener) { 579 | window.addEventListener("orientationchange", util.handleOrientation, false); 580 | } 581 | } 582 | function interstitialScroll(pos) { 583 | if( $().velocity ) { 584 | $(settings.target).stop().velocity('scroll', { 585 | duration: settings.scrollSpeed, 586 | easing: settings.easing, 587 | offset: pos, 588 | mobileHA: false 589 | }); 590 | } else { 591 | $(settings.target).stop().animate({ 592 | scrollTop: pos 593 | }, settings.scrollSpeed,settings.easing); 594 | } 595 | } 596 | 597 | function sizePanels(keepPosition) { 598 | if(keepPosition) { 599 | top = $(settings.target).scrollTop(); 600 | } 601 | 602 | var selector = settings.section; 603 | overflow = []; 604 | if(settings.interstitialSection.length) { 605 | selector += "," + settings.interstitialSection; 606 | } 607 | if(settings.scrollbars===false) { 608 | settings.overflowScroll = false; 609 | } 610 | portHeight = getportHeight(); 611 | $(selector).each(function(i) { 612 | var $this = $(this); 613 | 614 | if(settings.setHeights) { 615 | if($this.is(settings.interstitialSection)) { 616 | overflow[i] = false; 617 | } else { 618 | if(($this.css("height","auto").outerHeight()0) { 659 | heights[i] = parseInt($this.offset().top) + settings.offset; 660 | } else { 661 | heights[i] = parseInt($this.offset().top); 662 | } 663 | if(settings.sectionName && $this.data(settings.sectionName)) { 664 | names[i] = "#" + $this.data(settings.sectionName).toString().replace(/ /g,"-"); 665 | } else { 666 | if($this.is(settings.interstitialSection)===false) { 667 | names[i] = "#" + (i + 1); 668 | } else { 669 | names[i] = "#"; 670 | if(i===$(selector).length-1 && i>1) { 671 | heights[i] = heights[i-1] + (parseInt($($(selector)[i-1]).outerHeight()) - parseInt($(window).height())) + parseInt($this.outerHeight()); 672 | } 673 | } 674 | } 675 | elements[i] = $this; 676 | try { 677 | if($(names[i]).length && window.console) { 678 | console.warn("Scrollify warning: Section names can't match IDs - this will cause the browser to anchor."); 679 | } 680 | } catch (e) {} 681 | 682 | if(window.location.hash===names[i]) { 683 | index = i; 684 | hasLocation = true; 685 | } 686 | 687 | }); 688 | 689 | if(true===scroll) { 690 | //index, instant, callbacks, toTop 691 | animateScroll(index,false,false,false); 692 | } 693 | } 694 | 695 | function atTop() { 696 | if(!overflow[index]) { 697 | return true; 698 | } 699 | top = $(settings.target).scrollTop(); 700 | if(top>parseInt(heights[index])) { 701 | return false; 702 | } else { 703 | return true; 704 | } 705 | } 706 | function atBottom() { 707 | if(!overflow[index]) { 708 | return true; 709 | } 710 | top = $(settings.target).scrollTop(); 711 | portHeight = getportHeight(); 712 | 713 | if(top=0;z--) { 726 | if(typeof panel === 'string') { 727 | if (names[z]===panel) { 728 | index = z; 729 | //index, instant, callbacks, toTop 730 | animateScroll(z,instant,true,true); 731 | } 732 | } else { 733 | if(z===panel) { 734 | index = z; 735 | //index, instant, callbacks, toTop 736 | animateScroll(z,instant,true,true); 737 | } 738 | } 739 | } 740 | } 741 | scrollify.move = function(panel) { 742 | if(panel===undefined) { 743 | return false; 744 | } 745 | if(typeof panel!=="number" && panel.originalEvent) { 746 | panel = $(this).attr("href"); 747 | } 748 | move(panel,false); 749 | }; 750 | scrollify.instantMove = function(panel) { 751 | if(panel===undefined) { 752 | return false; 753 | } 754 | move(panel,true); 755 | }; 756 | scrollify.next = function() { 757 | if(index0) { 765 | index -= 1; 766 | //index, instant, callbacks, toTop 767 | animateScroll(index,false,true,true); 768 | } 769 | }; 770 | scrollify.instantNext = function() { 771 | if(index0) { 779 | index -= 1; 780 | //index, instant, callbacks, toTop 781 | animateScroll(index,true,true,true); 782 | } 783 | }; 784 | scrollify.destroy = function() { 785 | if(!initialised) { 786 | return false; 787 | } 788 | if(settings.setHeights) { 789 | $(settings.section).each(function() { 790 | $(this).css("height","auto"); 791 | }); 792 | } 793 | $window.off("resize",util.handleResize); 794 | if(settings.scrollbars) { 795 | $window.off('mousedown', manualScroll.handleMousedown); 796 | $window.off('mouseup', manualScroll.handleMouseup); 797 | $window.off('scroll', manualScroll.handleScroll); 798 | } 799 | // $window.off(wheelEvent,manualScroll.wheelHandler); 800 | window.removeEventListener(wheelEvent,manualScroll.wheelHandler); 801 | $window.off('keydown', manualScroll.keyHandler); 802 | 803 | if (document.addEventListener && settings.touchScroll) { 804 | document.removeEventListener('touchstart', swipeScroll.touchHandler, eventListenerOptions); 805 | document.removeEventListener('touchmove', swipeScroll.touchHandler, eventListenerOptions); 806 | document.removeEventListener('touchend', swipeScroll.touchHandler, eventListenerOptions); 807 | } 808 | heights = []; 809 | names = []; 810 | elements = []; 811 | overflow = []; 812 | firstLoad = true; 813 | initialised = false; 814 | }; 815 | scrollify.update = function() { 816 | if(!initialised) { 817 | return false; 818 | } 819 | util.handleUpdate(); 820 | }; 821 | scrollify.current = function() { 822 | return elements[index]; 823 | }; 824 | scrollify.currentIndex = function() { 825 | return index; 826 | }; 827 | scrollify.disable = function() { 828 | disabled = true; 829 | }; 830 | scrollify.enable = function() { 831 | disabled = false; 832 | if (initialised) { 833 | //instant,callbacks 834 | manualScroll.calculateNearest(false,false); 835 | } 836 | }; 837 | scrollify.isDisabled = function() { 838 | return disabled; 839 | }; 840 | scrollify.setOptions = function(updatedOptions) { 841 | if(!initialised) { 842 | return false; 843 | } 844 | if(typeof updatedOptions === "object") { 845 | settings = $.extend(settings, updatedOptions); 846 | util.handleUpdate(); 847 | } else if(window.console) { 848 | console.warn("Scrollify warning: setOptions expects an object."); 849 | } 850 | }; 851 | $.scrollify = scrollify; 852 | return scrollify; 853 | })); 854 | --------------------------------------------------------------------------------