# 覆盖浏览器的“在页面中查找”快捷键

**URL:** <https://meta.discourse.org/t/overriding-the-browsers-find-in-page-keyboard-shortcut/203233>\
**Category:** UX\
**Tags:** keyboard-shortcuts\
**Created:** [2021年九月11日 08:14 UTC](https://meta.discourse.org/t/overriding-the-browsers-find-in-page-keyboard-shortcut/203233 "2021-09-11T08:14:10Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![fakename](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fakename/32/233738_2.png) [@fakename](https://meta.discourse.org/u/fakename)\
**Post date:** [2021年九月11日 08:14 UTC](https://meta.discourse.org/t/overriding-the-browsers-find-in-page-keyboard-shortcut/203233/1 "2021-09-11T08:14:11Z")

</div>

你好，我是 Discourse 的粉丝，来自一个正在讨论从 vBulletin5 迁移的小型社区。有一个人反对 Discourse，理由是“劫持 Ctrl+f 是邪恶的”，在了解他们的意思后，我不得不表示同意。Discourse 目前处理 Ctrl+f 的方式存在严重的可用性问题，因为 Ctrl+f 是浏览器中“在页面内查找文本”的快捷键。

# 问题所在

- 有时，Ctrl+f 能正常工作，Discourse 会使用浏览器内置的查找功能，随着用户输入，页面会立即滚动到第一个匹配项。Ctrl+G 可以跳转到下一个匹配项。
  - 一切都很完美。

- 但有时 Ctrl+f 无法正常工作，反而会显示来自数据库搜索的结果列表。
  - 它不会随着用户输入将页面滚动到第一个匹配项。
  - 只有当搜索短语恰好已经在屏幕上时，才会高亮显示。
  - 它不支持搜索过短的术语，例如"UX"。
  - 它不接受 Ctrl+G 来显示下一个匹配项。
  - 它确实会显示一些不相关主题的结果，而如果使用浏览器原生的 Ctrl+f 且页面上找不到该术语，则根本不会显示这些结果。

- 这种失效对完全用户来说是看不见的，但却极其令人沮丧。用户感觉在页面内搜索的功能被剥夺了，却没有任何解释。
- 告诉他们再按一次 Ctrl+f 就会执行浏览器搜索也无济于事，因为那样会找不到实际存在的帖子。

# 根本原因

这不仅仅是一个外观问题，而是一个根本性的可用性问题，Discourse 必须从根源上解决：即造成“整个对话实际上都在浏览器的 DOM 中”的错觉，而实际上内容是动态加载的。

当一个主题包含超过二十篇帖子时，Discourse 仅按需将帖子发送到浏览器。你可以查看一个[包含超过 1000 篇帖子的线程](https://try.discourse.org/t/what-happens-when-a-topic-has-over-1000-replies/301)，服务器几乎没有任何负载，因为大部分 DOM 只是空的占位符。这是一个绝妙的主意，但也是导致 Ctrl+f 神秘失效的原因。

我并不是建议放弃这种错觉，我认为它非常有价值。Discourse 正确地摒弃了将对话人为分割成每页约 40 篇帖子的旧方式。

Discourse 只需要更好地让这种错觉无缝衔接。

# 解决方案

老实说，我不知道最佳解决方案是什么，但我有一些想法，希望能有所帮助。

## 有意识地打破错觉

首先，如果 Discourse 决定通过切换到数据库搜索来打破这种错觉，以下是一些合理且简单的想法：

1. 让用户知道发生了什么。在浏览器查找框通常出现的位置放一个小提示，说明情况并致歉。

- “很抱歉，该主题共有 1002 篇帖子，但您的浏览器仅加载了其中的 7 篇，因此‘在页面中查找’可能无法正常工作。如果您仍想尝试，请再次按下 Ctrl+f。”

1. 让用户拥有一定的控制权。当用户按下 Ctrl+f 时，显示一个按钮，允许用户手动将主题中所有帖子的文本加载到 DOM 中。

- 如果由于浏览器一次只能缓存 100 篇帖子的限制而被认为不可行，则显示一个按钮，让用户回退到查看主题的旧方式：按页分割。
- “点击此处以兼容 Ctrl+f 的方式查看此主题：[第 1 页] [2] [3] [4] [5] [6] [7] [8] [9] […] [\>\>]"

1. 将默认截断数量从 20 篇帖子增加到 100 篇。这可能并不难实现，因为 Discourse 已经能够在 DOM 中缓存这么多帖子。

## 修复错觉

当然，上述想法并不美观，我认为它们只是权宜之计。最终，最好的解决方案是 Discourse 实现一种符合用户预期的 Ctrl+f 功能。在 Discourse 中复现浏览器交互式搜索的功能将非常值得，但我想象这会很困难。

不过，可能存在一个（相对）简单的解决方案。

# 不要从 DOM 中修剪文本

我认为 Discourse 的最佳解决方案是仅从帖子中移除媒体对象，而不是文本。这样，就不需要“劫持 Ctrl+f”并用数据库搜索取而代之。

“在页面中查找”仅搜索文本，因此浏览器无需加载整个 DOM 即可进行搜索。文本的传输极其轻量，尤其是如果 HTTP 服务器启用了 gzip 压缩。文本在网页浏览器中占用的内存也很少。

你们比我更了解这些，但我有一些猜测：

- 平均帖子大小：5 KiB 文本
- 平均主题长度：50 条回复
- 平均需要传输的文本量：250 KiB，这看起来很合理。

当然，每一个字节对响应速度都很重要。如果我的估算有误且文本大小确实是个问题，可以在页面的重要部分发送后，将填充 DOM 文本的操作作为后台进程进行。如果当用户按下 Ctrl+f 时 DOM 尚未完全填充文本，可以显示一个进度条，告知用户稍等，并显示文本逐渐加载的进度。

# 致谢

虽然 Ctrl+f 破坏了 Discourse 所营造的错觉是一个严重的问题，但我对 Discourse 开发人员在最初创造这种错觉方面所取得的惊人工作印象深刻。我相信他们最终也会找到正确的修复方法。

感谢您花时间考虑我的建议。

此致，

_Mx. F.N._

---

<div class="post-metadata">

**Author:** ![JonathanShaw](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jonathanshaw/32/532672_2.png) [@JonathanShaw](https://meta.discourse.org/u/JonathanShaw)\
**Post date:** [2021年九月11日 10:25 UTC](https://meta.discourse.org/t/overriding-the-browsers-find-in-page-keyboard-shortcut/203233/2 "2021-09-11T10:25:27Z")

</div>

我完全同意你的看法，这里的用户体验既令人沮丧又出乎意料。对我来说，在一个只有 30 个主题帖的简单讨论串中上下滚动也很别扭。这确实是 Discourse 让我感到尴尬的一点。

我不禁怀疑，在小中型讨论串中追求良好体验与在大型讨论串中避免崩溃之间的平衡是否真的恰当。在我的项目中，超大型讨论串不太可能成为主要问题，因此因迁就它们的需求而损害整体用户体验实在令人沮丧。

我记得曾读到，当前方案的主要限制因素是 Android 设备上的渲染时间。如果确实如此，那么因部分设备的局限而拖累所有设备，未免太可惜了。

我很想知道开发者是否有可能自定义以下两点：  
(1) 每个分块中的主题数量（例如根据不同设备进行调整）；  
(2) 保持已渲染的主题可见，而不是像现在这样将其卸载（这导致回滚到顶部时操作笨拙）。

我明白这是一个非常复杂的领域，目前尚无完美解决方案，且已投入了大量精力。

---

<div class="post-metadata">

**Author:** ![n0by](https://avatars.discourse-cdn.com/v4/letter/n/dec6dc/32.png) [@n0by](https://meta.discourse.org/u/n0by)\
**Post date:** [2024年三月1日 22:36 UTC](https://meta.discourse.org/t/overriding-the-browsers-find-in-page-keyboard-shortcut/203233/3 "2024-03-01T22:36:05Z")

</div>

这个帖子中有很多好主意，但目前的实现（仍然）很糟糕。  
不要这样做，只是不要覆盖强大的快捷方式。即使是旧的公告板方法，有几个搜索按钮也更易于访问。找到一种搜索主题的好方法，或者让用户将所有相关内容加载到 DOM 中（这也同样糟糕）。联合创始人之一给出了最好的建议，按两次。看来我们更聪明……
