URL Scroll-To-Text Fragment

1,473 阅读7分钟

前言

近期Chrome更新带来很多新东西,比如标签移动,新建组,阅读清单,标签页搜索功能,以及在Chrome90版本转正的功能【分享特定的文本内容】,超级惊艳的效果,为我们带来更佳友好的使用体验。本文就重点介绍一下这个新特性,它最早于2020年6月提出,以内容扩展的形式存在。现在我们可以在新版浏览器上正式使用它,先看看下面这个场景。

使用场景

某天,我正在专心摸鱼,看见一件趣事,我想把它分享给咩咩同学,我应该怎么办?

作为高级的 ctrl cv 工程师,当然是复制粘贴发送三连呐。

不过很糟糕的是,我必须附着一些信息,在第 XXX 段落,标题是 XXX。

可是有了text fragment后,事情就简单啦,选中想分享的内容,然后右键选择【复制指向突出显示的内容的链接】,三连。当咩咩同学打开链接的时候,就会很准确的看到我想让其看到的内容。

快速体验

如果你还没有升级到 Chrome90版本(目前是小流量),可以手动开启功能。

浏览器打开下面地址,然后设置Copy Link To TextEnabled,并重启浏览器。

chrome://flags/#copy-link-to-text

image.png

点点看

来吧年轻人,点我

当我们点开链接后,发现navigating to a URL被默认选中并高亮 image.png

右键菜单变化

image.png

特殊的 url 格式

#:~:text=URL%20fragment.%20When-,navigating%20to%20a%20URL,-with%20such%20a

更多应用场景

我们在产品开发中,经常会遇到链接跳转的需求,通常,我们使用锚点方式(hash#)来实现定位,有时候这种方式不能很准确的表达出来,而使用text fragment就可以顺利解决。

带文本的链接跳转

点点看,是不是特别酷。

image.png

我们再考虑另外一个场景

我们在使用搜索引擎,查找某个 case 的时,通常在结果页都会有关键词提示,但当我们点击链接进入页面后,我们就不知道我们寻找的 keyword 它在哪,就不得不再一次的 Ctrl F 搜索,很麻烦。如果在点击链接后,结果页面自动帮我们高亮提示并定位到目标位置,就很舒服。(可以参照下面 &character 的例子)

浏览器支持

语法中有:~:text=这样的片段,它的名字叫Scroll To Text Fragment

URL fragment that defines a piece of text to be scrolled into view and highlighted.

image.png

目前只能体验功能,还不能正式投入到生产环境,Firefox,Safari等浏览器尚未支持。

语法结构

https://example.com#:~:text=prefix-,startText,endText,-suffix


:~:text=[prefix-,]textStart[,textEnd][,-suffix]

         context  |-------match-----|  context

文本参数在匹配前需要解码,保证语法结构符号(- & ,)被正确解读。

方括号中的内容均是可选的,只有textStart是必选内容。

textStart

最简用法:~:text=startText,可以在 url 后手动增加参数,指定任意内容。

1. 来个普普通通的 url
https://fuchunhui.github.io/copy-link-text/

2.要定位到某个地方,需要有 hash
https://fuchunhui.github.io/copy-link-text/#

3.接下来把我们的小可爱`:~:text=`加上
https://fuchunhui.github.io/copy-link-text/#:~:text=

4.最后的最后,我们要让哪块文字高亮,就把它编码后加到最后
https://fuchunhui.github.io/copy-link-text/#:~:text=Copy%20URL%20to%20here

我是上面步骤4的 url,点我试试

对于有很多重复内容的页面,如果仅仅指定了 textStart,那么第一个匹配到的内容会被高亮。

重复文本高亮

textEnd

同时使用 textStart 和 textEnd,就可以指定一段文本。匹配规则是从符合 textStart 的第一段文字开始,到符合 textEnd 的第一段文字结束,这样设计的好处是可以节省 url参数长度。

来看个例子

:~:text=textStart,textEnd(中间写上逗号,就是选择一段)
我们从“郁孤台下清江水”开始,结尾到“长安”,会命中“西北望长安”而不是“长安一片月”

#:~:text=郁孤台下清江水,长安

image.png

另外,textEnd 的使用,要明确有意义。

#:~:text=Windows, Linux

这个的语法结构是什么?

:~:text=textStart,textEnd
:~:text=textStart

这两种解释都说的通

prefix- and -suffix

再看刚刚的例子,如果要匹配“长安一片月”的长安这两个字,该怎么办?

此时需要增加前缀和后缀,来看看 url 格式

:~:text=prefix-,textStart,-suffix

#:~:text=唐·李白-,长安,-一片月,万户

长安一片月的长安

"&" character

春风得意马蹄疾,一日看尽长安花。

如果想要提示多个文本怎么办?例如把所有长安都重点提示,我们需要使用&操作符

命中多个“长安”

#:~:text=长安&text=一片月”的-,长安,-选中多个&text=西北望-,长安,-,可怜无数&text=李白-,长安,-一片月

看下这段url 结构,等同于

#:~:
text=长安
&text=一片月”的-,长安,-选中多个
&text=西北望-,长安,-,可怜无数
&text=李白-,长安,-一片月

可以命中四个“长安”

image.png

fragment directive

前文提到的小可爱(:~:),它真正的名字为Fragment Directive Delimiter

The fragment directive delimiter is the string ":~:", that is the three consecutive code points U+003A (:), U+007E (~), U+003A (:).

fragment directive 属于 url 的一部分内容,紧跟着小可爱后的内容,就是片段指令,上述 multiple 的例子(多个长安的例子),就是多个片段指令由&连接符组成的。

为了防止影响页面操作,文本片段主要响应在 UA 中,滚动屏幕,高亮提示就会消失,当我们选中很大一段文本的时候,也可能出现看不完整的场景。

目前的Chrome浏览器实现在 Location 对象中,尚未记录 directive 的内容。

image.png

quick fox and lazy dog

算法在匹配文本的过程中,匹配的文本及其前缀/后缀可以跨越块边界,但是这些独立的各个参数不能跨块。就是说,prefix,textStart,textEnd和suffix对应的值必须是单个块内的文本内容。

单个块内的文本匹配

<article>
  <p>The<p> </p>quick brown fox</p>
  <p>jumped over the lazy dog. (p 分隔)</p>
</article>
<article>
  <p>The<span> </span>quick brown fox</p>
  <p>jumped over the lazy dog. (span 分隔)</p>
</article>

image.png

起始的字符串“The quick”在两个示例中都有,但是上面的例子,在Thequick中间是 block 元素,所以没有匹配成功,而下面的例子,是单个不间断的块,匹配成功。

补充说明

  • 大小写不敏感(可通过 quick fox and lazy dog 的例子测试,把The修改成the

  • 必须完整切词,不能截断单词。

The substring "mountain range" is word bounded within the string "An impressive mountain range" but not within "An impressive mountain ranger".

  • 高亮的文本内容,不会被背景色和文字颜色覆盖,这一点是毫无疑问的。人间有味是清欢

  • 文本变化了怎么解决?如果匹配不到内容,就不匹配。(在产品上运用要多多注意,这是体验上的bug)

  • 滚屏就消失,只有首次打开页面才有,仅提示一次。同时一屏内放不下的内容会看不到,因为滚动下屏幕高亮就消失了(所以高亮提示的内容不应该太多,太多也不符合功能设计初衷)。

  • 不是所有的页面都支持解析。例如 can i use 上就不能高亮提示,需要与语法解析配合使用。

项目地址

本文代码的完整地址请移步:copy link text

在线体验地址:copy link text

参考资料