Add debounce.js

This commit is contained in:
Talia 2022-02-08 14:50:32 +01:00
parent 5512c955e5
commit c0a9d7465d
5 changed files with 81 additions and 5 deletions

10
debounce.js Normal file
View file

@ -0,0 +1,10 @@
export default (action, delay=1e3) => {
let timeout
return (...args) => {
if (timeout) clearTimeout(timeout)
timeout = setTimeout(() => {
timeout = undefined
action(...args)
}, delay)
}
}

View file

@ -31,5 +31,19 @@
</section> </section>
<section> <section>
<h2>Listener</h2> <h2>Debounce</h2>
<p>
Debounces data like user input or events that can occur in a burst.
</p>
<p>
<h3 class="all-unset"><b>Code Sample</b>:</h3>
<code-block>
import debounce from 'debounce.js'
input.addEventListener("change", debounce(event =&gt; update(input.value)))
</code-block>
</p>
<a class="button" href="page/debounce.html">Read More</a>
</section> </section>

View file

@ -10,9 +10,14 @@ hljs.registerLanguage('javascript', javascript);
const escapes = { "&gt;": ">" } const escapes = { "&gt;": ">" }
class CodeBlock extends HTMLElement { class CodeBlock extends HTMLElement {
connectedCallback() { connectedCallback() {
let content = this.innerHTML.replace(/^\s*\n/, "").replace(/\n\s*$/, "") let content = this.innerHTML
let prefix = new RegExp(`${content.match(/^\t*/)}`, "g") .replace(/^\s*\n/, "")
content = content.replace(prefix, "").replace(/&.*;/g, str => escapes[str] ?? str) .replace(/\n\s*$/, "")
let prefix = new RegExp(`(?<![^\n])${content.match(/^\t*/)}`, "g")
console.log(prefix)
content = content
.replace(prefix, "")
.replace(/&[a-z]+;/g, str => escapes[str] ?? str)
this.replaceChildren(html.pre(html.code(template(hljs.highlight(content, {language: 'javascript'}).value)))) this.replaceChildren(html.pre(html.code(template(hljs.highlight(content, {language: 'javascript'}).value))))
} }
} }

41
page/debounce.html Normal file
View file

@ -0,0 +1,41 @@
<link rel="stylesheet" href="style.css">
<script type="module" src="codeblock.js"></script>
<script type="module" src="filesize.js"></script>
<h1 class="js module">debounce.js</h1>
<code-block>import debounce from 'debounce.js'</code-block>
<section>
<h2>Description</h2>
<p>
Utility module for debouncing user-interactions (or any other events).
</p>
<p>
Its main application are cases where expensive operations like updating or querying data are performed in response to some event like a user typing into a search box.
</p>
<dl>
<code>
<dt>debounce</dt>
<dd>target &xrarr; wrapper</dd>
<dd>target, timeout &xrarr; wrapper</dd>
</code>
<dd>
A decorator function that takes a target function and returns a wrapper that will only call the target after a set timeout expires.
Repeatedly calling the wrapper while the timeout is running will reset the timeout without calling the target function.
</dd>
</dl>
<h2>Example</h2>
<code-block>
const update = value =&gt; expensive_operation(value)
input.addEventListener("change", debounce(event =&gt; update(input.value)))
</code-block>
This code will debounce the update event handler of an input element, calling the <code>update</code>
function only after no changes have been made for at least one second.
</section>

View file

@ -107,7 +107,13 @@ dl>*+* { margin-top: .4em; }
code { font-size: 1.1em; } code { font-size: 1.1em; }
dl>code dt, dl>code dd { all: unset;} dl>code dt, dl>code dd { all: unset;}
dl>code dt::after { content: ' : ';} dl>code dt::after { content: '\00A0:\00A0';}
dl>code {
display: grid;
grid-template-columns: auto 1fr;
}
dl>code>dt~dd { grid-column: 2/2; }
.columns { .columns {
display: grid; display: grid;