@taufik-nurrohman/tick
Version:
Utility functions to do time-related tasks.
242 lines (197 loc) • 6.87 kB
Markdown
Time Utility
============
Utility functions to do time-related tasks.
**FYI:**
- [Debounce](https://developer.mozilla.org/en-US/docs/Glossary/Debounce)
- [Throttle](https://developer.mozilla.org/en-US/docs/Glossary/Throttle)
Usage
-----
## CommonJS
~~~ js
const {debounce} = require('@taufik-nurrohman/tick');
const [debounceStart] = debounce(() => {
console.log('resize');
});
window.addEventListener('resize', debounceStart(1000));
~~~
## ECMAScript
~~~ js
import {debounce} from '@taufik-nurrohman/tick';
const [debounceStart] = debounce(() => {
console.log('resize');
});
window.addEventListener('resize', debounceStart(1000));
~~~
Methods
-------
## confine(task, time)
Perform a task once. Repeating the same task multiple times will not cause it to be executed until you stop repeating it
after a certain amount of time has passed. An example use case would be to force the user to be patient.
~~~ js
const [confineStart, confineContinue] = confine(function (e) {
console.log('Saving your data…');
}, 1000);
const form = document.querySelector('form');
form.addEventListener('submit', function (e) {
confineStart.call(this, e), e.preventDefault();
});
// Clicking the “Save” button multiple times is considered “rude”. Continue the restriction!
form.elements['save'].addEventListener('click', function () {
confineContinue();
});
~~~
[!TIP]
> If the `time` value is neither an integer nor less than zero, the first argument of the `confineStart` function call
will be used to hold it:
> ~~~ js
const [confineStart, confineContinue] = confine(function (e) {
console.log('Saving your data…');
});
> const form = document.querySelector('form');
> form.addEventListener('submit', function (e) {
confineStart.call(this, 1000, e), e.preventDefault();
});
> form.elements['save'].addEventListener('click', function () {
confineContinue();
});
~~~
## debounce(task, time)
Perform a task only after the user pauses for a certain amount of time. An example use case would be to start an AJAX
search instantly after the user stops typing their search query.
~~~ js
const [debounceStart, debounceStop] = debounce(function (e) {
console.log('Using query “' + this.value + '” to search for the data you want…');
}, 1000);
const form = document.querySelector('form');
form.elements['query'].addEventListener('input', function (e) {
debounceStart.call(this, e);
});
~~~
[!TIP]
> If the `time` value is neither an integer nor less than zero, the first argument of the `debounceStart` function call
will be used to hold it:
> ~~~ js
const [debounceStart, debounceStop] = debounce(function (e) {
console.log('Using query “' + this.value + '” to search for the data you want…');
});
> const form = document.querySelector('form');
> form.elements['query'].addEventListener('input', function (e) {
debounceStart.call(this, 1000, e);
});
~~~
## delay(task, time)
Perform a task after a certain amount of time has passed. An example use case would be to hide or show a custom
placeholder based on whether a content-editable element is empty or not.
~~~ js
const [delayStart, delayStop] = delay(function (e) {
this.nextElementSibling.style.visibility = "" !== this.innerHTML.trim() ? 'hidden' : "";
}, 1000);
const editor = document.querySelector('[contenteditable]');
editor.addEventListener('input', function (e) {
delayStart.call(this, e);
});
~~~
[!TIP]
> If the `time` value is neither an integer nor less than zero, the first argument of the `delayStart` function call
will be used to hold it:
> ~~~ js
const [delayStart, delayStop] = delay(function (e) {
this.nextElementSibling.style.visibility = "" !== this.innerHTML.trim() ? 'hidden' : "";
});
> const editor = document.querySelector('[contenteditable]');
> editor.addEventListener('input', function (e) {
delayStart.call(this, 1000, e);
});
~~~
## repeat(task, start, step)
Repeat a task only after a certain amount of time has passed. An example use case would be to allow the user to scroll
an area with a click of a button and then continue scrolling when the user holds the button down.
~~~ js
const [repeatStart, repeatStop] = repeat(function (e) {
// Continue scroll…
document.body.scrollTop += 10;
document.documentElement.scrollTop += 10;
}, 1000, 100);
const button = document.querySelector('button');
button.addEventListener('mousedown', function (e) {
// Start scroll…
document.body.scrollTop += 10;
document.documentElement.scrollTop += 10;
repeatStart.call(this, e);
});
document.addEventListener('mouseup', function (e) {
repeatStop();
});
~~~
[!TIP]
> If the `start` value is neither an integer nor less than zero, the first argument of the `repeatStart` function call
will be used to hold it. If the `step` value is neither an integer nor less than zero, the second argument of the
`repeatStart` function call will be used to hold it:
> ~~~ js
const [repeatStart, repeatStop] = repeat(function (e) {
document.body.scrollTop += 10;
document.documentElement.scrollTop += 10;
});
> const button = document.querySelector('button');
> button.addEventListener('mousedown', function (e) {
document.body.scrollTop += 10;
document.documentElement.scrollTop += 10;
repeatStart.call(this, 1000, 100, e);
});
> document.addEventListener('mouseup', function (e) {
repeatStop();
});
~~~
## throttle(task, step)
Perform a task only within a specific time frame and ignore repetitions outside of it. An example use case would be to
limit an API call.
~~~ js
const [throttleStart, throttleStop] = throttle(function (e) {
console.log('Fetching information about the online status of other users…');
}, 1000);
// Fetch data every 10 seconds of user activity on the site!
function checkOnlineStatus() {
throttleStart.call(this, e);
}
window.addEventListener('keydown', checkOnlineStatus);
window.addEventListener('mousedown', checkOnlineStatus);
window.addEventListener('mousemove', checkOnlineStatus);
window.addEventListener('scroll', checkOnlineStatus);
~~~
[!TIP]
> If the `step` value is neither an integer nor less than zero, the first argument of the `throttleStart` function call
will be used to hold it:
> ~~~ js
const [throttleStart, throttleStop] = throttle(function (e) {
console.log('Fetching information about the online status of other users…');
}, 1000);
> function checkOnlineStatus() {
throttleStart.call(this, e);
}
> window.addEventListener('keydown', checkOnlineStatus);
window.addEventListener('mousedown', checkOnlineStatus);
window.addEventListener('mousemove', checkOnlineStatus);
window.addEventListener('scroll', checkOnlineStatus);
~~~