MarkIt 螢光筆
這是一個 Chrome 擴充功能鏈接,可讓您突出顯示任何網頁上的重要文字。在 1 分鐘、1 週或 1 年內重新造訪該頁面 - 您的資料將始終存在。
科技
- (原版)JavaScript
- 谷歌應用程式介面
特徵
- 反白顯示任何文字並按 Command+K 自動儲存
- 使用者可以透過一個簡單的命令(Command+Shift+A)清除任何 URL 的儲存突出顯示
- 在所有裝置上同步 - 如果您在筆記型電腦上突出顯示文本,然後在手機上查看同一網頁,您的突出顯示就會在那裡(如果您在兩台裝置上都登入了 Chrome)。
我儲存的資料結構(對象)
highlights = {
google.com: {
text1: ["query selector", index, note, color]
text2: ["query selector", index, note, color]
},
yahoo.com: {
text3: ["query selector", index, note, color],
text4: ["query selector", index, note, color]
},
https://developer.mozilla.org/en-US/docs/Web/API/document/execCommand: {
"When an HTML document has been switched to designMode, its document object exposes an execCommand": ["p.summary", 20],
"A DOMString specifying the name of the command to execute. See Commands for a list of possible commands.": ["p", 0, "example note", #CFFFDF]
}
}
它是如何運作的
我有兩個腳本加載在每個頁面上。第一個是background.js,它監聽特定事件。 Command+K 事件觸發函數,將腳本注入瀏覽器 (injection_script.js),突出顯示所選文字。
若要反白顯示,請將滑鼠拖曳到某些文字上,然後按 Command+K。這會觸發一個呼叫其他幾個函數的函數。事件順序:
- 抓取選定的文本
- 「開啟」設計模式,讓我們可以對 DOM 進行臨時更改
- 如果背景已經突出顯示,那麼我們需要刪除突出顯示:
- 選擇文字周圍的<span>標籤並設定style.backgroundColor=透明(移除反白)
- 從儲存中取得「亮點」物件 -
chrome.storage.get()
- 循環遍歷所有鍵(即儲存的突出顯示)以查找匹配項,並將其從儲存中刪除
- 否則,將文字包裹在 <span> 中並套用背景顏色
- 頁面刷新時:從儲存中檢索“亮點”
- 如果活動 URL 沒有數據,則將鍵設為目前 URL,將值設為空物件 (aol.com: {})
- 如果有,從儲存中取得高亮資料結構(chrome.storage.get())
- 為所選文字擷取並指派有效的查詢選擇器值(這將用於查詢 DOM 並稍後套用突出顯示。請參閱上面的物件結構以進行說明)
- 如果反白文字的父元素有類別名,則儲存字串「element.className」(「p.firstParagraph」、「h2.sectionHeader」等)
- 如果沒有類別名,則儲存字串「element」(「p」、「h2」、「li」等)
- 為鍵(反白的文字)提供一個值(包含 2 個值的陣列 - 第一個是查詢選擇器,第二個是所選文字在父元素中出現的位置的索引)
- 我儲存字串的索引,因為如果我只儲存文字和查詢選擇器,假設您在“p”標籤下突出顯示了“the”,那麼在刷新頁面時應用突出顯示時,“the”的每次出現都會在“p”標籤下突出顯示。添加 indexOf 值可以讓我驗證索引是否與 DOM 匹配,然後才應用突出顯示,因此我將突出顯示應用到正確的單字。
- 使用 chrome.storage.set() 儲存包含新反白文字的更新後的反白變數
- “關閉”設計模式
每個頁面上運行的第二個 JavaScript 檔案是 content_script.js。它檢查是否存在名為“highlights”的儲存物件。如果沒有,則表示用戶從未突出顯示任何內容。然後它會建立一個空物件並將其儲存在 Chrome 中。
如果它找到「突出顯示」對象,則會檢查是否儲存了活動 URL 的資料。如果不存在,腳本將傳回。
如果該 URL 儲存了突出顯示:
- applyHighlights() 函式運行
- 它需要兩個參數,「highlights」物件和活動 URL
- 循環存取儲存物件的鍵(鍵是儲存的突出顯示,而這些鍵的值是包含 querySelector 和 indexOf 值的陣列)
- 運行 document.body.querySelectorAll() 以取得所有匹配節點的數組
- 循環遍歷每個傳回的節點,如果innerHTML包含與物件鍵(突出顯示的文字)匹配的「字串」並且具有相同的indexOf值: 1. 運行.replace() 函數,將匹配的文字包裝在<span > 標記中,並使用背景顏色的內聯樣式屬性
- 附註:我最初遞歸地遍歷每個 DOM 節點來檢查匹配項,但存儲 querySelector 值並將僅匹配節點的 HTML 值與我存儲的值進行比較要快得多。
下一版的升級
- 儲存您突出顯示的特定字串
- 「從 jQuery.com 下載 jQuery 函式庫」。
- 如果反白顯示第二個“jQuery”,則儲存的值將是第一個實例的值。
- 這是因為我存儲的 indexOf 值在第一個匹配後返回
- PLAN - 開始計算跨距標籤後的索引
- 無法跨區塊元素突出顯示(如果將突出顯示從 h2 拖曳到 ap 標記中,則只有 h2 會註冊)
- 進行中:允許使用者選擇突出顯示顏色
- 在擴展 popup.html 中顯示頁面的突出顯示數量和實際突出顯示數量
- 限制/邊緣情況:電子郵件、PDF
- 我請求每個網站的權限。有些網站阻止「*」訪問 (cnn.com)
- 如果您在一個元素中突出顯示“jQuery”,則在另一個元素中再次突出顯示它,第二個元素將覆蓋第一個元素(因為鍵相同)
- 如果父元素是內聯標籤,則innertext/html indexOf不會註冊(-1),或者它在內聯標籤末尾結束突出顯示找到span標籤的索引並在那裡開始indexOf
- 折疊模式 - 將文件折疊到僅儲存突出顯示的父元素
已解決的問題
- 儲存跨越內聯元素標籤(a、em、st 等)的突出顯示
- 之前,只保存了內聯標籤之前的文本,因為我存儲了innerText
- 我透過儲存innerHTML 解決了這個問題
- 此更改引起的問題是我存儲了innerText的indexOf,這會將突出顯示重新應用到文本元素內的標準文本,例如“p”標籤。但是對於內聯元素周圍的項目,indexOf 是不同的,因為indexOf 計算標籤中的每個字元。
- 為了解決這個問題,我比較了innerText.indexOf 和innerHTML.indexOf 值,並在將突出顯示應用於用戶再次訪問的頁面時將每個值與匹配節點進行比較。
- 如果您雙擊以突出顯示某個部分,則 indexOf 值將不會註冊,因此我的應用程式無法重新套用突出顯示
- 為了解決這個問題,我將 .toString() 和 .trim() 方法加入 indexOf(...)
- 反白 < a > 標記將刪除頁面載入時的連結。
未來的升級
## 範例圖像
邊緣情況
- 如果類別名稱改變
- 解決方案:如果類別名稱在DOM中不存在,則從查詢選擇器中移除類別名,只搜尋元素標籤節點
- 如果內容被按鈕隱藏,我的突出顯示將不會註冊,因為它會搜尋 on_load 並且內容僅在瀏覽器事件後顯示(這就是它不適用於電子郵件的原因)
允許某人存取 popup.html 上的所有突出顯示 允許使用者更改突出顯示顏色 修復內聯元素突出顯示錯誤