├── .gitignore ├── README.md ├── index.js ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vsbl 2 | In-viewport detection without event listeners. **440 bytes gzipped.** 3 | 4 | ## Install 5 | ``` 6 | npm i vsbl --save 7 | ``` 8 | 9 | # Usage 10 | ```javascript 11 | import vsbl from 'vsbl' 12 | 13 | const enter = () => {} 14 | const exit = () => {} 15 | 16 | const listener = vsbl(document.getElementById('scroll'))(enter, exit) 17 | 18 | listener() // destroy 19 | ``` 20 | 21 | ## Options 22 | ### `threshold` 23 | Trigger visibility sooner or later than usual. 24 | - Values below `0.5` will be treated as a percentage of the viewport 25 | - Values of `0.5` and over will be considered pixel values 26 | 27 | ```javascript 28 | const listener = vsbl(node, { threshold: 0.25 })(() => console.log('visible')) 29 | ``` 30 | 31 | You can optionally include this threshold as an attribute on the element itself: 32 | ```html 33 |
34 | ``` 35 | 36 | ## License 37 | MIT License © [Eric Bailey](https://estrattonbailey.com) 38 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import srraf from 'srraf' 2 | 3 | export default function vsbl (node, opts = {}) { 4 | return function handlers (enter, exit) { 5 | let visible = false 6 | 7 | const threshold = parseFloat(node.getAttribute('data-threshold') || opts.threshold || 0) 8 | 9 | return srraf((...args) => { 10 | const [ { y, vh }, timestamp ] = args 11 | 12 | const bounds = node.getBoundingClientRect() 13 | const nodeTop = bounds.top + y 14 | const nodeBot = nodeTop + bounds.height 15 | const offset = threshold >= 0.5 ? threshold : threshold * vh // allow pixel vals 16 | 17 | const iv = nodeBot - offset >= y && nodeTop + offset <= y + vh 18 | 19 | if (iv && !visible) { 20 | visible = true 21 | enter && enter(...args) 22 | } else if (!iv && visible) { 23 | visible = false 24 | exit && exit(...args) 25 | } 26 | }) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vsbl", 3 | "version": "1.3.3", 4 | "description": "In-viewport detection without event listeners.", 5 | "source": "index.js", 6 | "module": "dist/vsbl.es.js", 7 | "jsnext:main": "dist/vsbl.es.js", 8 | "main": "dist/vsbl.js", 9 | "umd:main": "dist/vsbl.umd.js", 10 | "files": [ 11 | "dist" 12 | ], 13 | "scripts": { 14 | "build": "microbundle build", 15 | "watch": "microbundle watch --compress false", 16 | "publish": "npm publish" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "git+ssh://git@github.com/estrattonbailey/vsbl.git" 21 | }, 22 | "author": "estrattonbailey", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/estrattonbailey/vsbl/issues" 26 | }, 27 | "homepage": "https://github.com/estrattonbailey/vsbl#readme", 28 | "devDependencies": { 29 | "microbundle": "^0.11.0" 30 | }, 31 | "dependencies": { 32 | "srraf": "^3.1.4" 33 | } 34 | } 35 | --------------------------------------------------------------------------------