├── .babelrc ├── .editorconfig ├── .gitignore ├── .rollup.js ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── index.js └── package.json /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "env", 5 | { 6 | "modules": false 7 | } 8 | ] 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_style = tab 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.md] 11 | trim_trailing_whitespace = false 12 | 13 | [{*.{json,md,yml},.*}] 14 | indent_size = 2 15 | indent_style = space 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | index.*.js 3 | index.*.mjs 4 | package-lock.json 5 | *.log* 6 | .* 7 | !.babelrc 8 | !.editorconfig 9 | !.gitignore 10 | !.rollup.js 11 | !.travis.yml 12 | -------------------------------------------------------------------------------- /.rollup.js: -------------------------------------------------------------------------------- 1 | import babel from 'rollup-plugin-babel'; 2 | 3 | export default { 4 | input: 'index.js', 5 | output: [ 6 | { file: 'index.cjs.js', format: 'cjs', strict: false }, 7 | { file: 'index.es.mjs', format: 'es', strict: false } 8 | ], 9 | plugins: [ 10 | babel({ 11 | presets: [ 12 | ['env', { 13 | modules: false, 14 | targets: { node: 6 } 15 | }] 16 | ] 17 | }) 18 | ] 19 | }; 20 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # https://docs.travis-ci.com/user/travis-lint 2 | 3 | language: node_js 4 | 5 | node_js: 6 | - 6 7 | 8 | install: 9 | - npm install --ignore-scripts 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changes to Watch Size 2 | 3 | ### 2.0.0 (June 24, 2018) 4 | 5 | - The package now exports to commonjs and es modules, rather than attaching 6 | itself to `this`. 7 | 8 | ### 1.0.0 (June 20, 2018) 9 | 10 | - Initial version 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Watch Size 2 | 3 | You want to help? You rock! Now, take a moment to be sure your contributions 4 | make sense to everyone else. 5 | 6 | ## Reporting Issues 7 | 8 | Found a problem? Want a new feature? 9 | 10 | - See if your issue or idea has [already been reported]. 11 | - Provide a [reduced test case] or a [live example]. 12 | 13 | Remember, a bug is a _demonstrable problem_ caused by _our_ code. 14 | 15 | ## Submitting Pull Requests 16 | 17 | Pull requests are the greatest contributions, so be sure they are focused in 18 | scope and avoid unrelated commits. 19 | 20 | 1. To begin; [fork this project], clone your fork, and add our upstream. 21 | ```bash 22 | # Clone your fork of the repo into the current directory 23 | git clone git@github.com:YOUR_USER/watch-size.git 24 | 25 | # Navigate to the newly cloned directory 26 | cd watch-size 27 | 28 | # Assign the original repo to a remote called "upstream" 29 | git remote add upstream git@github.com:jonathantneal/watch-size.git 30 | 31 | # Install the tools necessary for testing 32 | npm install 33 | ``` 34 | 35 | 2. Create a branch for your feature or fix: 36 | ```bash 37 | # Move into a new branch for your feature 38 | git checkout -b feature/thing 39 | ``` 40 | ```bash 41 | # Move into a new branch for your fix 42 | git checkout -b fix/something 43 | ``` 44 | 45 | 3. If your code follows our practices, then push your feature branch: 46 | ```bash 47 | # Test current code 48 | npm test 49 | ``` 50 | ```bash 51 | # Push the branch for your new feature 52 | git push origin feature/thing 53 | ``` 54 | ```bash 55 | # Or, push the branch for your update 56 | git push origin update/something 57 | ``` 58 | 59 | That’s it! Now [open a pull request] with a clear title and description. 60 | 61 | [already been reported]: issues 62 | [fork this project]: fork 63 | [live example]: https://codepen.io/pen 64 | [open a pull request]: https://help.github.com/articles/using-pull-requests/ 65 | [reduced test case]: https://css-tricks.com/reduced-test-cases/ 66 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # CC0 1.0 Universal 2 | 3 | ## Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer 6 | exclusive Copyright and Related Rights (defined below) upon the creator and 7 | subsequent owner(s) (each and all, an “owner”) of an original work of 8 | authorship and/or a database (each, a “Work”). 9 | 10 | Certain owners wish to permanently relinquish those rights to a Work for the 11 | purpose of contributing to a commons of creative, cultural and scientific works 12 | (“Commons”) that the public can reliably and without fear of later claims of 13 | infringement build upon, modify, incorporate in other works, reuse and 14 | redistribute as freely as possible in any form whatsoever and for any purposes, 15 | including without limitation commercial purposes. These owners may contribute 16 | to the Commons to promote the ideal of a free culture and the further 17 | production of creative, cultural and scientific works, or to gain reputation or 18 | greater distribution for their Work in part through the use and efforts of 19 | others. 20 | 21 | For these and/or other purposes and motivations, and without any expectation of 22 | additional consideration or compensation, the person associating CC0 with a 23 | Work (the “Affirmer”), to the extent that he or she is an owner of Copyright 24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and 25 | publicly distribute the Work under its terms, with knowledge of his or her 26 | Copyright and Related Rights in the Work and the meaning and intended legal 27 | effect of CC0 on those rights. 28 | 29 | 1. Copyright and Related Rights. A Work made available under CC0 may be 30 | protected by copyright and related or neighboring rights (“Copyright and 31 | Related Rights”). Copyright and Related Rights include, but are not limited 32 | to, the following: 33 | 1. the right to reproduce, adapt, distribute, perform, display, communicate, 34 | and translate a Work; 35 | 2. moral rights retained by the original author(s) and/or performer(s); 36 | 3. publicity and privacy rights pertaining to a person’s image or likeness 37 | depicted in a Work; 38 | 4. rights protecting against unfair competition in regards to a Work, 39 | subject to the limitations in paragraph 4(i), below; 40 | 5. rights protecting the extraction, dissemination, use and reuse of data in 41 | a Work; 42 | 6. database rights (such as those arising under Directive 96/9/EC of the 43 | European Parliament and of the Council of 11 March 1996 on the legal 44 | protection of databases, and under any national implementation thereof, 45 | including any amended or successor version of such directive); and 46 | 7. other similar, equivalent or corresponding rights throughout the world 47 | based on applicable law or treaty, and any national implementations 48 | thereof. 49 | 50 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 51 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 52 | unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright 53 | and Related Rights and associated claims and causes of action, whether now 54 | known or unknown (including existing as well as future claims and causes of 55 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 56 | duration provided by applicable law or treaty (including future time 57 | extensions), (iii) in any current or future medium and for any number of 58 | copies, and (iv) for any purpose whatsoever, including without limitation 59 | commercial, advertising or promotional purposes (the “Waiver”). Affirmer 60 | makes the Waiver for the benefit of each member of the public at large and 61 | to the detriment of Affirmer’s heirs and successors, fully intending that 62 | such Waiver shall not be subject to revocation, rescission, cancellation, 63 | termination, or any other legal or equitable action to disrupt the quiet 64 | enjoyment of the Work by the public as contemplated by Affirmer’s express 65 | Statement of Purpose. 66 | 67 | 3. Public License Fallback. Should any part of the Waiver for any reason be 68 | judged legally invalid or ineffective under applicable law, then the Waiver 69 | shall be preserved to the maximum extent permitted taking into account 70 | Affirmer’s express Statement of Purpose. In addition, to the extent the 71 | Waiver is so judged Affirmer hereby grants to each affected person a 72 | royalty-free, non transferable, non sublicensable, non exclusive, 73 | irrevocable and unconditional license to exercise Affirmer’s Copyright and 74 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 75 | maximum duration provided by applicable law or treaty (including future time 76 | extensions), (iii) in any current or future medium and for any number of 77 | copies, and (iv) for any purpose whatsoever, including without limitation 78 | commercial, advertising or promotional purposes (the “License”). The License 79 | shall be deemed effective as of the date CC0 was applied by Affirmer to the 80 | Work. Should any part of the License for any reason be judged legally 81 | invalid or ineffective under applicable law, such partial invalidity or 82 | ineffectiveness shall not invalidate the remainder of the License, and in 83 | such case Affirmer hereby affirms that he or she will not (i) exercise any 84 | of his or her remaining Copyright and Related Rights in the Work or (ii) 85 | assert any associated claims and causes of action with respect to the Work, 86 | in either case contrary to Affirmer’s express Statement of Purpose. 87 | 88 | 4. Limitations and Disclaimers. 89 | 1. No trademark or patent rights held by Affirmer are waived, abandoned, 90 | surrendered, licensed or otherwise affected by this document. 91 | 2. Affirmer offers the Work as-is and makes no representations or warranties 92 | of any kind concerning the Work, express, implied, statutory or 93 | otherwise, including without limitation warranties of title, 94 | merchantability, fitness for a particular purpose, non infringement, or 95 | the absence of latent or other defects, accuracy, or the present or 96 | absence of errors, whether or not discoverable, all to the greatest 97 | extent permissible under applicable law. 98 | 3. Affirmer disclaims responsibility for clearing rights of other persons 99 | that may apply to the Work or any use thereof, including without 100 | limitation any person’s Copyright and Related Rights in the Work. 101 | Further, Affirmer disclaims responsibility for obtaining any necessary 102 | consents, permissions or other rights required for any use of the Work. 103 | 4. Affirmer understands and acknowledges that Creative Commons is not a 104 | party to this document and has no duty or obligation with respect to this 105 | CC0 or use of the Work. 106 | 107 | For more information, please see 108 | http://creativecommons.org/publicdomain/zero/1.0/. 109 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Watch Size [PostCSS][Watch Size] 2 | 3 | [![NPM Version][npm-img]][npm-url] 4 | [![Build Status][cli-img]][cli-url] 5 | [![Support Chat][git-img]][git-url] 6 | 7 | [Watch Size] lets you watch the size changes of a DOM element using the 8 | `watchSize` function. 9 | 10 | ## Usage 11 | 12 | Add [Watch Size] to your project: 13 | 14 | ```bash 15 | npm install watch-size 16 | ``` 17 | 18 | Use `watchSize()` to rewrite your queries: 19 | 20 | ```js 21 | import watchSize from 'watch-size'; 22 | 23 | const stop = watchSize( 24 | document.querySelector('.box:nth-child(2)') 25 | ({ width, height }) => { /* callback */ } 26 | ); 27 | 28 | /* use stop() to end listening */ 29 | ``` 30 | 31 | ## How does it work? 32 | 33 | The `watchSize` function attaches hidden, over-sized DOM elements to your 34 | target with `scroll` listeners that are triggered whenever the element resizes. 35 | This allows the listener to avoid polling, and to truly respond to size changes. 36 | This technique can be used in all browsers going back to Internet Explorer 9. 37 | 38 | The entire script is about 400 bytes when minified and gzipped. 39 | 40 | [cli-img]: https://img.shields.io/travis/jonathantneal/watch-size.svg 41 | [cli-url]: https://travis-ci.org/jonathantneal/watch-size 42 | [git-img]: https://img.shields.io/badge/support-chat-blue.svg 43 | [git-url]: https://gitter.im/postcss/postcss 44 | [npm-img]: https://img.shields.io/npm/v/watch-size.svg 45 | [npm-url]: https://www.npmjs.com/package/watch-size 46 | 47 | [Watch Size]: https://github.com/jonathantneal/watch-size 48 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | export default (element, listener) => { 2 | const expand = document.createElement('_'); 3 | const shrink = expand.appendChild(document.createElement('_')); 4 | const expandChild = expand.appendChild(document.createElement('_')); 5 | const shrinkChild = shrink.appendChild(document.createElement('_')); 6 | 7 | let lastWidth, lastHeight; 8 | 9 | shrink.style.cssText = expand.style.cssText = 'height:100%;left:0;opacity:0;overflow:hidden;pointer-events:none;position:absolute;top:0;transition:0s;width:100%;z-index:-1'; 10 | shrinkChild.style.cssText = expandChild.style.cssText = 'display:block;height:100%;transition:0s;width:100%'; 11 | shrinkChild.style.width = shrinkChild.style.height = '200%'; 12 | 13 | element.appendChild(expand); 14 | 15 | test(); 16 | 17 | return stop; 18 | 19 | function test() { 20 | unbind(); 21 | 22 | const width = element.offsetWidth; 23 | const height = element.offsetHeight; 24 | 25 | if (width !== lastWidth || height !== lastHeight) { 26 | lastWidth = width; 27 | lastHeight = height; 28 | 29 | expandChild.style.width = width * 2 + 'px'; 30 | expandChild.style.height = height * 2 + 'px'; 31 | 32 | expand.scrollLeft = expand.scrollWidth; 33 | expand.scrollTop = expand.scrollHeight; 34 | shrink.scrollLeft = shrink.scrollWidth; 35 | shrink.scrollTop = shrink.scrollHeight; 36 | 37 | listener({ width, height }); 38 | } 39 | 40 | shrink.addEventListener('scroll', test); 41 | expand.addEventListener('scroll', test); 42 | } 43 | 44 | function unbind() { 45 | shrink.removeEventListener('scroll', test); 46 | expand.removeEventListener('scroll', test); 47 | } 48 | 49 | function stop() { 50 | unbind(); 51 | 52 | element.removeChild(expand); 53 | } 54 | }; 55 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "watch-size", 3 | "version": "2.0.0", 4 | "description": "Watch the size changes of a DOM element", 5 | "author": "Jonathan Neal ", 6 | "license": "CC0-1.0", 7 | "repository": "jonathantneal/watch-size", 8 | "homepage": "https://github.com/jonathantneal/watch-size#readme", 9 | "bugs": "https://github.com/jonathantneal/watch-size/issues", 10 | "main": "index.cjs.js", 11 | "module": "index.es.mjs", 12 | "files": [ 13 | "index.cjs.js", 14 | "index.es.mjs" 15 | ], 16 | "scripts": { 17 | "prepublishOnly": "npm test", 18 | "pretest": "rollup -c .rollup.js --silent", 19 | "test": "echo 'Running tests...'; npm run test:js", 20 | "test:js": "eslint *.js --cache --ignore-path .gitignore --quiet" 21 | }, 22 | "devDependencies": { 23 | "babel-core": "^6.26.3", 24 | "babel-eslint": "^8.2.6", 25 | "babel-preset-env": "^1.7.0", 26 | "eslint": "^5.2.0", 27 | "eslint-config-dev": "^2.0.0", 28 | "pre-commit": "^1.2.2", 29 | "rollup": "^0.63.4", 30 | "rollup-plugin-babel": "^3.0.7", 31 | "rollup-plugin-uglify-es": "0.0.1" 32 | }, 33 | "eslintConfig": { 34 | "extends": "dev", 35 | "parser": "babel-eslint" 36 | }, 37 | "keywords": [ 38 | "dark", 39 | "mode", 40 | "modes", 41 | "light", 42 | "interface", 43 | "css", 44 | "media", 45 | "query", 46 | "queries" 47 | ] 48 | } 49 | --------------------------------------------------------------------------------