Skip to content

Commit 8647375

Browse files
committed
Initial commit
0 parents  commit 8647375

15 files changed

+808
-0
lines changed

.bowerrc

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"directory": "test/bower_components"
3+
}

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/node_modules
2+
/build
3+
/test/bower_components

Gruntfile.js

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
module.exports = function(grunt) {
2+
'use strict'
3+
4+
grunt.initConfig({
5+
uglify: {
6+
options: {
7+
mangle: false,
8+
compress: false,
9+
preserveComments: function(node, comment) {
10+
return !!comment.value.match(/(license|copyright|MIT)/i)
11+
}
12+
},
13+
all: {
14+
files: {
15+
'build/debounce-event.min.js': ['build/debounce-event.js']
16+
}
17+
}
18+
},
19+
copy: {
20+
build: {
21+
expand: true,
22+
cwd: 'src/',
23+
src: ['**/*'],
24+
dest: 'build/'
25+
},
26+
dist: {
27+
expand: true,
28+
cwd: 'build/',
29+
src: ['**/*'],
30+
dest: 'dist/'
31+
}
32+
},
33+
shell: {
34+
mochaPhantomJS: {
35+
command: './node_modules/mocha-phantomjs/bin/mocha-phantomjs test/test.html'
36+
},
37+
installBowerComponents: {
38+
command: 'bower install'
39+
}
40+
}
41+
})
42+
43+
grunt.loadNpmTasks('grunt-contrib-copy')
44+
grunt.loadNpmTasks('grunt-contrib-uglify')
45+
grunt.loadNpmTasks('grunt-shell')
46+
47+
grunt.registerTask('install', 'shell:installBowerComponents')
48+
49+
grunt.registerTask('build', [
50+
'copy:build',
51+
'uglify'
52+
])
53+
54+
grunt.registerTask('test', 'shell:mochaPhantomJS')
55+
56+
grunt.registerTask('dist', [
57+
'build',
58+
'test',
59+
'copy:dist'
60+
])
61+
62+
grunt.registerTask('default', 'build')
63+
}

LICENSE

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Copyright (c) 2016 Greg Stallings
2+
3+
Permission is hereby granted, free of charge, to any person obtaining
4+
a copy of this software and associated documentation files (the
5+
"Software"), to deal in the Software without restriction, including
6+
without limitation the rights to use, copy, modify, merge, publish,
7+
distribute, sublicense, and/or sell copies of the Software, and to
8+
permit persons to whom the Software is furnished to do so, subject to
9+
the following conditions:
10+
11+
The above copyright notice and this permission notice shall be
12+
included in all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Debounce Event
2+
3+
Debounces batched browser event callback execution until the last event within a given time period. The utility returns a key upon event/callback attachment which can be later used to attach multiple callbacks to the same debounced event batch by given element, event name, and timeout. Debounced event batches can be manually detached, or will detach automatically if the callback is specified to be executed only once.
4+
5+
## Usage
6+
7+
### Include
8+
9+
Script include creates global `DebounceEvent`:
10+
11+
```html
12+
<script src="debounce-event.min.js"></script>
13+
```
14+
15+
16+
AMD:
17+
18+
```html
19+
<script src="debounce-event.min.js"></script>
20+
<script>
21+
define([debounce-event], function() {
22+
// do something
23+
})
24+
<script>
25+
```
26+
27+
28+
CommonJS:
29+
30+
```bash
31+
npm install debounce-event
32+
```
33+
34+
```javascript
35+
require 'debounce-event'
36+
```
37+
38+
### API
39+
40+
#### Debounce Initializer Parameters
41+
42+
`DebounceEvent.attach()` takes an object with the following named parameters:
43+
44+
| Name | Description | Required |
45+
| ---- | ----------- | -------- |
46+
| eventName | Name of the browser event to handle. | if `eventKey` not given |
47+
| elem | DOM element to attach the event handler. | if `eventKey` not given |
48+
| done | Callback to execute on the debounced event. | always |
49+
| timeout | Timeout (ms) at which to debounce the event before executing the callback. | always |
50+
| once | True if the callback should execute only once. If the event is the only event in its group, its handler will be detached after the callback executes. Default is `false`. | no |
51+
| eventKey | Previously returned key of an event group to add this callback. If this parameter is specified, `eventName` and `elem` are not used since an event group uses a common event handler. | no |
52+
53+
#### Example
54+
55+
```javascript
56+
// Register the first event in a new event batch, set to execute only once
57+
var eventKey = DebounceEvent.attach({
58+
eventName: 'resize',
59+
elem: window,
60+
done: function() {
61+
console.log('done 1')
62+
},
63+
timeout: 200,
64+
once: true
65+
})
66+
67+
// Register the second event in an existing event batch given the previous
68+
// event key
69+
DebounceEvent.attach({
70+
eventKey: eventKey1,
71+
done: function() {
72+
console.log('done 2')
73+
},
74+
once: true
75+
})
76+
77+
// Register the third event in a new event batch
78+
var eventKey2 = DebounceEvent.attach({
79+
eventName: 'resize',
80+
elem: window,
81+
done: function() {
82+
console.log('done 3')
83+
},
84+
timeout: 300
85+
})
86+
87+
// Manually detach the given event group
88+
DebounceEvent.detach(eventKey2)
89+
```
90+
91+
## Development
92+
93+
```bash
94+
$ cd debounce-event
95+
$ npm install
96+
$ grunt install
97+
$ grunt build
98+
$ grunt test
99+
100+
# Build for release
101+
$ grunt dist
102+
```
103+
104+
## License
105+
106+
Copyright (c) 2016 Greg Stallings. See [LICENSE](https://github.com/gregstallings/debounce-event/blob/master/LICENSE) for details.

bower.json

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "debounce-event",
3+
"description": "Debounces batched browser event callback execution until the last event within a given time period. The utility provides support for attaching multiple callbacks to the same debounced event batch, manual detaching of batches, and the option to execute callbacks only once.",
4+
"main": [
5+
"dist/debounce-event.min.js"
6+
],
7+
"devDependencies": {
8+
"jquery": "2.1.4",
9+
"requirejs": "2.1.22",
10+
"mocha": "2.3.4",
11+
"chai": "3.4.2"
12+
},
13+
"moduleType": [
14+
"amd",
15+
"globals",
16+
"node"
17+
],
18+
"keywords": [
19+
"debounce",
20+
"throttle",
21+
"event"
22+
],
23+
"author": "Greg Stallings <[email protected]>",
24+
"license": "MIT"
25+
}

dist/debounce-event.js

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*!
2+
* Debounce Event
3+
* https://github.com/gregstallings/debounce-event
4+
*
5+
* Copyright 2016 Greg Stallings
6+
* Released under the MIT license
7+
*/
8+
;(function(root, factory) {
9+
if (typeof define === 'function' && define.amd) {
10+
define([], factory)
11+
} else if (typeof module === 'object' && module.exports) {
12+
module.exports = factory()
13+
} else {
14+
root.DebounceEvent = factory()
15+
}
16+
}(this, function() {
17+
'use strict'
18+
19+
var keyCount = 0
20+
var eventGroups = {}
21+
22+
function debounceEvent(eventKey, elem, eventName, timeout) {
23+
var that = this
24+
var count = 0
25+
var eventGroup = eventGroups[eventKey]
26+
var items = eventGroup.items
27+
28+
var listener = function() {
29+
var id = (++count)
30+
31+
setTimeout(function() {
32+
if (id === count) {
33+
var toRemove = []
34+
35+
for (var i = 0; i < items.length; i++) {
36+
items[i][0].call(that)
37+
38+
// Remove if only once
39+
if (items[i][1]) {
40+
toRemove.push(i)
41+
}
42+
}
43+
44+
// Remove elements marked for removal
45+
for (var i = toRemove.length - 1; i >= 0; i--) {
46+
items.splice(toRemove[i], 1)
47+
}
48+
49+
// Detach event handler and delete event group if empty
50+
if (items.length === 0) {
51+
DebounceEvent.detach(eventKey)
52+
}
53+
}
54+
}, timeout)
55+
}
56+
57+
elem.addEventListener(eventName, listener)
58+
59+
// Register other properties on the event group for use by the detach
60+
// handler
61+
eventGroup.elem = elem
62+
eventGroup.eventName = eventName
63+
eventGroup.listener = listener
64+
}
65+
66+
function eventKeyNotRegistered(key) {
67+
throw new Error("Given event key '" + key + "' not registered")
68+
}
69+
70+
var DebounceEvent = {
71+
attach: function(obj) {
72+
var eventKey
73+
var once = obj.hasOwnProperty('once') ? obj.once : false
74+
75+
if (obj.hasOwnProperty('eventKey')) {
76+
eventKey = obj.eventKey
77+
if (!eventGroups.hasOwnProperty(eventKey)) {
78+
eventKeyNotRegistered(eventKey)
79+
}
80+
81+
eventGroups[eventKey].items.push([obj.done, once])
82+
} else {
83+
eventKey = keyCount++
84+
eventGroups[eventKey] = {}
85+
eventGroups[eventKey].items = []
86+
eventGroups[eventKey].items.push([obj.done, once])
87+
debounceEvent(eventKey, obj.elem, obj.eventName, obj.timeout)
88+
}
89+
90+
return eventKey
91+
},
92+
93+
detach: function(eventKey) {
94+
if (!eventGroups.hasOwnProperty(eventKey)) {
95+
eventKeyNotRegistered(eventKey)
96+
}
97+
98+
var eventGroup = eventGroups[eventKey]
99+
eventGroup.elem.removeEventListener(eventGroup.eventName, eventGroup.listener)
100+
delete eventGroups[eventKey]
101+
}
102+
}
103+
104+
return DebounceEvent
105+
}));

dist/debounce-event.min.js

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

example/window-resize.html

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>Debounce Event Example</title>
6+
</head>
7+
<body>
8+
<script src="../src/debounce-event.js"></script>
9+
<script src="window-resize.js"></script>
10+
</body>
11+
</html>

0 commit comments

Comments
 (0)