forked from aurora-is-near/rainbow-bridge-frontend
-
Notifications
You must be signed in to change notification settings - Fork 1
/
domHelpers.js
101 lines (86 loc) · 2.98 KB
/
domHelpers.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import render from './render'
import * as urlParams from './urlParams'
const isObject = x =>
Object.prototype.toString.call(x) === '[object Object]'
const fillCache = {}
// Update DOM elements that have a "data-behavior" attribute
// Given `<span data-behavior="thing"></span>`
// You can `fill('thing').with('whatever')` to set the innerHTML
// You can pass an array, and it will be joined with empty string
// You can `fill('thing').with({ title: 'whatever' }) to set any other attribute
//
// The values filled are cached, so attempts to fill the same content multiple
// times will not cause unnecessary DOM manipulations
export const fill = selector => ({
with: (contentOrAttrObj) => {
const attrs = isObject(contentOrAttrObj)
? contentOrAttrObj
: { innerHTML: contentOrAttrObj }
Object.entries(attrs).forEach(([attr, content]) => {
const contentString = Array.isArray(content)
? content.join('')
: content
if (fillCache[`${selector}:${attr}`] !== contentString) {
fillCache[`${selector}:${attr}`] = contentString
findAll(selector).forEach(n => {
n[attr] = contentString
})
}
})
}
})
// A better String coercion than `String()`
export function toString (whatever) {
if (!whatever) return ''
return String(whatever)
}
// Attach a click event handler to elements with the specified
// "data-behavior" attribute
export function onClick (behavior, fn) {
document.querySelector('body').addEventListener('click', event => {
// did they click the thing?
const thing = event.target.closest(`[data-behavior=${behavior}]`)
if (thing) fn(event)
})
}
// Find element with the given "data-behavior" attribute
export const find = selector =>
document.querySelector(`[data-behavior="${selector}"]`)
// Find all elements with the given "data-behavior" attribute
// returns as array
export const findAll = selector =>
Array.from(document.querySelectorAll(`[data-behavior="${selector}"]`))
// Hide DOM elements that have the given "data-behavior" attribute
export const hide = selector =>
findAll(selector).forEach(n => { n.style.display = 'none' })
// Show DOM elements that have the given "data-behavior" attribute
export const show = (selector, display) =>
findAll(selector)
.forEach(n => {
if (display) {
n.style.display = display
} else {
n.style.removeProperty('display')
}
})
// call this once, after page load
export function init () {
onClick('goHome', function goHome () {
urlParams.clear()
render()
})
onClick('closeModal', function closeModal (e) {
e.target.closest('.modal').style.display = 'none'
})
// avoid page refreshes when submitting "get" forms
document.querySelectorAll('form[method="get"]').forEach(form => {
form.onsubmit = e => {
e.preventDefault()
urlParams.clear()
Array.from(e.target.elements).forEach(el => {
if (el.name) urlParams.set({ [el.name]: el.value })
})
render()
}
})
}