diff options
author | Hsieh Chin Fan <pham@topo.tw> | 2024-09-24 10:30:27 +0800 |
---|---|---|
committer | Hsieh Chin Fan <pham@topo.tw> | 2024-09-24 12:17:22 +0800 |
commit | f9b38e3fca78aa9d5bece0c5ce967ca89bbd2216 (patch) | |
tree | 8b7a593df60cb33509a8050083bca1117c4ac081 /src/dumbymap.mjs | |
parent | 8d161bfb1f014a3184ab7111f7cd39b3c253f552 (diff) |
feat: set focus state by CSS
data-focus -> class="focus"
Diffstat (limited to 'src/dumbymap.mjs')
-rw-r--r-- | src/dumbymap.mjs | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/src/dumbymap.mjs b/src/dumbymap.mjs index d7c822a..393cc08 100644 --- a/src/dumbymap.mjs +++ b/src/dumbymap.mjs | |||
@@ -147,18 +147,18 @@ function focusNextMap(reverse = false) { | |||
147 | if (mapNum === 0) return | 147 | if (mapNum === 0) return |
148 | 148 | ||
149 | // Get current focused map element | 149 | // Get current focused map element |
150 | const currentFocus = this.container.querySelector('.map-container[data-focus]') | 150 | const currentFocus = this.container.querySelector('.map-container.focus') |
151 | 151 | ||
152 | // Remove class name of focus for ALL candidates | 152 | // Remove class name of focus for ALL candidates |
153 | // This may trigger animation | 153 | // This may trigger animation |
154 | renderedList.forEach(ele => ele.removeAttribute('data-focus')) | 154 | renderedList.forEach(ele => ele.classList.remove('focus')) |
155 | 155 | ||
156 | // Get next existing map element | 156 | // Get next existing map element |
157 | const padding = reverse ? -1 : 1 | 157 | const padding = reverse ? -1 : 1 |
158 | let nextIndex = currentFocus ? renderedList.indexOf(currentFocus) + padding : 0 | 158 | let nextIndex = currentFocus ? renderedList.indexOf(currentFocus) + padding : 0 |
159 | nextIndex = (nextIndex + mapNum) % mapNum | 159 | nextIndex = (nextIndex + mapNum) % mapNum |
160 | const nextFocus = renderedList[nextIndex] | 160 | const nextFocus = renderedList[nextIndex] |
161 | nextFocus.setAttribute('data-focus', "true") | 161 | nextFocus.classList.add("focus") |
162 | 162 | ||
163 | return nextFocus | 163 | return nextFocus |
164 | } | 164 | } |
@@ -210,6 +210,7 @@ export const generateMaps = (container, callback) => { | |||
210 | dumbymap.utils = { | 210 | dumbymap.utils = { |
211 | focusNextMap: throttle(focusNextMap.bind(dumbymap), focusDelay.bind(dumbymap)), | 211 | focusNextMap: throttle(focusNextMap.bind(dumbymap), focusDelay.bind(dumbymap)), |
212 | switchToNextLayout: throttle(switchToNextLayout.bind(dumbymap), 300), | 212 | switchToNextLayout: throttle(switchToNextLayout.bind(dumbymap), 300), |
213 | focusNextBlock: focusNextBlock.bind(dumbymap), | ||
213 | } | 214 | } |
214 | 215 | ||
215 | // LeaderLine {{{ | 216 | // LeaderLine {{{ |
@@ -301,7 +302,7 @@ export const generateMaps = (container, callback) => { | |||
301 | const mapFocusObserver = () => new MutationObserver((mutations) => { | 302 | const mapFocusObserver = () => new MutationObserver((mutations) => { |
302 | const mutation = mutations.at(-1) | 303 | const mutation = mutations.at(-1) |
303 | const target = mutation.target | 304 | const target = mutation.target |
304 | const focus = target.getAttribute(mutation.attributeName) === 'true' | 305 | const focus = target.getAttribute(mutation.attributeName).includes('focus') |
305 | const shouldBeInShowcase = focus && showcase.checkVisibility({ | 306 | const shouldBeInShowcase = focus && showcase.checkVisibility({ |
306 | contentVisibilityAuto: true, | 307 | contentVisibilityAuto: true, |
307 | opacityProperty: true, | 308 | opacityProperty: true, |
@@ -314,7 +315,7 @@ export const generateMaps = (container, callback) => { | |||
314 | // Placeholder for map in Showcase, it should has the same DOMRect | 315 | // Placeholder for map in Showcase, it should has the same DOMRect |
315 | const placeholder = target.cloneNode(true) | 316 | const placeholder = target.cloneNode(true) |
316 | placeholder.removeAttribute('id') | 317 | placeholder.removeAttribute('id') |
317 | placeholder.classList.remove('map-container', 'data-focus') | 318 | placeholder.classList.remove('map-container', 'focus') |
318 | target.parentElement.replaceChild(placeholder, target) | 319 | target.parentElement.replaceChild(placeholder, target) |
319 | 320 | ||
320 | // HACK Trigger CSS transition, if placeholde is the olny chil element in block, | 321 | // HACK Trigger CSS transition, if placeholde is the olny chil element in block, |
@@ -383,9 +384,9 @@ export const generateMaps = (container, callback) => { | |||
383 | 384 | ||
384 | // Since layout change may show/hide showcase, the current focused map should do something | 385 | // Since layout change may show/hide showcase, the current focused map should do something |
385 | // Reset attribute triggers MutationObserver which is observing it | 386 | // Reset attribute triggers MutationObserver which is observing it |
386 | const focusMap = container.querySelector('.map-container[data-focus=true]') | 387 | const focusMap = container.querySelector('.map-container.focus') |
387 | ?? container.querySelector('.map-container') | 388 | ?? container.querySelector('.map-container') |
388 | focusMap?.setAttribute('data-focus', 'true') | 389 | focusMap?.classList?.add('focus') |
389 | }); | 390 | }); |
390 | layoutObserver.observe(container, { | 391 | layoutObserver.observe(container, { |
391 | attributes: true, | 392 | attributes: true, |
@@ -408,7 +409,7 @@ export const generateMaps = (container, callback) => { | |||
408 | const observer = mapFocusObserver() | 409 | const observer = mapFocusObserver() |
409 | mapFocusObserver().observe(mapContainer, { | 410 | mapFocusObserver().observe(mapContainer, { |
410 | attributes: true, | 411 | attributes: true, |
411 | attributeFilter: ["data-focus"], | 412 | attributeFilter: ["class"], |
412 | attributeOldValue: true | 413 | attributeOldValue: true |
413 | }); | 414 | }); |
414 | onRemove(mapContainer, () => observer.disconnect()) | 415 | onRemove(mapContainer, () => observer.disconnect()) |