summaryrefslogtreecommitdiff
path: root/assets
diff options
context:
space:
mode:
authorEltrac <hi@guhub.cn>2025-07-27 09:56:40 +0800
committerEltrac <hi@guhub.cn>2025-07-27 09:56:40 +0800
commit50dbd00f57e72c54ed93c54d39a3969769bd4388 (patch)
treec62378f6f4aa0a8b8ff9b71b60d62c502a337719 /assets
parent7e7d95f85995d2df66ec47144d16d663eeb3eea0 (diff)
refactor: extract tooltip feature as a global script
Former-commit-id: b64e0b67a1a425bb79055c1e42b12f5807836d66
Diffstat (limited to 'assets')
-rw-r--r--assets/js/tooltip.js54
1 files changed, 54 insertions, 0 deletions
diff --git a/assets/js/tooltip.js b/assets/js/tooltip.js
new file mode 100644
index 00000000..c90658a2
--- /dev/null
+++ b/assets/js/tooltip.js
@@ -0,0 +1,54 @@
+(() => {
+ const allTooltipped = document.querySelectorAll('[data-tooltip], [title]');
+
+ const createOrUpdateTooltip = (element) => {
+ const tooltipText = element.getAttribute('data-tooltip') || element.getAttribute('title');
+
+ if (!tooltipText) return;
+
+ let tooltipElement = element.querySelector('.__generated-tooltip');
+ if (!tooltipElement) {
+ element.classList.add('group', 'relative', 'tooltipped');
+
+ tooltipElement = document.createElement('div');
+ tooltipElement.classList.add(
+ '__generated-tooltip',
+ ...'absolute bottom-full left-1/2 transform -translate-x-1/2 translate-y-1 bg-black/80 text-white px-2.5 py-1.5 rounded text-xs whitespace-nowrap opacity-0 invisible transition-all duration-300 pointer-events-none mb-2 z-1000 group-hover:opacity-100 group-hover:visible group-hover:translate-y-0 dark:bg-white/90 dark:text-black'.split(' ')
+ );
+ element.appendChild(tooltipElement);
+ }
+
+ tooltipElement.textContent = tooltipText;
+ };
+
+ const observer = new IntersectionObserver((entries, obs) => {
+ entries.forEach(entry => {
+ if (!entry.isIntersecting) return;
+
+ const element = entry.target;
+ createOrUpdateTooltip(element);
+
+ // listen to tooltip text changes
+ const mutationObserver = new MutationObserver(mutations => {
+ for (const mutation of mutations) {
+ if (mutation.type === 'attributes' &&
+ (mutation.attributeName === 'title' || mutation.attributeName === 'data-tooltip')) {
+ createOrUpdateTooltip(element);
+ }
+ }
+ });
+
+ mutationObserver.observe(element, {
+ attributes: true,
+ attributeFilter: ['title', 'data-tooltip'],
+ });
+
+ obs.unobserve(element); // 不再需要 Intersection 监听
+ });
+ }, {
+ rootMargin: '100px',
+ threshold: 0.1,
+ });
+
+ allTooltipped.forEach(el => observer.observe(el));
+})();