以大膽連結的方式沒有任何人連結:文字片段

「文字片段」可讓您在網址片段中指定文字片段。 當瀏覽器導向含有這類文字片段的網址時,可以強調並/或將其帶到使用者的注意力。

片段 ID

Chrome 80 版本是重大版本,其中包含許多備受期待的功能,例如 Web Workers 中的 ECMAScript 模組空值合併選用鏈結等等。這邊的版本跟往常一樣 透過 網誌文章 Chromium 網誌。請參閱下方螢幕截圖,瞭解網誌文章的摘要。

Chromium 網誌文章含有紅色方塊,其中含有 id 屬性。

您可能會想知道所有紅色方塊代表什麼。這些是開發人員工具中執行下列程式碼片段的結果。它會醒目顯示所有具有 id 屬性的元素。

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

我也可以插入任何以紅色方塊醒目顯示的元素深層連結 片段 ID 以便我將這項功能用於 指定網頁網址如果要開啟「提供意見」連結, 「產品論壇」方塊 我也可以手動把網址 https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html#HTML1。 如您在「開發人員工具」的「元素」面板中看到的,問題元素含有值為 HTML1id 屬性。

開發人員工具顯示元素的 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 Modules in Web Workers」標題。如您在下方螢幕截圖中所見,問題中的 <h1> 沒有 id 屬性,也就是說,我無法連結至這個標題。這就是問題所在 文字片段解析。

開發人員工具顯示標題,但沒有 id

文字片段

文字片段提案新增了在網址雜湊中指定文字片段的支援功能。瀏覽至含有這類文字片段的網址時, 使用者代理程式可以強調和/或吸引使用者的注意力

瀏覽器相容性

瀏覽器支援

  • Chrome:89。
  • Edge:89。
  • Firefox:131。
  • Safari 技術預覽:支援。

資料來源

基於安全性,這項功能規定使用者必須在 noopener 背景資訊。 因此,請務必在 <a> 錨點標記中加入 rel="noopener",或是將 noopener 新增至窗口功能功能的 Window.open() 清單。

start

簡單來說,文字片段的語法如下:井字號 # 後面接著 :~:text=,最後是 start,代表我要連結的百分比編碼文字。

#:~:text=start

舉例來說,假設我想連結至「Web Workers 中的 ECMAScript 模組」標題 發表 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 發布網誌文章做為範例?答案是,這個版本推出了文字片段:

網誌文章文字:文字網址片段。使用者或作者現在可以使用網址中提供的文字片段,連結到網頁的特定部分。載入網頁時,瀏覽器會醒目顯示文字,並捲動片段至檢視畫面中。舉例來說,下方的網址會載入「Cat」的 Wiki 頁面,並捲動至 `text` 參數中列出的內容。
Text Fragments 公告網誌文章摘錄。

請注意螢幕截圖中的「text」字樣出現 4 次第 4 次 綠色程式碼字型如果要連結這個特定字詞,將 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>

使用瀏覽器擴充功能建立文字片段網址

手動建立文字片段網址相當繁瑣,尤其是在確保網址不重複時。如果您真的想這麼做,規格說明書提供一些提示,並列出產生文字片段網址的確切步驟。我們提供一個名為 Link to Text Fragment 的開源瀏覽器擴充功能,可讓您選取任何文字,然後在內容選單中按一下「Copy Link to Selected Text」(複製所選文字的連結),即可連結至任何文字。這項擴充功能適用於下列瀏覽器:

連結至文字片段 瀏覽器擴充功能。

使用同一個網址處理多個文字片段

請注意,一個網址中可能會出現多個文字片段。特定的文字片段 並以 & 字元分隔。以下是包含三個文字片段的連結範例: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. 請到這裡的「請提供寶貴意見」連結 產品論壇專區 包含元素片段 (HTML1) 和文字片段 (text=Give%20us%20feedback%20in%20our%20Product%20Forums.):

連結元素片段和文字片段。

片段指令

還有一個語法元素尚未說明:片段指令 :~:。如上所述,為避免與現有網址元素片段的相容性問題,文字片段規格引入了片段指示詞。片段指令是網址片段的一部分,由程式碼序列 :~: 分隔。這個值會保留用於使用者代理程式操作說明 (例如 text=),並從網址中移除 載入期間,因此作者指令碼無法直接與它互動。使用者代理程式操作說明如下 (也稱為指令)。在具體案例中,text= 因此稱為「文字指令」

特徵偵測

如要偵測支援情形,請測試 document 上的唯讀 fragmentDirective 屬性。片段指令是一種機制,可讓網址指定指向瀏覽器的指令,而非指向文件。避免與作者指令碼直接互動,因此日後的使用者代理程式 並附上任何指示,不必擔心會對現有內容造成破壞性變更。一 像是翻譯提示等等

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

