├── .editorconfig ├── .github └── workflows │ └── tests.yml ├── .gitignore ├── API.md ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── bower.json ├── component.json ├── composer.json ├── example └── index.html ├── jquery.once.d.ts ├── jquery.once.js ├── jquery.once.min.js ├── jquery.once.min.js.map ├── once.jquery.json ├── package.json └── test └── test.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig 2 | # http://editorconfig.org 3 | root = true 4 | 5 | [*] 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | indent_style = space 11 | indent_size = 2 12 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: tests 2 | 3 | on: 4 | pull_request: 5 | paths-ignore: 6 | - '**.md' 7 | push: 8 | branches: 9 | - master 10 | paths-ignore: 11 | - '**.md' 12 | 13 | jobs: 14 | testing: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v2 18 | - uses: actions/setup-node@v1 19 | with: 20 | node-version: '18' 21 | - run: npm install 22 | - run: npm test 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Gitignore 2 | # https://git-scm.com/docs/gitignore 3 | 4 | # Log files 5 | **/*.log 6 | 7 | # Vendor packages 8 | /components 9 | /bower_components 10 | /node_modules 11 | /vendor 12 | /composer.lock 13 | /package-lock.json 14 | 15 | # Code coverage with Istanbul 16 | /coverage 17 | /.nyc_output 18 | -------------------------------------------------------------------------------- /API.md: -------------------------------------------------------------------------------- 1 | ## Functions 2 | 3 |
4 |
once([id])jQuery
5 |

Filter elements that have yet to be processed by the given data ID.

6 |
7 |
removeOnce([id])jQuery
8 |

Removes the once data from elements, based on the given ID.

9 |
10 |
findOnce([id])jQuery
11 |

Filters elements that have already been processed once.

