├── .gitignore ├── .npmignore ├── History.md ├── Makefile ├── Readme.md ├── example.html ├── index.es6 └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.js 3 | node_modules -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.es6 3 | -------------------------------------------------------------------------------- /History.md: -------------------------------------------------------------------------------- 1 | 2 | 1.0.2 / 2015-01-15 3 | ================== 4 | 5 | * Remove extraneous test code. 6 | 7 | 1.0.1 / 2015-01-15 8 | ================== 9 | 10 | * Stop DOM tree ascension at document.body (Fixes scrolling bug under some circumstances) 11 | 12 | 1.0.0 / 2015-01-15 13 | ================== 14 | 15 | * Fix npm publish loop in Makefile. 16 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Get Makefile directory name: http://stackoverflow.com/a/5982798/376773. 2 | # This is a defensive programming approach to ensure that this Makefile 3 | # works even when invoked with the `-C`/`--directory` option. 4 | THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) 5 | THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd) 6 | 7 | # BIN directory 8 | BIN := $(THIS_DIR)/node_modules/.bin 9 | NODE ?= node 10 | SIX_TO_FIVE ?= $(NODE) $(BIN)/6to5 11 | BROWSERIFY ?= $(NODE) $(BIN)/browserify 12 | 13 | ES6_FILES := $(wildcard *.es6) 14 | JS_FILES := $(wildcard *.js) 15 | 16 | COMPILED_FILES := $(ES6_FILES:.es6=.js) 17 | 18 | build: install $(COMPILED_FILES) 19 | 20 | install: node_modules 21 | 22 | example: build 23 | $(BROWSERIFY) index.js -s example -o example.js 24 | 25 | clean: $(COMPILED_FILES) 26 | rm $(COMPILED_FILES) 27 | 28 | node_modules: 29 | npm install 30 | 31 | %.js: %.es6 32 | $(SIX_TO_FIVE) -i coreAliasing $< --out-file $@ 33 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # element-scroll-to 2 | 3 | Makes sure an element is fully visible on the browser viewport, 4 | by recursively scrolling all elements that might be containing it, 5 | along with the browser window. 6 | 7 | If scrolling the entirety of the element into the viewport is not 8 | possible (e.g. it's larger than the viewport, or positioned outside 9 | of the page) a best effort is made to position it on the viewport. 10 | 11 | If the supplied element is `position: fixed` or `position: sticky`, 12 | the behavior is undefined. 13 | 14 | ## Usage 15 | 16 | ```js 17 | var scrollTo = require('element-scroll-to'); 18 | 19 | // ... 20 | 21 | scrollTo(element, options); 22 | ``` 23 | 24 | options may include: 25 | 26 | - `margin` (default 0): additional gutters around the element 27 | 28 | ## License 29 | 30 | The MIT License (MIT) 31 | 32 | Copyright (c) 2015 Automattic Inc. 33 | 34 | Permission is hereby granted, free of charge, to any person obtaining a copy 35 | of this software and associated documentation files (the "Software"), to deal 36 | in the Software without restriction, including without limitation the rights 37 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 38 | copies of the Software, and to permit persons to whom the Software is 39 | furnished to do so, subject to the following conditions: 40 | 41 | The above copyright notice and this permission notice shall be included in 42 | all copies or substantial portions of the Software. 43 | 44 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 45 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 46 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 47 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 48 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 49 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 50 | THE SOFTWARE. 51 | -------------------------------------------------------------------------------- /example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Example 5 | 6 | 18 | 35 | 36 | 37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | 46 | 47 |
48 | 49 | -------------------------------------------------------------------------------- /index.es6: -------------------------------------------------------------------------------- 1 | function scrollWrapperElements(element, options) { 2 | let elementRect = element.getBoundingClientRect(); 3 | let wrapper = element.parentNode; 4 | 5 | while (wrapper != document.body) { 6 | let wrapperRect = wrapper.getBoundingClientRect(); 7 | let margin = options.margin; 8 | let deltaX = 0, deltaY = 0; 9 | 10 | if (elementRect.top < wrapperRect.top + margin) { 11 | deltaY = elementRect.top - wrapperRect.top - margin; 12 | } else if (elementRect.bottom > wrapperRect.bottom - margin) { 13 | deltaY = elementRect.bottom - wrapperRect.bottom + margin; 14 | } 15 | if (elementRect.left < wrapperRect.left + margin) { 16 | deltaX = elementRect.left - wrapperRect.left - margin; 17 | } else if (elementRect.right > wrapperRect.right - margin) { 18 | deltaX = elementRect.right - wrapperRect.right + margin; 19 | } 20 | wrapper.scrollTop += deltaY; 21 | wrapper.scrollLeft += deltaX; 22 | wrapper = wrapper.parentNode; 23 | } 24 | 25 | return elementRect; 26 | } 27 | 28 | function scrollWindow(element, options, elementRect) { 29 | let margin = options.margin; 30 | let deltaX = 0, deltaY = 0; 31 | 32 | if (elementRect.top < 0 + margin) { 33 | deltaY = elementRect.top - margin; 34 | } else if (elementRect.bottom > window.innerHeight - margin) { 35 | deltaY = elementRect.bottom - window.innerHeight + margin; 36 | } 37 | if (elementRect.left < 0 + margin) { 38 | deltaX = elementRect.left - margin; 39 | } else if (elementRect.right > window.innerWidth - margin) { 40 | deltaX = elementRect.right - window.innerWidth + margin; 41 | } 42 | 43 | window.scrollBy(deltaX, deltaY); 44 | } 45 | 46 | function scrollTo(element, options) { 47 | options = options || {} 48 | options.margin = options.margin || 0 49 | var rect = scrollWrapperElements(element, options); 50 | scrollWindow(element, options, rect); 51 | } 52 | 53 | export default scrollTo; 54 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "element-scroll-to", 3 | "description": "Scrolls an HTML element into view", 4 | "tags": ["webmodule", "browser", "scroll", "element", "view", "viewport"], 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/webmodules/element-scroll-to.git" 8 | }, 9 | "version": "1.1.0", 10 | "dependencies": { 11 | "core-js": "0.4.4" 12 | }, 13 | "devDependencies": { 14 | "6to5": "2.12.0", 15 | "browserify": "8.1.0" 16 | }, 17 | "scripts": { 18 | "prepublish": "make build" 19 | } 20 | } 21 | --------------------------------------------------------------------------------