├── .babelrc ├── .gitignore ├── .npmignore ├── LICENSE ├── .github └── workflows │ └── npmpublish.yml ├── src ├── lodash.js ├── index.js └── domEvent.js ├── package.json └── README.md /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"] 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 18 | .grunt 19 | 20 | # node-waf configuration 21 | .lock-wscript 22 | 23 | # Compiled binary addons (http://nodejs.org/api/addons.html) 24 | build/Release 25 | 26 | # Dependency directory 27 | node_modules 28 | 29 | # Optional npm cache directory 30 | .npm 31 | 32 | # Optional REPL history 33 | .node_repl_history 34 | 35 | # Bundle files 36 | samples/bundle.js 37 | 38 | **/package.json.lock -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 18 | .grunt 19 | 20 | # node-waf configuration 21 | .lock-wscript 22 | 23 | # Compiled binary addons (http://nodejs.org/api/addons.html) 24 | build/Release 25 | build 26 | 27 | # Dependency directory 28 | node_modules 29 | 30 | # Optional npm cache directory 31 | .npm 32 | 33 | # Optional REPL history 34 | .node_repl_history 35 | 36 | # Samples 37 | samples 38 | 39 | # Bundle files 40 | src 41 | 42 | # Bundle scripts 43 | gulpfile.js -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 wangpin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, 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, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/npmpublish.yml: -------------------------------------------------------------------------------- 1 | name: Node.js Package 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | - 2.0-compatible 8 | push: 9 | branches: 10 | - master 11 | - 2.0-compatible 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v1 18 | - uses: actions/setup-node@v1 19 | with: 20 | node-version: 12 21 | - run: npm install 22 | 23 | publish-npm: 24 | needs: build 25 | runs-on: ubuntu-latest 26 | steps: 27 | - uses: actions/checkout@v1 28 | - uses: actions/setup-node@v1 29 | with: 30 | node-version: 12 31 | registry-url: https://registry.npmjs.org/ 32 | - run: npm install 33 | - run: npm publish 34 | env: 35 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 36 | 37 | publish-gpr: 38 | needs: build 39 | runs-on: ubuntu-latest 40 | steps: 41 | - uses: actions/checkout@v1 42 | - uses: actions/setup-node@v1 43 | with: 44 | node-version: 12 45 | registry-url: https://npm.pkg.github.com/ 46 | scope: '@your-github-username' 47 | - run: npm publish 48 | env: 49 | NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} 50 | -------------------------------------------------------------------------------- /src/lodash.js: -------------------------------------------------------------------------------- 1 | export const debounce = (func, delay) => { 2 | let inDebounce 3 | return function() { 4 | const context = this 5 | const args = arguments 6 | clearTimeout(inDebounce) 7 | inDebounce = setTimeout(() => func.apply(context, args), delay) 8 | } 9 | } 10 | 11 | export const throttle = (func, limit) => { 12 | let lastFunc 13 | let lastRan 14 | return function() { 15 | const context = this 16 | const args = arguments 17 | if (!lastRan) { 18 | func.apply(context, args) 19 | lastRan = Date.now() 20 | } else { 21 | clearTimeout(lastFunc) 22 | lastFunc = setTimeout(function() { 23 | if (Date.now() - lastRan >= limit) { 24 | func.apply(context, args) 25 | lastRan = Date.now() 26 | } 27 | }, limit - (Date.now() - lastRan)) 28 | } 29 | } 30 | } 31 | 32 | export const isNumber = function(arg) { 33 | return typeof arg === 'number' && arg !== NaN 34 | } 35 | 36 | export const isFunction = function(arg) { 37 | return typeof arg === 'function' 38 | } 39 | 40 | export const isObject = function(arg) { 41 | return Object.prototype.toString.call(arg) === '[object Object]' 42 | } 43 | 44 | export const isInteger = function(arg) { 45 | return isNumber(arg) && Math.round(arg) === arg 46 | } 47 | 48 | export const get = function(arg, path, def) { 49 | try { 50 | return eval(`arg.${path}`) 51 | } catch (err) { 52 | // ignore error 53 | return def 54 | } 55 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-scroll", 3 | "version": "2.1.13", 4 | "description": "scroll directive for vuejs 2.0", 5 | "main": "dist/vue-scroll.common.js", 6 | "module": "dist/vue-scroll.esm.js", 7 | "unpkg": "dist/vue-scroll.js", 8 | "scripts": { 9 | "dev:dist": "rollup -wm -c build/rollup.dev.config.js", 10 | "build": "babel-node build/build.js", 11 | "prepublishOnly": "npm run build" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git@github.com:wangpin34/vue-scroll" 16 | }, 17 | "bugs": { 18 | "url": "https://github.com/wangpin34/vue-scroll/issues" 19 | }, 20 | "keywords": [ 21 | "vue", 22 | "vuejs", 23 | "directive", 24 | "scroll" 25 | ], 26 | "author": "wangpin", 27 | "license": "MIT", 28 | "peerDependencies": { 29 | "vue": "^2.1.4" 30 | }, 31 | "devDependencies": { 32 | "@babel/cli": "^7.6.4", 33 | "@babel/core": "^7.6.4", 34 | "@babel/node": "^7.6.3", 35 | "@babel/preset-env": "^7.6.3", 36 | "acorn": "^7.1.0", 37 | "rollup": "^1.26.3", 38 | "rollup-plugin-buble": "^0.19.8", 39 | "rollup-plugin-cleanup": "^3.1.1", 40 | "rollup-plugin-commonjs": "^10.1.0", 41 | "rollup-plugin-flow-no-whitespace": "^1.0.0", 42 | "rollup-plugin-node-resolve": "^5.2.0", 43 | "rollup-plugin-replace": "^2.2.0", 44 | "rollup-plugin-sizes": "^0.5.1", 45 | "rollup-plugin-strip": "^1.2.2", 46 | "uglify-js": "^3.6.7", 47 | "zlib": "^1.0.5" 48 | }, 49 | "browser": { 50 | "vue": "vue/dist/vue-scroll.min.js" 51 | }, 52 | "files": [ 53 | "dist/**" 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { isObject, isFunction } from './lodash' 2 | import dom from './domEvent' 3 | 4 | 5 | const vuescroll = new Object; 6 | 7 | vuescroll.install = function (Vue, options) { 8 | 9 | options = options || {}; 10 | const SCROLL = 'scroll'; 11 | const THROTTLE = 'throttle'; 12 | const DEBOUNCE = 'debounce'; 13 | const VALID_ARGS = [THROTTLE, DEBOUNCE]; 14 | 15 | function bindValue (el, value, arg) { 16 | let fn, opt = Object.assign({}, options); 17 | if (isObject(value) || isFunction(value)) { 18 | fn = value; 19 | 20 | if (VALID_ARGS.indexOf(arg) > -1) { 21 | fn = value.fn; 22 | if (arg === THROTTLE) { 23 | opt = { throttle: value.throttle} 24 | } else if(arg === DEBOUNCE) { 25 | opt = { debounce: value.debounce} 26 | } 27 | } 28 | 29 | try { 30 | dom.bind(el, SCROLL, fn, opt); 31 | } catch(err) { 32 | console.warn('Unexpected error happened when binding listener'); 33 | } 34 | 35 | } else { 36 | console.warn('Unexpected scroll properties'); 37 | } 38 | } 39 | 40 | function unbindValue (el, value, arg) { 41 | let fn; 42 | if (isObject(value) || isFunction(value)) { 43 | fn = value; 44 | if (VALID_ARGS.indexOf(arg) > -1) { 45 | fn = value.fn; 46 | } 47 | dom.unbind(el, SCROLL, fn); 48 | } 49 | } 50 | 51 | Vue.directive(SCROLL, { 52 | 53 | bind: function(el, binding, vnode, oldVnode) { 54 | bindValue(el, binding.value, binding.arg); 55 | }, 56 | 57 | inserted: function(el, binding) { 58 | //To do, check whether element is scrollable and give warn message when not 59 | }, 60 | 61 | update: function(el, binding) { 62 | if (binding.value === binding.oldValue) { 63 | return; 64 | } 65 | bindValue(el, binding.value, binding.arg); 66 | unbindValue(el, binding.oldValue, binding.arg); 67 | }, 68 | 69 | unbind: function(el, binding) { 70 | unbindValue(el, binding.value, binding.arg); 71 | } 72 | 73 | }) 74 | 75 | } 76 | 77 | export default vuescroll; 78 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-scroll 2 | 3 | scroll directive for [vuejs 2.0](https://vuejs.org/v2/guide/) 4 | 5 | For vue 1.x, please use vue-scroll@1.0.4. Currently its code is in master branch. 6 | 7 | [![NPM](https://nodei.co/npm/vue-scroll.png?stars&downloads)](https://nodei.co/npm/vue-scroll/) 8 | 9 | [![](https://img.shields.io/travis/wangpin34/vue-scroll.svg?style=flat-square)](https://travis-ci.org/wangpin34/vue-scroll) 10 | [![Coveralls](https://img.shields.io/coveralls/wangpin34/vue-scroll.svg?style=flat-square)](https://coveralls.io/github/wangpin34/vue-scroll) 11 | 12 | 13 | [![npm package](https://img.shields.io/npm/v/vue-scroll.svg?style=flat-square)](https://www.npmjs.org/package/vue-scroll) 14 | [![NPM downloads](http://img.shields.io/npm/dm/vue-scroll.svg?style=flat-square)](https://npmjs.org/package/vue-scroll) 15 | [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/wangpin34/vue-scroll.svg)](http://isitmaintained.com/project/wangpin34/vue-scroll "Average time to resolve an issue") 16 | 17 | ## Installation 18 | ### NPM(recommended) 19 | ``` 20 | npm install vue-scroll --save 21 | ``` 22 | ### Standalone 23 | **Standalone bundle is not support on latest v2.1.0 currently** 24 | 25 | Simple download from [releases](https://github.com/wangpin34/vue-scroll/releases) and include it in script tag. 26 | 27 | ## Get started 28 | 29 | ```javascript 30 | import Vue from 'vue' 31 | import vuescroll from 'vue-scroll' 32 | 33 | Vue.use(vuescroll) 34 | ``` 35 | 36 | Directive v-scroll then can be used in any of your Component. 37 | 38 | ```App.vue 39 | 44 | ... 45 | ``` 46 | 47 | Method onScroll receives two arguments once scroll event is fired, 48 | 49 | * e - event 50 | * position - Object contains scrolling data 51 | - scrollTop Number 52 | - scrollLeft Number 53 | 54 | ## Advanced 55 | throttle and debounce are supported since v2.1.0, you can enable it as global configurations like: 56 | 57 | ```javascript 58 | Vue.use(vuescroll, {throttle: 600}) 59 | //Or 60 | Vue.use(vuescroll, {debounce: 600}) 61 | ``` 62 | 63 | Override global configurations like 64 | 65 | ```html 66 |