Skip to content

Instantly share code, notes, and snippets.

@kawaz
Last active Aug 20, 2021
Embed
What would you like to do?
よく使うJSの便利関数的な奴 tools.js
// Timeout付きInterval。cbに渡されるstopで繰り返しを停止することも出来る
const setIntervalTimeout = (cb, interval = 200, timeout = 5000) => { const stop = () => { clearInterval(i); clearTimeout(t) }, i = setInterval(cb, interval, stop), t = setTimeout(stop, timeout); cb(stop); return stop }
// querySelector のショートハンド
const query = (target) => target instanceof Element ? target : typeof target === 'string' ? document.querySelector(target) : null
const queryAll = (target) => target instanceof Element ? [target] : typeof target === 'string' ? [...document.querySelectorAll(target)] : []
const myStyle = (id) => myStyle[`$${id}`] ?? (myStyle[`$${id}`] = (document.head.append(document.createElement('style')), document.styleSheets.item(document.styleSheets.length - 1)))
const newRule = () => (s => (s.addRule(), s.cssRules[s.cssRules.length - 1]))(myStyle())
// target が見つかるまで待つPromise
const ready = (target, interval = 200, timeout = 5000) => new Promise((resolve, reject) => {
const waiter = () => {
const el = query(target)
if (el) {
clearInterval(waiterId)
clearTimeout(timeoutId)
resolve(el)
}
}
const timeoutId = setTimeout(() => { clearInterval(waiterId); reject(new Error(`target ${target} was not ready`)); }, timeout)
const waiterId = setInterval(waiter, interval)
waiter()
})
// DOMを作る
const createElement = (tag, props = {}, children = []) => {
const {classList=[], style={}, dataset={}, ...others} = props
const el = document.createElement(tag)
if(classList.length) {
el.classList.add(...classList)
}
Object.assign(el.style, style)
Object.assign(el.dataset, dataset)
Object.assign(el, others)
for(let child of children) {
if (child instanceof Element) {
el.appendChild(child)
} else {
el.appendChild(document.createTextNode(child))
}
}
return el
}
// フォーム要素の値を取得したりセットしたりする
const form = (target, ...values) => {
// get
if (values.length === 0) {
return query(target)?.value
}
// set
return [query(target)].map(e => {
const value = values.reduce((pre, value) => {
if (typeof value === "boolean" && e.tagName == "INPUT" && ["checkbox", "radio"].includes(e.type)) {
value = { checked: value }
} else if (["string", "number", "boolean"].includes(typeof value) || value === null) {
value = { value }
}
if (typeof value === "object") {
return Object.assign(pre, value)
}
}, {})
Object.assign(e, value)
return value
}).shift()
}
// ワイルドカードを正規表現化する
const wc = str => new RegExp(`^${str.replace(/[^a-z0-9_]/gi, "\\$&").replace(/\\\*/g, ".*")}$`)
// urlにマッチしたらcb(url)を実行
const urlmatch = (url, cb = url => console.log(`urlmatch: ${url}`)) =>
(wc(url)?.test(location.href) || (location.hash == "" && wc(url)?.test(location.href.replace(/#$/, "")))) && cb(url)
@kawaz

This comment has been minimized.

Copy link
Owner Author

@kawaz kawaz commented Jul 27, 2021

ユーザスクリプトのコメントに以下を追記すると使えるようになる

// @require      https://gist.githubusercontent.com/kawaz/804ddbcc7ddc5033d09d4e72fdcd3bf5/raw/tools.js?v=1

クエリの ?v=1 はキャッシュクリア用のパラメータ。gist更新後にすぐ使いたい場合はユーザスクリプト側の @require のクエリを変えればよい。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment