大家好,我是Byron。如果你经常在不同设备间切换,或者像我一样,对某些特定平台上的小功能“爱不释手”,那么你可能会理解我今天想分享的这份心情。最近,我完成并发布了一个小小的油猴脚本——Large Type Display,它的核心功能,是复刻 macOS 上广受好评的 PopClip 工具中的“Large Type”(大字体显示)特性。
这篇博客,我想把这次“为爱发电”的开发经历记录下来,特别是其中遇到的两个不大不小的“坑”以及我是如何一步步把它们填平的。希望能给同样热爱折腾、喜欢用代码解决实际问题的朋友们带来一些共鸣和启发。
目录
Open 目录
灵感闪现:那个 macOS 上的“大字”诱惑
故事的开头,得从 macOS 上的 PopClip 说起。用过 Mac 的朋友,很多都对这个小巧的文本工具赞不绝口。PopClip 有个功能叫“Large Type”,选中一段文字,轻轻一点,文字就能“唰”地一下以巨大的、清晰的字体全屏显示。这个功能在很多场景下都特别实用:比如你想把屏幕上的小字看得更清楚,或者想快速把一段信息展示给旁边的同事。
然而,当我切换到 Windows 环境,或者在 Linux 上工作时,这份便利就消失了。我开始琢磨:“万能的油猴(Tampermonkey)是不是可以帮我实现这个愿望,让所有浏览器都能用上类似的功能呢?” 这个念头一旦萌生,就有点一发不可收拾了。
初版诞生:从想法到看得见的“雏形”
万事开头难,但对于这种目标明确的小工具,快速搭建一个原型还是比较顺利的。我的初步构想很简单:
- 用户在网页上用鼠标选中一段文本。
- 按下预设的快捷键。
- 脚本动态创建一个覆盖全屏的 div 作为蒙版。
- 将选中的文本内容放入这个蒙版中,并用 CSS 设置一个较大的固定字体(比如
8vw
)。
三下五除二,基础的 HTML 结构、CSS 样式和 JavaScript 核心逻辑很快就位。当第一次成功选中文字,按下快捷键,看到选中的内容真的以大字体弹了出来——尽管还很粗糙,蒙版简陋,字体大小也远谈不上完美——但那种“It works!”的喜悦,相信每个开发者都懂。
第一个“拦路虎”:快捷键为何“纹丝不动”?
正当我沉浸在初步成功的喜悦中,准备进一步打磨功能时,第一个“拦路虎”不期而至。我给脚本设置的默认快捷键是 Alt + D
。但在某些情况下(尤其是我最初在 macOS 上用 Chrome 测试,后来发现某些 Windows 的键盘布局或输入法状态也可能触发),这个快捷键就像“失灵”了一样,按下去毫无反应。
“代码逻辑看起来没问题啊,监听器也加上了,怎么回事?” 我挠了挠头,祭出了前端开发的老朋友——console.log()
大法。我把键盘事件对象 event
里的各种属性,特别是 event.key
, event.altKey
, event.ctrlKey
等,一股脑儿全打印出来。
很快,问题暴露了:当我按下 Alt + D
时,在某些环境下,event.key
的值并不是我期望的 d
或者 D
,而是一个奇怪的 ∂
符号(偏导数符号,这是 macOS 上 Option + D
的默认输入)。我的脚本里判断 event.key.toUpperCase() === 'D'
自然就“扑街”了。
解决方案: 经过一番查阅,我了解到 event.key
返回的是按键产生的“字符”,会受到修饰键(如 Alt/Option)和键盘布局的影响。而 event.code
属性则更能代表键盘上物理按键的“代码”,比如字母“D”键对应的就是 KeyD
。于是,我果断将快捷键的判断逻辑从:
if (event.altKey && event.key.toUpperCase() === currentShortcutKey.toUpperCase() && ...)
修改为:
if (event.altKey && event.code === 'Key' + currentShortcutKey.toUpperCase() && ...)
问题迎刃而解!无论 Alt + D 最终输入的是什么字符,只要用户确实按下了物理上的 Alt 键和 D 键,脚本就能正确响应。
小结: 这个小波折提醒我,看似简单的浏览器事件,其内部属性和跨平台表现也可能充满“细节”。对于需要精确捕获用户按键的场景,event.code 往往比 event.key 更可靠。
第二个挑战:如何让文字“恰到好处”地铺满屏幕?
快捷键的问题解决了,我开始聚焦核心体验——如何让大字体显示得“恰到好处”。我最初用的是 CSS 的 vw (viewport width) 单位来定义字体大小,比如 font-size: 8vw;。这种方式能让字体随着浏览器窗口宽度变化,有一定响应性。
但很快我就不满意了:
选几个字时:比如选中 “你好” 这两个字,8vw 的大小虽然比原文大了不少,但放在整个屏幕中央,还是显得“空落落”的,不够突出,没有那种“全屏放大”的冲击力。 选一大段文字时:如果选了几百个字,8vw 可能又导致文本行数过多,整体高度超出屏幕,或者因为 line-height 的累积,内容显示不全。 我理想中的效果是:当选中的文字很少(比如一个单词或短语),字体应该变得巨大无比,几乎撑满屏幕的宽度或高度;当选中的文字很多时,字体则应自动缩小,以确保内容能清晰、完整地在屏幕内展示。这显然不是一个固定的 vw 值或者简单的几档媒体查询能完美解决的。
攻坚之路:让 JavaScript 赋予字体“灵魂”
我很快意识到,单靠 CSS 的 vw 单位和媒体查询,是喂不饱我这个“既要…又要…”的贪心需求的。要想让字体大小能同时兼顾文本长短和屏幕尺寸,做到真正的“量体裁衣”,还得请 JavaScript 出马。
我的核心思路其实也挺“朴素”:
大胆假设(一个超大字号):脚本会根据你选中的文字有多少,先在心里估摸一个比较“奔放”的初始字体大小(用像素 px 做单位,这样控制起来更精确)。如果字少,这个初始值就尽量往大了猜,目标就是“铺满它”! 小心求证(字体能塞得下吗?):然后,脚本会把这个“奔放”的字号“穿”在你的文字上,再悄悄地测量一下,看看这些文字实际占了多宽、多高(这里用到了 scrollWidth 和 scrollHeight 这两个属性,为了测得准,我还得确保每次都是在一个“干净”的容器里进行测量)。 不断试探(逐步调整到完美):如果发现文字“胖”得快把屏幕(准确说,是预留给它显示的那块区域,大概是屏幕宽高的85-90%)给撑破了,那就说明初始字号太“浪”了,得收敛点。别急,脚本会自动、而且非常快速地一点点把字号调小,调小一点,再量一下,又超了?再调小一点,再量一下……就这样循环往复,直到文字不多不少、刚刚好能舒适地待在屏幕里,或者已经缩小到了一个我们能接受的最小阅读字号为止。 整个过程听起来可能有点像“机器人试衣服”,但对电脑来说就是一瞬间的事儿。调试这个“自动试穿并调整大小”的逻辑确实花了不少心思,尤其是要平衡好初始字号的“奔放”程度和缩小调整时的“小碎步”幅度。目标就是,既要让一两个字的时候,字体能“Duang”一下放大,带来视觉冲击;又要保证一大段“小作文”也能优雅地缩小,清晰完整地呈现出来。
当最终看到,无论是寥寥数字,还是一大篇文章,都能在屏幕上以近乎完美的姿态动态适应、时而霸气侧漏、时而温婉如玉时,那种“成了!”的舒畅感,嗯,就是内个味儿!之前挠破头皮想的各种细节、尝试的各种参数,在那一刻都值了!
小细节与“公之于众”
核心功能稳定后,我还做了一些锦上添花的工作:
使用 GM_registerMenuCommand 添加了自定义快捷键的功能,用户可以在油猴菜单中修改触发字母,增加了脚本的灵活性。 给覆盖层的出现和消失加入了一些简单的 CSS 过渡动画,让体验更平滑一点。 一切就绪,我把脚本命名为 “Large Type Display”,整理好元数据和描述,将它发布到了 Greasy Fork。这是我第一次正儿八经地发布一个自己从头写的油猴脚本,心情还是有点小激动的。
一些心得与未来
这次开发“Large Type Display”的经历,虽然只是一个小工具的诞生过程,但对我而言是一次宝贵的实践和学习。
- 小需求驱动大折腾:有时候,一个小小的、源于个人痛点的需求,就能成为学习新技术、打磨编程技巧的绝佳动力。 直面问题,迭代解决:无论是快捷键的“神秘失灵”,还是动态字体大小的反复调校,核心都在于定位问题、分析原因、尝试方案、观察结果、持续迭代。这个过程可能充满挫败感,但最终解决问题后的喜悦也是加倍的。
- 基础知识的重要性:event.key 和 event.code 的区别,scrollWidth/scrollHeight 的精确测量条件……这些看似基础的知识点,在实际开发中往往是解决问题的关键。
- 分享的乐趣:把自认为有用的小工具分享出去,如果能得到他人的认可,甚至帮助到一两个人,这份满足感是纯粹写代码本身难以替代的。 目前 “Large Type Display” 的功能已经能满足我的核心需求。未来,或许可以考虑增加一些自定义选项,比如蒙版颜色、字体选择等,但暂时还是让它保持简洁和专注吧。
如果你也对这个脚本感兴趣,或者在日常中常常有放大屏幕文字的需求,欢迎前往 Large Type Display 下载体验。有任何建议或 Bug 反馈,都可以在 Greasy Fork 页面留言。
感谢你的阅读,希望这篇开发日记能给你带来一点点启发或乐趣!