12 |
13 |
14 | 15 | 16 | 17 | ## once([id]) ⇒ jQuery 18 | Filter elements that have yet to be processed by the given data ID. 19 | 20 | **Kind**: global function 21 | **Returns**: jQuery - jQuery collection of elements that have now run once by 22 | the given ID. 23 | **this**: jQuery 24 | **Access**: public 25 | **See** 26 | 27 | - removeOnce 28 | - findOnce 29 | 30 | 31 | | Param | Type | Default | Description | 32 | | --- | --- | --- | --- | 33 | | [id] | string | "once" | The data ID used to determine whether the given elements have already been processed or not. Defaults to `'once'`. | 34 | 35 | **Example** 36 | ``` javascript 37 | // The following will change the color of each paragraph to red, just once 38 | // for the 'changecolor' key. 39 | $('p').once('changecolor').css('color', 'red'); 40 | 41 | // .once() will return a set of elements that yet to have the once ID 42 | // associated with them. You can return to the original collection set by 43 | // using .end(). 44 | $('p') 45 | .once('changecolorblue') 46 | .css('color', 'blue') 47 | .end() 48 | .css('color', 'red'); 49 | 50 | // To execute a function on the once set, you can use jQuery's each(). 51 | $('div.calendar').once().each(function () { 52 | // Since there is no once ID provided here, the key will be 'once'. 53 | }); 54 | ``` 55 | 56 | 57 | ## removeOnce([id]) ⇒ jQuery 58 | Removes the once data from elements, based on the given ID. 59 | 60 | **Kind**: global function 61 | **Returns**: jQuery - jQuery collection of elements that were acted upon to remove their 62 | once data. 63 | **this**: jQuery 64 | **Access**: public 65 | **See**: once 66 | 67 | | Param | Type | Default | Description | 68 | | --- | --- | --- | --- | 69 | | [id] | string | "once" | A string representing the name of the data ID which should be used when filtering the elements. This only filters elements that have already been processed by the once function. The ID should be the same ID that was originally passed to the once() function. Defaults to `'once'`. | 70 | 71 | **Example** 72 | ``` javascript 73 | // Remove once data with the 'changecolor' ID. The result set is the 74 | // elements that had their once data removed. 75 | $('p').removeOnce('changecolor').css('color', ''); 76 | 77 | // Any jQuery function can be performed on the result set. 78 | $('div.calendar').removeOnce().each(function () { 79 | // Remove the calendar behavior. 80 | }); 81 | ``` 82 | 83 | 84 | ## findOnce([id]) ⇒ jQuery 85 | Filters elements that have already been processed once. 86 | 87 | **Kind**: global function 88 | **Returns**: jQuery - jQuery collection of elements that have been run once. 89 | **this**: jQuery 90 | **Access**: public 91 | **See**: once 92 | 93 | | Param | Type | Default | Description | 94 | | --- | --- | --- | --- | 95 | | [id] | string | "once" | A string representing the name of the data id which should be used when filtering the elements. This only filters elements that have already been processed by the once function. The id should be the same id that was originally passed to the once() function. Defaults to 'once'. | 96 | 97 | **Example** 98 | ``` javascript 99 | // Find all elements that have been changecolor'ed once. 100 | $('p').findOnce('changecolor').each(function () { 101 | // This function is called for all elements that has already once'd. 102 | }); 103 | 104 | // Find all elements that have been acted on with the default 'once' key. 105 | $('p').findOnce().each(function () { 106 | // This function is called for all elements that have been acted on with 107 | // a 'once' action. 108 | }); 109 | ``` 110 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. 3 | This project adheres to [Semantic Versioning](http://semver.org/). 4 | 5 | ## [2.3.0] - January 4th, 2024 6 | ### Changed 7 | - Switched from `var` to `let` and `const` for variable scope 8 | - Removed `use strict` directives 9 | - Updated developer dependencies 10 | - Minor updates to developer documentation 11 | - Switched to GitHub Actions for testing 12 | 13 | ## [2.2.3] - May 14th, 2019 14 | ### Fixed 15 | - Fix CommonJS factory when export element is present 16 | - By [Sam152](https://github.com/Sam152) from [#91](https://github.com/RobLoach/jquery-once/issues/91) 17 | 18 | ## [2.2.2] - May 8th, 2019 19 | ### Changed 20 | - Updated developer dependencies and documenation 21 | 22 | ## [2.2.1] - March 29th, 2018 23 | ### Changed 24 | - Updated dependencies 25 | 26 | ## [2.2.0] - June 15th, 2017 27 | ### Fixed 28 | - Fixed throwing `Error` to `TypeError` when passing an incorrect `string` parameter 29 | 30 | ### Changed 31 | - Updated dependencies 32 | - Added [TypeScript](http://www.typescriptlang.org/) definition 33 | - By [olavorn](https://github.com/olavorn) 34 | 35 | ## [2.1.2] - June 11th, 2016 36 | ### Changed 37 | - Updated development dependencies 38 | - Updated documentation 39 | - Switched from [`semistandard`](http://npm.im/semistandard) to [`xo`](http://npm.im/xo) for coding standards 40 | - Tested in [jQuery 3.0](https://blog.jquery.com/2016/06/09/jquery-3-0-final-released/) 41 | 42 | ## [2.1.1] - August 31st, 2015 43 | ### Fixed 44 | - Corrected version information in the source 45 | 46 | ## [2.1.0] - August 31st, 2015 47 | ### Changed 48 | - Switched to [Keep a CHANGELOG](http://keepachangelog.com) in CHANGELOG.md 49 | - Moved to [JavaScript Semi-Standard Coding Style](http://npm.im/semistandard) 50 | - Updated development dependencies 51 | 52 | ## [2.0.2] - June 5th, 2015 53 | ### Added 54 | - Added code coverage 55 | - Added [jsDelivr CDN](http://www.jsdelivr.com/#!jquery-once) automated support 56 | - Added [cdnjs](https://github.com/cdnjs/cdnjs) automated support 57 | 58 | ## [2.0.1] - May 5th, 2015 59 | ### Changed 60 | - Updated development dependencies 61 | - Updated documentation 62 | 63 | ## [2.0.0] - January 20th, 2015 64 | ### Fixed 65 | - Fixed type checking of the `id` parameter of `.once()` as optional 66 | - From [@theodoreb](http://github.com/theodoreb) 67 | - Fixed inline code documentation 68 | - From [@yched](http://github.com/yched) 69 | 70 | ### Added 71 | - Added performance improvement through [`.data()`](http://api.jquery.com/data/) 72 | use rather than class attributes 73 | - Added `findOnce()` function to allow filtering once'd elements 74 | - Added automated testing through [Mocha](http://mochajs.org) 75 | - Added [jsdoc-to-markdown](https://github.com/75lb/jsdoc-to-markdown) to 76 | automatically build API documentation 77 | 78 | ### Changed 79 | - Switched to [ESLint](http://eslint.org) for code linting 80 | - Removed unneeded cache variable 81 | - Removed function callback in order to promote jQuery chaining standards 82 | 83 | ## [1.2.6] - August 31, 2013 84 | ### Changed 85 | - Fixed Bower 86 | - Updated documentation 87 | 88 | ## [1.2.4] - June 13, 2013 89 | ### Added 90 | - Added jquery.once.min.js to the file meta data 91 | - Added removeOnce() test 92 | 93 | ### Changed 94 | - Don't limit jQuery.once usage to jQuery 1.8. 95 | - Updated documentation 96 | 97 | ## [1.2.3] - June 13, 2013 98 | ### Added 99 | - Added tests 100 | - Fixed documentation 101 | 102 | ## [1.2.1] - May 18, 2013 103 | ### Added 104 | - Added UMD support 105 | - Added Bower support 106 | 107 | ## [1.2.0] - April 5, 2013 108 | ### Added 109 | - Added jQuery Once 110 | 111 | [unreleased]: https://github.com/RobLoach/jquery-once/compare/2.2.3...HEAD 112 | [2.2.3]: https://github.com/RobLoach/jquery-once/compare/2.2.2...2.2.3 113 | [2.2.2]: https://github.com/RobLoach/jquery-once/compare/2.2.1...2.2.2 114 | [2.2.1]: https://github.com/RobLoach/jquery-once/compare/2.2.0...2.2.1 115 | [2.2.0]: https://github.com/RobLoach/jquery-once/compare/2.1.2...2.2.0 116 | [2.1.2]: https://github.com/RobLoach/jquery-once/compare/2.1.1...2.1.2 117 | [2.1.1]: https://github.com/RobLoach/jquery-once/compare/2.1.0...2.1.1 118 | [2.1.0]: https://github.com/RobLoach/jquery-once/compare/2.0.2...2.1.0 119 | [2.0.2]: https://github.com/RobLoach/jquery-once/compare/2.0.1...2.0.2 120 | [2.0.1]: https://github.com/RobLoach/jquery-once/compare/2.0.0...2.0.1 121 | [2.0.0]: https://github.com/RobLoach/jquery-once/compare/1.2.6...2.0.0 122 | [1.2.6]: https://github.com/RobLoach/jquery-once/compare/1.2.4...1.2.6 123 | [1.2.4]: https://github.com/RobLoach/jquery-once/compare/1.2.3...1.2.4 124 | [1.2.3]: https://github.com/RobLoach/jquery-once/compare/1.2.1...1.2.3 125 | [1.2.1]: https://github.com/RobLoach/jquery-once/compare/1.2.0...1.2.1 126 | [1.2.0]: https://github.com/RobLoach/jquery-once/compare/7db530a0bd48f249c5f0df4fab02e93444623889...1.2.0 127 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # License 2 | 3 | Copyright © 2016-2024 [Rob Loach](http://github.com/RobLoach) 4 | 5 | ## GPL-2.0 6 | 7 | > [GPL-2.0](http://opensource.org/licenses/gpl-2.0.php) 8 | 9 | ## The MIT License 10 | 11 | > Permission is hereby granted, free of charge, to any person obtaining a copy 12 | > of this software and associated documentation files (the "Software"), to deal 13 | > in the Software without restriction, including without limitation the rights 14 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | > copies of the Software, and to permit persons to whom the Software is 16 | > furnished to do so, subject to the following conditions: 17 | > 18 | > The above copyright notice and this permission notice shall be included in 19 | > all copies or substantial portions of the Software. 20 | > 21 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 | > SOFTWARE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jQuery Once [![NPM version](https://img.shields.io/npm/v/jquery-once.svg)](https://npmjs.org/package/jquery-once "View this project on NPM") 2 | 3 | ![Testing](https://github.com/RobLoach/jquery-once/workflows/tests/badge.svg) 4 | [![NPM downloads](https://img.shields.io/npm/dm/jquery-once.svg)](https://npmjs.org/package/jquery-once "View this project on NPM") 5 | 6 | > Act on [jQuery](http://jquery.com) elements only once. 7 | 8 | Filters out all elements that had the same filter applied on them before. It 9 | can be used to ensure that a function is only applied once to an element. 10 | 11 | ## Install 12 | 13 | Method | Installation 14 | ------ | ------------ 15 | [npm](http://npmjs.com/package/jquery-once) | `npm install jquery-once --save` 16 | [Composer](https://packagist.org/packages/robloach/jquery-once) | `composer require robloach/jquery-once` 17 | [Bower](http://bower.io/search/?q=jquery-once) | `bower install jquery-once` 18 | [Component](https://github.com/componentjs/component) | `component install RobLoach/jquery-once` 19 | [jsDelivr](http://www.jsdelivr.com/#!jquery.once) | `//cdn.jsdelivr.net/npm/jquery-once@2.3.0/jquery.once.min.js` 20 | [cdnjs](https://cdnjs.com/libraries/jquery-once) | `//cdnjs.cloudflare.com/ajax/libs/jquery-once/2.3.0/jquery.once.js` 21 | 22 | ## Usage 23 | 24 | [See the API documentation for more information on how to use jQuery Once.](https://github.com/RobLoach/jquery-once/blob/master/API.md#readme) 25 | 26 | ``` javascript 27 | // The following will change the color of each paragraph to red, just once 28 | // for the "changecolor" key. 29 | $('p').once('changecolor').css('color', 'red'); 30 | 31 | // .once() will return a set of elements that yet to have the once ID 32 | // associated with them. You can return to the original collection set by 33 | // using .end(). 34 | $('p') 35 | .once("changecolorblue") 36 | .css("color", "blue") 37 | .end() 38 | .css("color", "red"); 39 | 40 | // To execute a function on the once set, you can use jQuery's each(). 41 | $('div.calendar').once().each(function() { 42 | // Since there is no once ID provided here, the key will be "once". 43 | }); 44 | ``` 45 | 46 | ## Development 47 | 48 | 1. Ensure you are using [node](http://nodejs.org) >= 4: 49 | ``` 50 | node --version 51 | ``` 52 | 53 | 2. Install dependencies through [npm](http://npmjs.org): 54 | ``` 55 | npm install 56 | ``` 57 | 58 | 3. Check coding style standard, and automated testing: 59 | ``` 60 | npm test 61 | ``` 62 | 63 | 4. Build `jquery.once.min.js` with: 64 | ``` 65 | npm run build 66 | ``` 67 | 68 | 5. Update API documentation: 69 | ``` 70 | npm run docs 71 | ``` 72 | 73 | 6. Tag and publish the new versions to [npm](http://npmjs.com) with [Semantic 74 | Versioning](http://semver.org/): 75 | ``` 76 | git add -A 77 | git commit -m "2.3.0" 78 | git tag 2.3.0 79 | git push origin 2.3.0 80 | npm publish 81 | ``` 82 | 83 | ## Change Log 84 | 85 | [Discover the change history by heading on over to the `CHANGELOG.md` file.](CHANGELOG.md) 86 | 87 | ## License 88 | 89 | Dual licensed under: 90 | 91 | - [GPL-2.0](http://opensource.org/licenses/gpl-2.0.php) 92 | - the incredibly [permissive](http://en.wikipedia.org/wiki/Permissive_free_software_licence) [MIT license](http://opensource.org/licenses/MIT) 93 | 94 | Copyright © [Rob Loach](http://github.com/RobLoach) 95 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-once", 3 | "homepage": "http://github.com/robloach/jquery-once", 4 | "description": "Act on jQuery elements only once.", 5 | "license": "GPL-2.0", 6 | "main": "jquery.once.js", 7 | "ignore": [ 8 | "*.json", 9 | "test", 10 | "example", 11 | ".travis.yml", 12 | ".gitignore", 13 | "Gruntfile.js" 14 | ], 15 | "keywords": [ 16 | "jquery", 17 | "jquery-plugin" 18 | ], 19 | "dependencies": { 20 | "jquery": "*" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-once", 3 | "repo": "robloach/jquery-once", 4 | "homepage": "http://github.com/robloach/jquery-once", 5 | "description": "Act on jQuery elements only once.", 6 | "license": "GPL-2.0", 7 | "version": "2.3.0", 8 | "keywords": [ 9 | "jquery", 10 | "jquery-plugin" 11 | ], 12 | "dependencies": { 13 | "components/jquery": "*" 14 | }, 15 | "main": "jquery.once.js", 16 | "scripts": [ 17 | "jquery.once.js" 18 | ], 19 | "files": [ 20 | "jquery.once.js" 21 | ], 22 | "demo": "http://github.com/robloach/jquery-once" 23 | } 24 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "jQuery Once", 3 | "name": "robloach/jquery-once", 4 | "description": "Act on jQuery elements only once.", 5 | "homepage": "http://github.com/robloach/jquery-once", 6 | "type": "component", 7 | "license": [ 8 | "MIT", 9 | "GPL-2.0" 10 | ], 11 | "require": { 12 | "components/jquery": "*" 13 | }, 14 | "extra": { 15 | "component": { 16 | "scripts": [ 17 | "jquery.once.js" 18 | ], 19 | "files": [ 20 | "jquery.once.min.js", 21 | "jquery.once.min.js.map" 22 | ], 23 | "shim": { 24 | "deps": ["jquery"] 25 | } 26 | } 27 | }, 28 | "archive": { 29 | "exclude": [ 30 | ".*", 31 | "*", 32 | "!jquery.once*", 33 | "!README.md", 34 | "!LICENSE.md", 35 | "!composer.json" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |

