You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
"use strict"
const months = document.getElementById('months') let selecting = null // { origin, className, range }
let is_select = false
months.addEventListener("pointerdown", event => { selecting = null is_select = false for (const elem of document.querySelectorAll(".selecting, .unselecting")) { elem.className = "" }
if (event.buttons !== 1) return let target = event.target if (target.nodeType == 3) target = target.parentNode if (target.tagName !== "LABEL") return
event.preventDefault()
const className = target.className = document.getElementById(target.htmlFor).checked ? "unselecting" : "selecting" selecting = { origin: target, className, range: [ target ] } })
months.addEventListener('pointermove', event => { if (selecting === null) return event.preventDefault() is_select = true
const range = document.createRange() range.selectNode(selecting.origin) if (range.comparePoint(event.target, 0) > 0) range.setEndAfter(event.target) else range.setStartBefore(event.target)
const treeWalker = document.createTreeWalker( range.commonAncestorContainer, NodeFilter.SHOW_ELEMENT, { acceptNode: (node) => node.nodeName.toLowerCase() === 'label' ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP } )
const new_range = [] let currentNode while (currentNode = treeWalker.nextNode()) { if (range.intersectsNode(currentNode)) { new_range.push(currentNode) const idx = selecting.range.indexOf(currentNode) if (idx !== -1) selecting.range.splice(idx, 1) else currentNode.className = selecting.className } } for (const elem of selecting.range) { elem.className = "" } selecting.range = new_range })
document.addEventListener('pointercancel', event => { if (selecting === null) return for (const elem of selecting.range) { elem.className = "" } selecting = null is_select = false })
document.addEventListener('pointerup', event => { if (selecting === null) return event.preventDefault() for (const elem of selecting.range) { if (is_select) document.getElementById(elem.htmlFor).checked = selecting.className == "selecting" elem.className = "" } selecting = null }) months.addEventListener('click', event => { if (is_select) { event.preventDefault() is_select = false } })
|