为你的 Hexo 博客添加交互式点击提示:clicktip 插件详解
在博客写作中,我们经常需要对某些词语或概念进行补充说明。传统的做法要么是使用括号注释打断阅读 flow,要么是使用脚注需要读者跳转查看。今天我要介绍一款自己开发的 Hexo 插件 ——clicktip,它能让你的读者通过点击词语就能查看详细说明,既保持了文章的简洁性,又提供了丰富的补充信息。
什么是 clicktip 插件?
clicktip
是一款专为 Hexo 博客设计的标签插件,它允许你在文章中为任意词语添加点击提示功能。当读者点击带有提示的词语时,会显示预设的解释内容,再次点击或点击其他地方则会关闭提示。这种交互方式既直观又不影响正常阅读,非常适合添加注释、解释专业术语或提供额外背景信息。
插件特点
-简洁易用:通过简单的标签语法即可为词语添加提示功能
-样式丰富:支持多种触发元素样式(下划线、虚线等)
-交互友好:提供高亮、颜色变化等悬停效果
-智能定位:提示框会根据页面空间自动选择最佳显示位置
-响应式设计:在不同屏幕尺寸下都能良好展示
-无冲突保证:通过唯一 ID 机制确保页面中多个提示框正常工作
安装方法
安装 clicktip
插件非常简单:
1.在你的 Hexo 博客根目录下,创建 scripts
文件夹(如果已存在则忽略)
2.在 scripts
文件夹中创建 clicktip.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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
| let clickTipCounter = 0;
hexo.extend.tag.register('clt', function(args) { const word = args[0]; const tip = args[1].replace(/"/g, ''); const styleType = args[2] || 'none'; const hoverEffect = args[3] || 'none'; const hoverColor = args[4] || '#2c3e50';
const uniqueId = `click-tip-${Date.now()}-${clickTipCounter++}`; let triggerClasses = 'click-tip-trigger'; if (styleType === 'underline') triggerClasses += ' click-tip-underline'; if (styleType === 'dashed') triggerClasses += ' click-tip-dashed'; if (hoverEffect === 'highlight') triggerClasses += ' click-tip-highlight'; if (hoverEffect === 'color') triggerClasses += ' click-tip-color';
const dataAttrs = hoverEffect === 'color' ? `data-hover-color="${hoverColor}"` : '';
return ` <span class="click-tip-wrapper" data-id="${uniqueId}"> <span id="${uniqueId}-trigger" class="${triggerClasses}" ${dataAttrs}> ${word} </span> <span id="${uniqueId}-content" class="click-tip-content"> ${tip} </span> </span> `; });
hexo.extend.filter.register('after_render:html', function(html) { const script = ` <style> .click-tip-wrapper { position: relative; display: inline-block; } .click-tip-trigger { cursor: pointer; color: #2c3e50; transition: all 0.2s; } .click-tip-underline { text-decoration: underline; } .click-tip-dashed { border-bottom: 1px dashed #999; } .click-tip-highlight:hover { background-color: rgba(0,0,0,0.05); } .click-tip-color:hover { color: var(--hover-color, #3498db); } .click-tip-content { display: none; position: absolute; padding: 8px 12px; background: #fff; border: 1px solid #eaecef; border-radius: 4px; font-size: 0.9em; color: #333; white-space: nowrap; z-index: 100; box-shadow: 0 4px 12px rgba(0,0,0,0.08); opacity: 0; transform: translateY(8px); transition: opacity 0.2s ease, transform 0.2s ease; } .click-tip-content.active { display: block; opacity: 1; transform: translateY(0); } /* 响应式定位样式 */ .click-tip-content.position-top { top: auto; bottom: 100%; margin-bottom: 8px; } .click-tip-content.position-right { left: 100%; top: 0; margin-left: 8px; } .click-tip-content.position-left { left: auto; right: 100%; top: 0; margin-right: 8px; } </style> <script> document.addEventListener('DOMContentLoaded', function() { // 设置颜色悬停效果 document.querySelectorAll('.click-tip-color').forEach(el => { const hoverColor = el.dataset.hoverColor || '#3498db'; el.style.setProperty('--hover-color', hoverColor); }); // 事件委托处理所有点击 document.body.addEventListener('click', function(e) { const trigger = e.target.closest('.click-tip-trigger'); if (!trigger) return; e.stopPropagation(); const wrapper = trigger.closest('.click-tip-wrapper'); const content = wrapper.querySelector('.click-tip-content'); const isActive = content.classList.contains('active'); // 关闭所有提示框 document.querySelectorAll('.click-tip-content.active').forEach(el => { el.classList.remove('active'); }); // 切换当前提示框 if (!isActive) { positionTooltip(wrapper); content.classList.add('active'); } }); // 点击外部关闭提示框 document.addEventListener('click', function() { document.querySelectorAll('.click-tip-content.active').forEach(el => { el.classList.remove('active'); }); }); // 智能定位提示框 function positionTooltip(wrapper) { const content = wrapper.querySelector('.click-tip-content'); const trigger = wrapper.querySelector('.click-tip-trigger'); // 重置位置 content.className = 'click-tip-content'; // 获取视口尺寸和元素位置 const viewportWidth = window.innerWidth; const viewportHeight = window.innerHeight; const { top, left, width, height } = trigger.getBoundingClientRect(); const tipWidth = content.offsetWidth; const tipHeight = content.offsetHeight; // 计算可用空间 const spaceRight = viewportWidth - (left + width); const spaceLeft = left; const spaceBelow = viewportHeight - (top + height); const spaceAbove = top; // 智能定位逻辑 if (spaceBelow >= tipHeight) { // 默认下方 content.style.top = 'calc(100% + 8px)'; content.style.left = '0'; } else if (spaceAbove >= tipHeight) { // 上方 content.classList.add('position-top'); content.style.left = '0'; } else if (spaceRight >= tipWidth) { // 右侧 content.classList.add('position-right'); content.style.top = '0'; } else if (spaceLeft >= tipWidth) { // 左侧 content.classList.add('position-left'); content.style.top = '0'; } else { // 缩小并居中显示 content.style.whiteSpace = 'normal'; content.style.maxWidth = '200px'; content.style.top = 'calc(100% + 8px)'; content.style.left = '50%'; content.style.transform = 'translateX(-50%)'; } } // 窗口大小改变时重新定位 window.addEventListener('resize', function() { document.querySelectorAll('.click-tip-content.active').forEach(content => { const wrapper = content.closest('.click-tip-wrapper'); positionTooltip(wrapper); }); }); }); </script> `; return html.replace('</body>', script + '</body>'); });
|
3.清理 Hexo 生成的静态文件和缓存
使用方法
clicktip
插件提供了简洁的标签语法:
1
| {% clt 词语 "提示内容" [样式类型] [悬停效果] [悬停颜色] %}
|
标签可改:
1 2
| >代码第四行: >hexo.extend.tag.register('clt', function(args){...});
|
参数说明:
-词语:需要添加提示的词语或短语
-提示内容:点击后显示的提示文本(需要用双引号包裹)
-样式类型(可选):
-none
:无特殊样式(默认)
-underline
:下划线样式
-dashed
:虚线样式
-悬停效果(可选):
-none
:无效果(默认)
-highlight
:背景高亮效果
-color
:文字变色效果
-悬停颜色(可选):当悬停效果为 color
时生效,可指定颜色值(默认 #2c3e50)
示例:
1
| {% clt "提示" "这是一个提示" underline color #ff0000 %}
|
提示
这是一个提示