jQuery Once

9 |

This is some text, which should stay green.

10 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /jquery.once.d.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Once v2.3.0 Typescript Definition - http://github.com/robloach/jquery-once 3 | * @license MIT, GPL-2.0 4 | * http://opensource.org/licenses/MIT 5 | * http://opensource.org/licenses/GPL-2.0 6 | * Author: Olavo Rocha Neto (github: olavorn) 7 | */ 8 | 9 | /// 10 | 11 | interface JQuery { 12 | 13 | /** 14 | * Filter elements that have yet to be processed by the given data ID. 15 | * 16 | * @param {string} [id=once] 17 | * The data ID used to determine whether the given elements have already 18 | * been processed or not. Defaults to `'once'`. 19 | * 20 | * @returns jQuery collection of elements that have now run once by 21 | * the given ID. 22 | * 23 | * @example 24 | * ``` javascript 25 | * // The following will change the color of each paragraph to red, just once 26 | * // for the 'changecolor' key. 27 | * $('p').once('changecolor').css('color', 'red'); 28 | * 29 | * // .once() will return a set of elements that yet to have the once ID 30 | * // associated with them. You can return to the original collection set by 31 | * // using .end(). 32 | * $('p') 33 | * .once('changecolorblue') 34 | * .css('color', 'blue') 35 | * .end() 36 | * .css('color', 'red'); 37 | * 38 | * // To execute a function on the once set, you can use jQuery's each(). 39 | * $('div.calendar').once().each(function () { 40 | * // Since there is no once ID provided here, the key will be 'once'. 41 | * }); 42 | * ``` 43 | * 44 | * @see removeOnce 45 | * @see findOnce 46 | * @this jQuery 47 | * 48 | * @global 49 | * @public 50 | */ 51 | once(id?: string): JQuery; 52 | 53 | /** 54 | * Removes the once data from elements, based on the given ID. 55 | * 56 | * @param {string} [id=once] 57 | * A string representing the name of the data ID which should be used when 58 | * filtering the elements. This only filters elements that have already been 59 | * processed by the once function. The ID should be the same ID that was 60 | * originally passed to the once() function. Defaults to `'once'`. 61 | * 62 | * @returns jQuery collection of elements that were acted upon to remove their 63 | * once data. 64 | * 65 | * @example 66 | * ``` javascript 67 | * // Remove once data with the 'changecolor' ID. The result set is the 68 | * // elements that had their once data removed. 69 | * $('p').removeOnce('changecolor').css('color', ''); 70 | * 71 | * // Any jQuery function can be performed on the result set. 72 | * $('div.calendar').removeOnce().each(function () { 73 | * // Remove the calendar behavior. 74 | * }); 75 | * ``` 76 | * 77 | * @see once 78 | * @this jQuery 79 | * 80 | * @global 81 | * @public 82 | */ 83 | removeOnce(id: string): JQuery; 84 | 85 | /** 86 | * Filters elements that have already been processed once. 87 | * 88 | * @param {string} [id=once] 89 | * A string representing the name of the data id which should be used when 90 | * filtering the elements. This only filters elements that have already 91 | * been processed by the once function. The id should be the same id that 92 | * was originally passed to the once() function. Defaults to 'once'. 93 | * 94 | * @returns jQuery collection of elements that have been run once. 95 | * 96 | * @example 97 | * ``` javascript 98 | * // Find all elements that have been changecolor'ed once. 99 | * $('p').findOnce('changecolor').each(function () { 100 | * // This function is called for all elements that has already once'd. 101 | * }); 102 | * 103 | * // Find all elements that have been acted on with the default 'once' key. 104 | * $('p').findOnce().each(function () { 105 | * // This function is called for all elements that have been acted on with 106 | * // a 'once' action. 107 | * }); 108 | * ``` 109 | * 110 | * @see once 111 | * @this jQuery 112 | * 113 | * @global 114 | * @public 115 | */ 116 | findOnce(id: string): JQuery; 117 | } 118 | 119 | 120 | -------------------------------------------------------------------------------- /jquery.once.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Once v2.3.0 - http://github.com/robloach/jquery-once 3 | * @license MIT, GPL-2.0 4 | * http://opensource.org/licenses/MIT 5 | * http://opensource.org/licenses/GPL-2.0 6 | */ 7 | 8 | /** 9 | * jQuery Once: Universal Module Definition 10 | * 11 | * jQuery Once has a dependency on jQuery, so we wrap the code with a UMD 12 | * pattern in order to allow loading jQuery and jQuery Once through a module 13 | * definition like CommonJS, AMD, or through a global object. 14 | * 15 | * @see {@link http://github.com/umdjs/umd} 16 | */ 17 | (function (factory) { 18 | if (typeof exports === 'object' && typeof exports.nodeName !== 'string') { 19 | // CommonJS 20 | factory(require('jquery')); 21 | } else if (typeof define === 'function' && define.amd) { 22 | // AMD 23 | /* globals define */ 24 | define(['jquery'], factory); 25 | } else { 26 | // Global object 27 | /* globals jQuery */ 28 | factory(jQuery); 29 | } 30 | })($ => { 31 | /** 32 | * Ensures that the given ID is valid, returning 'once' if one is not given. 33 | * 34 | * @param {string} [id=once] 35 | * A string representing the ID to check. Defaults to `'once'`. 36 | * 37 | * @returns {string} The valid ID name. 38 | * 39 | * @throws TypeError when an ID is provided, but not a string. 40 | * @private 41 | */ 42 | const checkId = function (id = 'once') { 43 | if (typeof id !== 'string') { 44 | throw new TypeError('The jQuery Once id parameter must be a string'); 45 | } 46 | 47 | return id; 48 | }; 49 | 50 | /** 51 | * Filter elements that have yet to be processed by the given data ID. 52 | * 53 | * @param {string} [id=once] 54 | * The data ID used to determine whether the given elements have already 55 | * been processed or not. Defaults to `'once'`. 56 | * 57 | * @returns {jQuery} jQuery collection of elements that have now run once by 58 | * the given ID. 59 | * 60 | * @example 61 | * ``` javascript 62 | * // The following will change the color of each paragraph to red, just once 63 | * // for the 'changecolor' key. 64 | * $('p').once('changecolor').css('color', 'red'); 65 | * 66 | * // .once() will return a set of elements that yet to have the once ID 67 | * // associated with them. You can return to the original collection set by 68 | * // using .end(). 69 | * $('p') 70 | * .once('changecolorblue') 71 | * .css('color', 'blue') 72 | * .end() 73 | * .css('color', 'red'); 74 | * 75 | * // To execute a function on the once set, you can use jQuery's each(). 76 | * $('div.calendar').once().each(function () { 77 | * // Since there is no once ID provided here, the key will be 'once'. 78 | * }); 79 | * ``` 80 | * 81 | * @see removeOnce 82 | * @see findOnce 83 | * @this jQuery 84 | * 85 | * @global 86 | * @public 87 | */ 88 | $.fn.once = function (id) { 89 | // Build the jQuery Once data name from the provided ID. 90 | const name = 'jquery-once-' + checkId(id); 91 | 92 | // Find elements that don't have the jQuery Once data applied to them yet. 93 | return this.filter(function () { 94 | return $(this).data(name) !== true; 95 | }).data(name, true); 96 | }; 97 | 98 | /** 99 | * Removes the once data from elements, based on the given ID. 100 | * 101 | * @param {string} [id=once] 102 | * A string representing the name of the data ID which should be used when 103 | * filtering the elements. This only filters elements that have already been 104 | * processed by the once function. The ID should be the same ID that was 105 | * originally passed to the once() function. Defaults to `'once'`. 106 | * 107 | * @returns {jQuery} jQuery collection of elements that were acted upon to remove their 108 | * once data. 109 | * 110 | * @example 111 | * ``` javascript 112 | * // Remove once data with the 'changecolor' ID. The result set is the 113 | * // elements that had their once data removed. 114 | * $('p').removeOnce('changecolor').css('color', ''); 115 | * 116 | * // Any jQuery function can be performed on the result set. 117 | * $('div.calendar').removeOnce().each(function () { 118 | * // Remove the calendar behavior. 119 | * }); 120 | * ``` 121 | * 122 | * @see once 123 | * @this jQuery 124 | * 125 | * @global 126 | * @public 127 | */ 128 | $.fn.removeOnce = function (id) { 129 | // Filter through the elements to find the once'd elements. 130 | return this.findOnce(id).removeData('jquery-once-' + checkId(id)); 131 | }; 132 | 133 | /** 134 | * Filters elements that have already been processed once. 135 | * 136 | * @param {string} [id=once] 137 | * A string representing the name of the data id which should be used when 138 | * filtering the elements. This only filters elements that have already 139 | * been processed by the once function. The id should be the same id that 140 | * was originally passed to the once() function. Defaults to 'once'. 141 | * 142 | * @returns {jQuery} jQuery collection of elements that have been run once. 143 | * 144 | * @example 145 | * ``` javascript 146 | * // Find all elements that have been changecolor'ed once. 147 | * $('p').findOnce('changecolor').each(function () { 148 | * // This function is called for all elements that has already once'd. 149 | * }); 150 | * 151 | * // Find all elements that have been acted on with the default 'once' key. 152 | * $('p').findOnce().each(function () { 153 | * // This function is called for all elements that have been acted on with 154 | * // a 'once' action. 155 | * }); 156 | * ``` 157 | * 158 | * @see once 159 | * @this jQuery 160 | * 161 | * @global 162 | * @public 163 | */ 164 | $.fn.findOnce = function (id) { 165 | // Filter the elements by which do have the data. 166 | const name = 'jquery-once-' + checkId(id); 167 | 168 | return this.filter(function () { 169 | return $(this).data(name) === true; 170 | }); 171 | }; 172 | }); 173 | -------------------------------------------------------------------------------- /jquery.once.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Once v2.3.0 - http://github.com/robloach/jquery-once 3 | * @license MIT, GPL-2.0 4 | * http://opensource.org/licenses/MIT 5 | * http://opensource.org/licenses/GPL-2.0 6 | */ 7 | (function(e){if(typeof exports==="object"&&typeof exports.nodeName!=="string"){e(require("jquery"))}else if(typeof define==="function"&&define.amd){define(["jquery"],e)}else{e(jQuery)}})(t=>{const r=function(e="once"){if(typeof e!=="string"){throw new TypeError("The jQuery Once id parameter must be a string")}return e};t.fn.once=function(e){const n="jquery-once-"+r(e);return this.filter(function(){return t(this).data(n)!==true}).data(n,true)};t.fn.removeOnce=function(e){return this.findOnce(e).removeData("jquery-once-"+r(e))};t.fn.findOnce=function(e){const n="jquery-once-"+r(e);return this.filter(function(){return t(this).data(n)===true})}}); 8 | //# sourceMappingURL=jquery.once.min.js.map -------------------------------------------------------------------------------- /jquery.once.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"jquery.once.min.js","sources":["jquery.once.js"],"names":["factory","exports","nodeName","require","define","amd","jQuery","$","checkId","id","TypeError","fn","once","name","this","filter","data","removeOnce","findOnce","removeData"],"mappings":";;;;;;CAgBA,SAAWA,GACT,GAAI,OAAOC,UAAY,UAAY,OAAOA,QAAQC,WAAa,SAAU,CAEvEF,EAAQG,QAAQ,QAAQ,CAAC,CAC3B,MAAO,GAAI,OAAOC,SAAW,YAAcA,OAAOC,IAAK,CAGrDD,OAAO,CAAC,UAAWJ,CAAO,CAC5B,KAAO,CAGLA,EAAQM,MAAM,CAChB,CACD,GAAEC,IAYD,MAAMC,EAAU,SAAUC,EAAK,QAC7B,GAAI,OAAOA,IAAO,SAAU,CAC1B,MAAM,IAAIC,UAAU,+CAA+C,CACrE,CAEA,OAAOD,CACT,EAwCAF,EAAEI,GAAGC,KAAO,SAAUH,GAEpB,MAAMI,EAAO,eAAiBL,EAAQC,CAAE,EAGxC,OAAOK,KAAKC,OAAO,WACjB,OAAOR,EAAEO,IAAI,EAAEE,KAAKH,CAAI,IAAM,IAChC,CAAC,EAAEG,KAAKH,EAAM,IAAI,CACpB,EAgCAN,EAAEI,GAAGM,WAAa,SAAUR,GAE1B,OAAOK,KAAKI,SAAST,CAAE,EAAEU,WAAW,eAAiBX,EAAQC,CAAE,CAAC,CAClE,EAiCAF,EAAEI,GAAGO,SAAW,SAAUT,GAExB,MAAMI,EAAO,eAAiBL,EAAQC,CAAE,EAExC,OAAOK,KAAKC,OAAO,WACjB,OAAOR,EAAEO,IAAI,EAAEE,KAAKH,CAAI,IAAM,IAChC,CAAC,CACH,CACF,CAAC"} -------------------------------------------------------------------------------- /once.jquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "once", 3 | "title": "jQuery Once", 4 | "description": "Act on jQuery elements only once.", 5 | "keywords": [ 6 | "jquery", 7 | "once" 8 | ], 9 | "version": "2.3.0", 10 | "author": { 11 | "name": "Rob Loach", 12 | "url": "http://robloach.net" 13 | }, 14 | "licenses": [ 15 | { 16 | "type": "GPL-2.0", 17 | "url": "http://opensource.org/licenses/gpl-2.0.php" 18 | }, 19 | { 20 | "type": "MIT", 21 | "url": "http://opensource.org/licenses/MIT" 22 | } 23 | ], 24 | "bugs": "https://github.com/RobLoach/jquery-once/issues", 25 | "homepage": "https://github.com/RobLoach/jquery-once", 26 | "download": "https://github.com/RobLoach/jquery-once/archive/master.zip", 27 | "dependencies": { 28 | "jquery": "*" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-once", 3 | "title": "jQuery Once", 4 | "description": "Act on jQuery elements only once.", 5 | "version": "2.3.0", 6 | "keywords": [ 7 | "jquery", 8 | "jquery-plugin" 9 | ], 10 | "homepage": "https://github.com/RobLoach/jquery-once", 11 | "author": "Rob Loach (http://github.com/RobLoach)", 12 | "maintainers": [ 13 | "Rob Loach (https://github.com/RobLoach)" 14 | ], 15 | "types": "jquery.once.d.ts", 16 | "main": "jquery.once.js", 17 | "contributors": [ 18 | "JohnAlbin (https://github.com/JohnAlbin)", 19 | "Rob Loach (https://github.com/RobLoach)", 20 | "theodoreb (https://github.com/theodoreb)", 21 | "Olavo Rocha Neto (https://github.com/olavorn)" 22 | ], 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/RobLoach/jquery-once.git" 26 | }, 27 | "bugs": { 28 | "url": "https://github.com/RobLoach/jquery-once/issues" 29 | }, 30 | "license": "(GPL-2.0 OR MIT)", 31 | "engines": { 32 | "node": ">=6" 33 | }, 34 | "dependencies": { 35 | "jquery": "*" 36 | }, 37 | "devDependencies": { 38 | "@types/jquery": "*", 39 | "jsdoc-to-markdown": "^8.0.0", 40 | "jsdom": "~23.0.1", 41 | "mocha": "^10.2.0", 42 | "mocha-jsdom": "*", 43 | "uglify-js": "~3.17.4", 44 | "xo": "*" 45 | }, 46 | "scripts": { 47 | "test": "mocha test/test.js --env node", 48 | "lint": "xo --space=2 --no-esnext jquery.once.js test", 49 | "docs": "jsdoc2md jquery.once.js > API.md", 50 | "build": "uglifyjs -o jquery.once.min.js --comments --source-map filename=jquery.once.min.js,url=jquery.once.min.js.map --mangle -- jquery.once.js", 51 | "prepackage": "npm it", 52 | "package": "npm run docs", 53 | "postpackage": "npm run build" 54 | }, 55 | "files": [ 56 | "jquery.once.js", 57 | "jquery.once.d.ts", 58 | "jquery.once.min.js", 59 | "jquery.once.min.js.map" 60 | ], 61 | "browser": "./jquery.once.min.js", 62 | "browserPackage": { 63 | "files": [ 64 | "jquery.once.js", 65 | "jquery.once.min.js", 66 | "jquery.once.min.js.map" 67 | ] 68 | }, 69 | "xo": { 70 | "rules": { 71 | "unicorn/prefer-module": 0 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | const assert = require('node:assert'); 2 | const jsdom = require('mocha-jsdom'); 3 | 4 | /** 5 | * Automated tests for jQuery Once. 6 | */ 7 | /* globals describe, it, before, beforeEach */ 8 | describe('jQuery Once', () => { 9 | /** 10 | * The global instance of jQuery. 11 | */ 12 | let $; 13 | 14 | /** 15 | * Turn the Mocha test environment into a DOM environment with JSDom. 16 | */ 17 | jsdom({ 18 | url: 'http://localhost', 19 | }); 20 | 21 | /** 22 | * Before the tests initiate, load jQuery and jQuery Once. 23 | */ 24 | before(() => { 25 | $ = require('jquery'); 26 | $.once = require('../jquery.once.js'); 27 | }); 28 | 29 | /** 30 | * Before each test, reset the document body so that there is fresh data. 31 | */ 32 | beforeEach(() => { 33 | // Build the body HTML. 34 | /* globals document */ 35 | document.body.innerHTML = '