功能偵測主要適用於動態產生連結 (例如 搜尋引擎),避免將文字片段連結至不支援這類程式碼的瀏覽器。

設定文字片段樣式

根據預設,瀏覽器會以與 mark 相同的方式設定文字片段樣式 (通常是黑底黃字,這是 mark 的 CSS 系統顏色)。使用者代理程式樣式表包含的 CSS 如下所示:

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

如您所見,瀏覽器會公開一個虛擬選取器 ::target-text,您可以使用該選取器自訂套用的醒目顯示效果。舉例來說,您可以將文字片段設計成黑色 並排顯示紅色背景的文字如常,請務必檢查色彩對比,確保覆寫樣式不會導致無障礙問題,並確保醒目顯示內容在視覺上與其他內容有所區隔。

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

多元包容性

文字片段功能在某些程度上可以進行折線填滿。我們提供 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;

安全性

只有在使用者啟用的結果為完整 (非同頁) 導覽時,才會叫用文字片段指示詞。此外,如果導覽的來源與目的地不同,則導覽必須在 noopener 情境中進行,以便確保目的地網頁已充分隔離。只有文字片段指令 已套用至主影格也就是說,系統不會在 iframe 內搜尋文字,且 iframe 導覽不會叫用文字片段。

隱私權

請務必確保 Text Fragments 規格的實作不會洩漏文字 網頁上是否有片段。雖然元素片段完全由 任何人都可以建立文字片段;在我的範例中,還記得 沒有辦法連結至 Web Workers 中的 ECMAScript 模組標題,因為 <h1> 沒有 id,但任何人 (包括我在內) 都能透過精心打造 文字片段?

假設我放送了一個邪惡廣告聯播網,evil-ads.example.com。再想想,如果我在其中一個廣告 iframe 中動態建立隱藏的跨來源 iframe,並在使用者與廣告互動時,使用文字片段網址 dating.example.com#:~:text=Log%20Out dating.example.com。如果發現「Log Out」文字,就表示受害者目前已登入 dating.example.com,可用於建立使用者設定檔。由於簡單的 Text Fragment 實作可能會判斷成功比對應應造成聚焦切換,因此我在 evil-ads.example.com 上監聽 blur 事件,進而瞭解何時發生比對。在 Chrome 中,我們已實作文字片段,以避免發生上述情況。

另一種攻擊方式是根據捲動位置來利用網路流量。假設我能夠 受害者的網路流量記錄,例如公司內部網路的管理員。假設有一份冗長的人力資源文件,標題為「如果您有以下症狀,該怎麼辦?」,接著列出一系列狀況,例如「倦怠」、「焦慮」等。我可以將追蹤像素放在清單上的每個項目旁邊。如果我判斷文件載入作業與「burn out」項目旁的追蹤像素載入作業同時發生,我就可以判斷內部網路管理員已點選含有 :~:text=burn%20out 的文字片段連結,而該員工可能認為該連結是機密資訊,不應讓任何人看到。因為這個範例 問題持續發生,因為入侵行為需要符合非常的特定先決條件。 Chrome 安全性團隊進行評估,評估是否導入捲動導覽功能的風險。 其他使用者代理程式可能會決定改為顯示手動捲動的 UI 元素。

對於希望停用的網站,Chromium 支援可傳送的 Document Policy 標頭值,這樣使用者代理程式就不會處理文字片段網址。

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 Enterprise 說明支援網站上的說明文件操作。

在某些情況下,Google 搜尋引擎會針對搜尋內容提供快速解答或摘要,並附上相關網站的內容片段。一般來說,這類精選摘要最可能在以問句形式進行搜尋時出現。按一下精選摘要後,系統會將使用者直接導向精選摘要 來源網頁上的摘要文字這都要歸功於自動建立的文字片段網址。

Google 搜尋引擎結果頁面顯示精選摘要。狀態列會顯示「文字片段網址」。
,瞭解如何調查及移除這項存取權。
點選連結後,捲動至頁面上的相關部分。

結論

文字片段網址是強大的功能,可連結至網頁上的任意文字。學術 社群也能使用它來提供非常準確的引文或參考連結。搜尋引擎 藉此建立網頁上文字搜尋結果的深層連結。社群網站可以使用這項功能,讓使用者分享網頁的特定段落,而非無法存取的螢幕截圖。希望您能開始使用文字片段網址,並發現這些網址和我一樣實用。請務必安裝文字片段連結瀏覽器擴充功能。

特別銘謝

文字片段是由 Nick BurrisDavid Bokan 實作及指定,Grant Wang 也對此做出貢獻。感謝 Joe Medley 仔細審查本文。主頁橫幅由 Greg Rakozy 提供 Unsplash