├── .gitignore ├── .travis.yml ├── README.md ├── example.js ├── index.d.ts ├── index.js ├── package.json └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | bundle.js 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '12' 4 | before_script: 5 | - export DISPLAY=:99.0; sh -e /etc/init.d/xvfb start 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # resize-event 2 | Detect resize on an element without polling or iframes 3 | 4 | [![build status](https://secure.travis-ci.org/shama/resize-event.svg)](https://travis-ci.org/shama/resize-event) 5 | [![NPM version](https://badge.fury.io/js/resize-event.svg)](https://badge.fury.io/js/resize-event) 6 | 7 | If the browser supports [`ResizeObserver`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) this will use that otherwise it will fallback to a [MutationObserver](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) 8 | to detect changes to the `style` attribute of an element and then compares the 9 | width/height to check if it has changed. 10 | 11 | A polyfill is provided for `MutationObserver` which will then use polling on really old browsers. 12 | 13 | ## usage 14 | 15 | ```js 16 | import onResize from "resize-event" 17 | 18 | // Create or select an element, must be in the DOM 19 | const element = document.createElement('div') 20 | document.body.appendChild(element) 21 | 22 | // Bind the event 23 | const observer = onResize(element, () => { 24 | console.log('element was resized', element.offsetWidth, element.offsetHeight) 25 | }) 26 | 27 | // Trigger the event 28 | element.style.width = '500px' 29 | 30 | // Later disconnect the event 31 | observer.disconnect() 32 | ``` 33 | 34 | ## install 35 | 36 | ```shell 37 | npm install resize-event --save 38 | ``` 39 | 40 | # license 41 | 42 | (c) 2020 Kyle Robinson Young. MIT License 43 | -------------------------------------------------------------------------------- /example.js: -------------------------------------------------------------------------------- 1 | var onResize = require('./index.js') 2 | var objectAssign = require('object-assign') 3 | 4 | var element = document.createElement('div') 5 | document.body.appendChild(element) 6 | 7 | objectAssign(element.style, { 8 | width: '400px', 9 | height: '400px', 10 | border: '1px solid #000', 11 | margin: '1em auto', 12 | padding: '1em', 13 | 'text-align': 'center', 14 | 'font-family': 'Helvetica, sans-serif' 15 | }) 16 | 17 | onResize(element, function () { 18 | element.textContent = 'Resized to ' + element.offsetWidth + 'px / ' + element.offsetHeight + 'px' 19 | }) 20 | 21 | setInterval(function () { 22 | if (Math.random() > .5) { 23 | element.style.width = Math.random() * 500 + 'px' 24 | } else { 25 | element.style.height = Math.random() * 500 + 'px' 26 | } 27 | }, 100) 28 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | declare module "resize-event" { 2 | export default function onresize( 3 | target: HTMLElement, 4 | callback: (entries?: ResizeObserverEntry[]) => void 5 | ); 6 | } 7 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | require('mutationobserver-shim') 2 | var win 3 | if (typeof window !== 'undefined') { 4 | win = window 5 | } else if (typeof global !== 'undefined') { 6 | win = global 7 | } else if (typeof self !== 'undefined') { 8 | win = self 9 | } else { 10 | win = {} 11 | } 12 | var onresize = ('ResizeObserver' in win) ? resizeObserverOnResize : mutationObserverOnResize 13 | module.exports = onresize 14 | onresize.default = onresize 15 | function mutationObserverOnResize (target, callback) { 16 | function makeid (el) { 17 | return [target.style.width, target.style.height, target.clientWidth, target.clientHeight].join('') 18 | } 19 | var last = makeid(target) 20 | var observer = new MutationObserver(function (mutations) { 21 | for (var i = 0; i < mutations.length; i++) { 22 | var mutation = mutations[i] 23 | if (mutation.attributeName !== 'style') continue 24 | var now = makeid(target) 25 | if (now !== last) { 26 | last = now 27 | callback() 28 | break 29 | } 30 | } 31 | }) 32 | observer.observe(target, { 33 | attributes: true, 34 | childList: false, 35 | characterData: false 36 | }) 37 | return observer 38 | } 39 | function resizeObserverOnResize (target, callback) { 40 | var observer = new ResizeObserver(callback) 41 | observer.observe(target) 42 | return observer 43 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "resize-event", 3 | "version": "2.0.1", 4 | "description": "Detect resize on an element without polling or iframes", 5 | "main": "index.js", 6 | "types": "index.d.ts", 7 | "scripts": { 8 | "start": "budo example.js", 9 | "test": "budo test.js" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+ssh://git@github.com/shama/resize-event.git" 14 | }, 15 | "keywords": [ 16 | "resize", 17 | "event", 18 | "element" 19 | ], 20 | "author": "Kyle Robinson Young (http://dontkry.com)", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/shama/resize-event/issues" 24 | }, 25 | "homepage": "https://github.com/shama/resize-event#readme", 26 | "devDependencies": { 27 | "browserify": "^16.5.1", 28 | "budo": "^11.6.3", 29 | "object-assign": "^4.1.1", 30 | "tape": "^5.0.1" 31 | }, 32 | "dependencies": { 33 | "mutationobserver-shim": "^0.3.5" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var onResize = require('./index.js') 2 | var test = require('tape') 3 | var objectAssign = require('object-assign') 4 | 5 | test('got resize event', function (t) { 6 | t.plan(1) 7 | var expected = parseInt(Math.random() * 1000, 10) + 'px' 8 | var div = document.createElement('div') 9 | document.body.appendChild(div) 10 | onResize(div, function () { 11 | t.equal(div.style.width, expected, 'triggered on width change') 12 | t.end() 13 | }) 14 | div.style.width = expected 15 | }) 16 | 17 | test('with center positioned element', function (t) { 18 | t.plan(1) 19 | var expected = parseInt(Math.random() * 1000, 10) + 'px' 20 | var div = document.createElement('div') 21 | objectAssign(div.style, { 22 | position: 'relative', 23 | width: '50em', 24 | height: '20em', 25 | top: '50%', 26 | left: '50%', 27 | padding: '3em', 28 | 'margin-left': '-25em', 29 | 'margin-top': '-10em', 30 | overflow: 'hidden', 31 | 'transition-duration': '3s' 32 | }) 33 | document.body.appendChild(div) 34 | onResize(div, function () { 35 | t.equal(div.style.width, expected, 'triggered on width change') 36 | t.end() 37 | }) 38 | div.style.width = expected 39 | }) 40 | --------------------------------------------------------------------------------