This is the Test.

'; 36 | }); 37 | 38 | it('should require ID to be a string', () => { 39 | // Expect it to throw an error. 40 | assert.throws(() => { 41 | $('span').once(() => { 42 | // Nothing. 43 | }); 44 | }); 45 | }); 46 | 47 | it('properly executes .once("test2")', () => { 48 | // Create one once('test2') call. 49 | $('span').once('test2').data('test2', 'foo'); 50 | 51 | // Create another once('test2') call. 52 | $('span').once('test2').data('test2', 'bar'); 53 | 54 | // The data should result to the first once() call. 55 | const data = $('span').data('test2'); 56 | assert.strictEqual(data, 'foo'); 57 | }); 58 | 59 | it('is called only once with an ID', () => { 60 | // Count the number of times once() was called. 61 | $('span').data('count', 0); 62 | 63 | // Create the once() callback. 64 | const callback = () => { 65 | // Increment the count variable stored in the data. 66 | $('span').data('count', $('span').data('count') + 1); 67 | }; 68 | 69 | // Call once() a bunch of times. 70 | for (let i = 0; i < 10; i++) { 71 | $('span').once('count').each(callback); 72 | } 73 | 74 | // Verify that it was only called once. 75 | const count = $('span').data('count'); 76 | assert.strictEqual(count, 1, 'It was called ' + count + ' times.'); 77 | }); 78 | 79 | it('is called only once without an ID', () => { 80 | // Count the number of times once() was called. 81 | $('span').data('once', 0); 82 | 83 | // Create the once() callback. 84 | const callback = () => { 85 | $('span').data('once', $('span').data('once') + 1); 86 | }; 87 | 88 | // Call once() a bunch of times. 89 | for (let i = 0; i < 10; i++) { 90 | $('span').once().each(callback); 91 | } 92 | 93 | // Verify that it was only called once. 94 | const count = $('span').data('once'); 95 | assert.strictEqual(count, 1, 'It was called ' + count + ' times.'); 96 | }); 97 | 98 | it('retrieves empty once data correctly', () => { 99 | // Verify that the element starts without the class. 100 | let hasData = $('span').data('jquery-once-test3'); 101 | assert(!hasData, 'Value not applied in the beginning.'); 102 | 103 | // Create one once() call. 104 | $('span').once('test3'); 105 | 106 | // Verify the data is applied. 107 | hasData = $('span').data('jquery-once-test3'); 108 | assert(hasData, 'The value is properly applied after once().'); 109 | }); 110 | 111 | it('calls removeOnce() correctly', () => { 112 | // Create one once() call. 113 | $('span').once('test4'); 114 | 115 | // Verify the data is applied. 116 | let hasData = $('span').data('jquery-once-test4'); 117 | assert(hasData, 'The value is properly applied after once().'); 118 | 119 | // Remove the once property. 120 | $('span').removeOnce('test4'); 121 | hasData = $('span').data('jquery-once-test4'); 122 | assert(!hasData, 'The value is properly removed when called removeOnce().'); 123 | }); 124 | 125 | it('calls findOnce() correctly', () => { 126 | // Append an additional span to the end. 127 | document.body.innerHTML += '

This is the Test 2.

'; 128 | 129 | // Create one once() call. 130 | $('span').once('test5').data('foo', 'bar'); 131 | 132 | // Find the once'd elements. 133 | $('span').findOnce('test5').each(function () { 134 | assert.strictEqual($(this).data('foo'), 'bar', 'Found correct span data.'); 135 | }); 136 | }); 137 | }); 138 | --------------------------------------------------------------------------------