Browse Source

fakebooks

master
rdrew 3 weeks ago
parent
commit
53381edc44
  1. 35
      js/audio-tooltip.js

35
js/audio-tooltip.js

@ -7,24 +7,27 @@
const href = link.getAttribute('href'); const href = link.getAttribute('href');
if (!href) return; if (!href) return;
// Create minimal tooltip with just the link // Create tooltip
const tooltip = document.createElement('div'); const tooltip = document.createElement('div');
tooltip.className = 'audio-tooltip'; tooltip.className = 'audio-tooltip';
tooltip.innerHTML = `<a href="${href}" class="audio-tooltip-link">Go to page →</a>`; tooltip.innerHTML = `<a href="${href}" class="audio-tooltip-link">Go to page →</a>`;
document.body.appendChild(tooltip); document.body.appendChild(tooltip);
let cleanup = null; let cleanup = null;
let hideTimeout = null;
const HIDE_DELAY_MS = 250; // Adjust if needed (higher = more forgiving)
const showTooltip = () => { const showTooltip = () => {
clearTimeout(hideTimeout);
tooltip.style.display = 'block'; tooltip.style.display = 'block';
// Dynamically import Floating UI (works if in core or via build/CDN) // Floating UI dynamic import + positioning
import('@floating-ui/dom').then(({ computePosition, autoUpdate, offset, flip, shift }) => { import('@floating-ui/dom').then(({ computePosition, autoUpdate, offset, flip, shift }) => {
cleanup = autoUpdate(link, tooltip, () => { cleanup = autoUpdate(link, tooltip, () => {
computePosition(link, tooltip, { computePosition(link, tooltip, {
placement: 'top', placement: 'top',
middleware: [ middleware: [
offset(10), // distance from link offset(10),
flip(), flip(),
shift({ padding: 8 }) shift({ padding: 8 })
] ]
@ -36,7 +39,7 @@
}); });
}); });
}).catch(() => { }).catch(() => {
// Fallback positioning if Floating UI import fails // Fallback centering above
const rect = link.getBoundingClientRect(); const rect = link.getBoundingClientRect();
tooltip.style.left = `${rect.left + window.scrollX + rect.width / 2}px`; tooltip.style.left = `${rect.left + window.scrollX + rect.width / 2}px`;
tooltip.style.top = `${rect.top + window.scrollY - tooltip.offsetHeight - 10}px`; tooltip.style.top = `${rect.top + window.scrollY - tooltip.offsetHeight - 10}px`;
@ -44,20 +47,34 @@
}); });
}; };
const hideTooltip = () => { const scheduleHide = () => {
clearTimeout(hideTimeout);
hideTimeout = setTimeout(() => {
tooltip.style.display = 'none'; tooltip.style.display = 'none';
if (cleanup) { if (cleanup) {
cleanup(); cleanup();
cleanup = null; cleanup = null;
} }
}, HIDE_DELAY_MS);
}; };
// Trigger events
link.addEventListener('mouseenter', showTooltip); link.addEventListener('mouseenter', showTooltip);
link.addEventListener('mouseleave', hideTooltip); link.addEventListener('mouseleave', scheduleHide);
// Optional: keep visible on hover of tooltip itself (so user can click) // Keep open when hovering tooltip
tooltip.addEventListener('mouseenter', showTooltip); tooltip.addEventListener('mouseenter', () => {
tooltip.addEventListener('mouseleave', hideTooltip); clearTimeout(hideTimeout);
tooltip.style.display = 'block';
});
tooltip.addEventListener('mouseleave', scheduleHide);
// Optional: Clean up on click (prevents stuck tooltips)
tooltip.querySelector('a').addEventListener('click', () => {
tooltip.style.display = 'none';
if (cleanup) cleanup();
});
}); });
} }
}; };

Loading…
Cancel
Save