以前无人关联的大胆添加链接:文本片段

通过文本片段,您可以在网址片段中指定文本片段。 当导航到包含此类文本片段的网址时,浏览器会强调 并/或引起用户的注意。

fragment 标识符

Chrome 80 是一个重大版本。它包含许多备受期待的功能, Web Worker 中的 ECMAScript 模块合并无效可选链等。和以往一样 通过 博文(在 Chromium 博客。您可以在下面的屏幕截图中查看该博文的摘录。

带有 id 属性的元素周围用红色方框圈住的 Chromium 博文。

你可能会问自己,所有这些红色方框都代表什么含义。它们是运行 以下代码段中。它会突出显示具有 id 属性的所有元素。

document.querySelectorAll('[id]').forEach((el) => {
  el.style.border = 'solid 2px red';
});

我可以放置指向任何用红色框突出显示的元素的深层链接,这要归功于 fragment 标识符 然后用于哈希 网页的网址。假设我希望深层链接到“请在我们的 产品论坛框中 我还可以手动编写网址 https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1。 正如您在开发者工具的“元素”面板中看到的,相关元素的 id 属性的值为 HTML1

显示元素的 id 的开发者工具。

如果使用 JavaScript 的 URL() 构造函数解析此网址,就会看到不同的组成部分。 请注意 hash 属性的值 #HTML1

new URL('https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1');
/* Creates a new `URL` object
URL {
  hash: "#HTML1"
  host: "blog.chromium.org"
  hostname: "blog.chromium.org"
  href: "https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1"
  origin: "https://blog.chromium.org"
  password: ""
  pathname: "/2019/12/chrome-80-content-indexing-es-modules.html"
  port: ""
  protocol: "https:"
  search: ""
  searchParams: URLSearchParams {}
  username: ""
}
*/

不过,我必须打开开发者工具来查找元素的 id,这很有说服力。 网页的这一特定部分 被链接至相关网页的作者的概率 这篇博文。

如果我想链接到的内容没有 id,该怎么办?假设我想链接到 ECMAScript 模块 “Web Workers”标题。如下面的屏幕截图所示,相关 <h1> 并非 具有 id 属性,这意味着我无法链接到此标题。这就是 通过文本片段解决问题。

开发者工具显示的标题中不含 id

文本片段

文本片段提案增加了对 在网址哈希值中指定文本片段。在导航到包含此类文本片段的网址时, 用户代理可以强调这一点并/或引起用户的注意。

浏览器兼容性

浏览器支持

  • Chrome:89。 <ph type="x-smartling-placeholder">
  • Edge:89。 <ph type="x-smartling-placeholder">
  • Firefox:不支持。 <ph type="x-smartling-placeholder">
  • Safari:不支持。 <ph type="x-smartling-placeholder">

来源

出于安全方面的考虑,该功能要求使用者在 noopener 上下文。 因此,请确保包含 rel="noopener"(在您的 <a>锚标记或添加 将noopener添加到您的 窗口功能功能的 Window.open() 列表。

start

文本片段的语法最简单的形式如下:哈希符号 #,后跟 :~:text=,最后是 start,它表示 百分比编码 文本。

#:~:text=start

例如,假设我想链接到 Web Workers 中的 ECMAScript Modules 标题, 发布 Chrome 80 各项功能的博文, 在这种情况下,网址为:

https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript%20Modules%20in%20Web%20Workers

文本片段的强调效果如下所示。 如果您在 Chrome 等支持性浏览器中点击链接,文本片段就会突出显示, 滚动至视图:

滚动到视图中并突出显示的文本片段。

startend

现在,如果我想要链接到整个部分(标题为 Web Workers 中的 ECMAScript 模块),该怎么办? 它的标题吗?对该部分的整个文本进行百分比编码后,得到的网址 长得不切实际

幸运的是,还有一种方法我可以使用 start,end 语法。因此,我在开头指定了几个百分号编码的单词, 并在末尾添加几个百分号编码的单词, 英文逗号 , 隔开。

如下所示:

https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript%20Modules%20in%20Web%20Workers,ES%20Modules%20in%20Web%20Workers.

对于 start,我先输入 ECMAScript%20Modules%20in%20Web%20Workers,后跟英文逗号 ,,后跟英文逗号 由ES%20Modules%20in%20Web%20Workers.end的身份提供。当您点击支持的浏览器时 与 Chrome 一样,整个部分都会突出显示并滚动到用户视野范围内:

滚动到视图中并突出显示的文本片段。

现在,您可能想知道我对 startend 的选择。短一点的网址 https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript%20Modules,Web%20Workers. 每侧只有两个单词也会有效果。将 startend 与以下内容进行比较: 先前的值。

如果我再更进一步,现在只针对 startend 使用一个字词,您可以 发现自己遇到了麻烦。网址 https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=ECMAScript,Workers. 比现在更短,但突出显示的文本片段已不再是最初所需的片段。通过 突出显示单词 Workers. 第一次出现时就停止了,这是正确的,但不是 。问题在于,所需部分并不能唯一地由 当前的单字 startend 值:

滚动到视野范围内并突出显示的意外文本片段。

prefix--suffix

startend 使用足够长的值是获取唯一链接的一种解决方案。 但在某些情况下是不可能的。另外,我为什么选择 是否以 Chrome 80 版本博文作为我的示例?答案是,在此版本中,文本片段 推出:

博文文字:文字网址片段。用户或作者现在可以使用网址中提供的文本片段链接到网页的特定部分。页面加载后,浏览器会突出显示该文本,并将 fragment 滚动到视图中。例如,下面的网址加载了一个关于“猫”的 Wiki 网页并滚动到 `text` 参数中列出的内容。
文本片段公告博文摘录。

请注意在屏幕截图中“text”一词的上方出现四次。第四种是 以绿色代码字体编写如果我想链接到这个特定字词,则应将 starttext。由于单词“text”只有一个字词,但不可以是 end。接下来该怎么做?通过 网址 https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=text 在单词“Text”首次出现时匹配已在标题中:

在“Text”首次出现时匹配文本片段。

幸运的是,有个解决方案在这种情况下,我可以指定 prefix​--suffix。通过 绿色代码字体“text”前面的字词是“the”,后面的字词是“parameter”。以上均不是 单词“text”的另外三次出现周围有相同的字词。配备此武器 因此我可以调整上一个网址并添加 prefix--suffix。与其他 参数,它们也必须进行百分比编码,并且可以包含多个字词。 https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=the-,text,-parameter。 为了让解析器明确识别 prefix--suffix,需要将两者分开 从 start 开始,以及可选用带短划线 -end

文本片段在期望的“文本”出现处匹配。

完整语法

文本片段的完整语法如下所示。(方括号表示可选参数。) 所有参数的值都需要进行百分比编码。这对于 -、和号 & 和英文逗号 , 字符,因此系统不会将其解释为文字的一部分 指令语法。

#:~:text=[prefix-,]start[,end][,-suffix]

prefix-startend-suffix 将仅匹配单个 块级元素、 但完整的 start,end 范围可以跨越多个块。例如: :~:text=The quick,lazy dog 在下例中将无法匹配,因为开始 字符串“The quick”不会出现在单个不间断的块级元素中:

<div>
  The
  <div></div>
  quick brown fox
</div>
<div>jumped over the lazy dog</div>

不过,它与下面的示例匹配:

<div>The quick brown fox</div>
<div>jumped over the lazy dog</div>

使用浏览器扩展程序创建文本片段网址

手动创建文本片段网址是一项繁琐的工作,尤其是在确保网址 唯一。如果您确实想了解,该规范中提供了一些提示,并列出了 生成文本片段网址的步骤。 我们提供了一个名为 文本片段链接 通过选择任意文本,然后点击“将链接复制到选定文本”来链接到该文本在上下文中 菜单。此扩展程序适用于以下浏览器:

。 <ph type="x-smartling-placeholder">
</ph>
指向文本片段的链接 浏览器扩展程序。

一个网址中的多个文本片段

请注意,一个网址中可以显示多个文本片段。特定文本片段需要 以 & 字符 & 分隔。下面是一个包含三个文本片段的示例链接: https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#:~:text=Text%20URL%20Fragments&text=text,-parameter&text=:~:text=On%20islands,%20birds%20can%20contribute%20as%20much%20as%2060%25%20of%20a%20cat's%20diet

一个网址中三个文本片段。

混合元素和文本片段

传统的元素片段可以与文本片段结合在一起。最好同时设置 例如,针对网页上的原始文本提供有意义的后备内容 更改,使文本片段不再匹配。网址 https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1:~:text=Give%20us%20feedback%20in%20our%20Product%20Forums. 点击此链接可访问我们的 产品论坛版块 包含元素 fragment (HTML1) 以及文本 fragment (text=Give%20us%20feedback%20in%20our%20Product%20Forums.):

同时与元素片段和文本片段建立链接。

fragment 指令

语法中还有一个元素我尚未解释,那就是片段指令 :~:。为避免 现有的网址元素片段存在兼容性问题(如上所示), 文本 Fragment 规范中引入了 Fragment 指令。片段指令是网址片段的一部分,由代码序列分隔 :~:。它是为用户代理指令(例如 text=)预留的,并且已从网址中删除 以免作者脚本直接与之交互用户代理说明如下: (也称为指令)。因此,在具体情况下,text= 称为文本指令

功能检测

如需检测支持情况,请在 document 上测试只读 fragmentDirective 属性。fragment 指令是一种机制,可让网址指定针对浏览器而非 文档。它用于避免与作者脚本的直接交互,以便将来的用户代理 添加说明,无需担心对现有内容引入破坏性更改。一个 例如,翻译提示就可能属于此类未来添加内容。

if ('fragmentDirective' in document) {
  // Text Fragments is supported.
}

功能检测主要用于动态生成链接的情况(例如 搜索引擎),以免将文本片段链接提供给不支持它们的浏览器。

设置文本 fragment 的样式

默认情况下,浏览器会按照其样式设置文本片段的样式 mark(通常为黄色底黑字, CSS 系统颜色 (针对 mark)。用户代理样式表包含如下所示的 CSS:

:root::target-text {
  color: MarkText;
  background: Mark;
}

如您所见,浏览器提供了一个伪选择器 ::target-text,可用于: 自定义已应用的突出显示。例如,您可以将文本片段设计为黑色 红色背景上的文字与往常一样,请务必 检查色彩对比度 因此您的替换样式不会导致无障碍功能问题,并确保突出显示 在视觉上与其余内容明显区分开来。

:root::target-text {
  color: black;
  background-color: red;
}

可填充性

文本片段功能可在某种程度上执行 polyfill 操作。我们提供了 polyfill,供内部 扩展程序,适用于不支持 提供对文本片段的内置支持,其中功能在 JavaScript 中实现。

polyfill 包含一个文件 fragment-generation-utils.js,您可以导入并使用它来生成文本片段链接。这是 如以下代码示例所示:

const { generateFragment } = await import('https://unpkg.com/text-fragments-polyfill/dist/fragment-generation-utils.js');
const result = generateFragment(window.getSelection());
if (result.status === 0) {
  let url = `${location.origin}${location.pathname}${location.search}`;
  const fragment = result.fragment;
  const prefix = fragment.prefix ?
    `${encodeURIComponent(fragment.prefix)}-,` :
    '';
  const suffix = fragment.suffix ?
    `,-${encodeURIComponent(fragment.suffix)}` :
    '';
  const start = encodeURIComponent(fragment.textStart);
  const end = fragment.textEnd ?
    `,${encodeURIComponent(fragment.textEnd)}` :
    '';
  url += `#:~:text=${prefix}${start}${end}${suffix}`;
  console.log(url);
}

获取文本片段以进行分析

许多网站使用片段进行路由,因此浏览器会剥离文本片段 以免破坏这些网页这里有 已确认的需求 将文本片段链接公开,以便进行分析、 但建议的解决方案尚未实施。 作为暂时的解决方法,您可以使用以下代码 所需的信息

new URL(performance.getEntries().find(({ type }) => type === 'navigate').name).hash;

安全

文本片段指令仅在完整(非同一网页)导航中调用 a 用户激活。 此外,如果导航的起点与终点不同,则需要 应该在 noopener 上下文,如 确认目标网页已充分隔离。文本片段指令 应用到主框架也就是说,系统不会在 iframe 内搜索文本, 导航不会调用文本片段。

隐私权

文本片段规范的实现不能泄露文本 是否在网页上找到 fragment。虽然元素片段完全在 网页原创作者,那么任何人都可以创建文本片段。还记得吗,在上例中, 无法链接到 ECMAScript Modules in Web Workers 标题,因为 <h1> 没有 id,但是任何人(包括我在)内都可以通过精心制作的链接 文本片段?

假设我投放了恶意广告联盟 evil-ads.example.com。再假设,在我的某个广告 iframes 我使用文本向 dating.example.com 动态创建了隐藏的跨源 iframe 片段网址 dating.example.com#:~:text=Log%20Out 当用户与广告互动时触发。如果显示“退出”我知道受害者目前 登录到 dating.example.com,我可以用它来进行用户分析。由于原始文本 fragment 实现可能会决定成功的匹配应触发焦点切换, evil-ads.example.com我可以监听 blur 事件,从而知道何时发生匹配。在 我们在 Chrome 中实现文本片段的方式避免了上述情况。

另一种攻击可能是根据滚动位置利用网络流量。假设我有权访问 受害者的网络流量日志,例如作为公司内网的管理员现在想象一下 之前就有一篇很长的人力资源文档《如果你遭受...的痛苦该怎么办...》,以及一份列表, 倦怠焦虑等症状。我可以在每个商品旁放置一个跟踪像素, 列表。如果我确定文档加载与 跟踪像素(例如倦怠项目),然后作为内网管理员,我可以确定 某员工点击了包含 :~:text=burn%20out 的文本片段链接, 会认为是机密内容,不对任何人显示。由于此示例与 Chrome 安全团队评估了在导航中实施滚动操作的风险,这是可管理的。 其他用户代理可能会决定改为显示手动滚动界面元素。

对于希望停用此功能的网站,Chromium 支持 文档政策 标头值,这样用户代理就不会处理文本片段网址。

Document-Policy: force-load-at-top

停用文本片段

停用该功能的最简单方法是使用可以注入 HTTP 响应的扩展程序 标头,例如 ModHeader (不是 Google 产品)插入响应(不是请求)标头,如下所示:

Document-Policy: force-load-at-top

另一个更复杂的方法是使用企业设置 ScrollToTextFragmentEnabled。 如需在 macOS 上执行此操作,请将以下命令粘贴到终端中。

defaults write com.google.Chrome ScrollToTextFragmentEnabled -bool false

在 Windows 上,请按照 Google Chrome 企业版帮助支持 网站。

对于某些搜索,搜索引擎 Google 会提供快速解答或摘要,其中会包含 从相关网站中摘录的代码段。这些精选摘要最有可能在用户搜索 问题的形式。点击精选摘要会直接转到精选摘要 来源网页上的摘要文字。这要归功于自动创建的文本片段网址。

显示精选摘要的 Google 搜索引擎搜索结果页。状态栏会显示文本片段网址。
。 <ph type="x-smartling-placeholder">
</ph>
点击后,页面的相关部分就会滚动到用户视野范围内。

总结

文本片段网址是一项强大的功能,可链接到网页上任意文本。《The Scholarly》 社区可以用它来提供高度准确的引用或参考链接。搜索引擎可以使用 深层链接到网页上的文字结果。社交网站可以用它来让用户分享内容 网页的具体段落,而不是显示无法访问的屏幕截图。希望你开始 使用文本片段网址 发现它们跟我一样有用请务必将 链接到文本片段浏览器 。

致谢

文本片段是由 Nick Burris 实现和指定的, David Bokan,来自 Grant Wang。感谢 Joe Medley 请仔细阅读本文中的详细内容。Greg Rakozy 提供的主打图片 不启动