Skip to content

Instantly share code, notes, and snippets.

@w35l3y
Last active March 15, 2024 16:05
Show Gist options
  • Save w35l3y/ecdb50ce6d40824defd66a946c203762 to your computer and use it in GitHub Desktop.
Save w35l3y/ecdb50ce6d40824defd66a946c203762 to your computer and use it in GitHub Desktop.
class WaitForKeyElements {
list = [];
timer;
#selector;
#callback;
#props;
constructor (selector, callback, props) {
this.#selector = selector
this.#callback = callback
this.#props = props
}
startPromise() {
return new Promise((resolve) => {
const { searchFirst = false, parentNode = document, executeOnce = false, waitTime = 250 } = this.#props
let nodes = []
if (searchFirst) {
const node = parentNode.querySelector(this.#selector)
if (node) {
nodes.push(node)
}
} else {
nodes = Array.from(parentNode.querySelectorAll(this.#selector))
}
this.list = this.list.filter(node => nodes.includes(node))
let found = 0 < nodes.length
nodes.forEach((node, index, arr) => {
if (!~this.list.indexOf(node)) {
if (this.#callback(node, index, arr)) {
found = false
} else {
this.list.push(node)
}
}
})
clearTimeout(this.timer)
if (!found || !executeOnce) {
this.timer = setTimeout(() => {
this.startPromise().then(resolve)
}, waitTime)
} else {
resolve(this)
}
})
}
start() {
this.startPromise()
return this
}
stop() {
this.list = []
clearTimeout(this.timer)
return this
}
}
function waitForKeyElements (/*String*/selector, /*Function*/callback, executeOnce = {}, parentNode, waitTime, searchFirst) {
if (typeof executeOnce === "boolean") {
return new WaitForKeyElements(selector, callback, {
searchFirst,
parentNode,
waitTime,
executeOnce,
}).start()
}
return new WaitForKeyElements(selector, callback, {
searchFirst,
parentNode,
waitTime,
...executeOnce,
}).start()
}
class WaitForKeyElements {
list = [];
timer;
#selector;
#callback;
#props;
constructor (selector, callback, props) {
this.#selector = selector
this.#callback = callback
this.#props = props
}
startPromise() {
return new Promise((resolve) => {
const { searchFirst = false, parentNode = document, executeOnce = false, waitTime = 250 } = this.#props
let nodes = []
if (searchFirst) {
const node = parentNode.querySelector(this.#selector)
if (node) {
nodes.push(node)
}
} else {
nodes = Array.from(parentNode.querySelectorAll(this.#selector))
}
this.list = this.list.filter(node => nodes.includes(node))
let found = 0 < nodes.length
nodes.forEach((node, index, arr) => {
if (!~this.list.indexOf(node)) {
if (this.#callback(node, index, arr)) {
found = false
} else {
this.list.push(node)
}
}
})
clearTimeout(this.timer)
if (!found || !executeOnce) {
this.timer = setTimeout(() => {
this.startPromise().then(resolve)
}, waitTime)
} else {
resolve(this)
}
})
}
start() {
this.startPromise()
return this
}
stop() {
this.list = []
clearTimeout(this.timer)
return this
}
}
function waitForKeyElements (/*String*/selector, /*Function*/callback, executeOnce = {}, parentNode, waitTime, searchFirst) {
if (typeof executeOnce === "boolean") {
return new WaitForKeyElements(selector, callback, {
searchFirst,
parentNode,
waitTime,
executeOnce,
}).startPromise()
}
return new WaitForKeyElements(selector, callback, {
searchFirst,
parentNode,
waitTime,
...executeOnce,
}).startPromise()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment