find.find()
在標籤頁中搜索文字。
您可以使用此函式搜尋常規的 HTTP(S) 網頁。它搜尋單個標籤頁:您可以指定要搜尋的特定標籤頁的 ID,否則預設搜尋活動標籤頁。它會搜尋標籤頁中的所有框架。
您可以使搜尋區分大小寫,並使其僅匹配整個單詞。
預設情況下,該函式僅返回找到的匹配項數量。透過傳入 includeRangeData 和 includeRectData 選項,您可以獲取有關目標標籤頁中匹配項位置的更多資訊。
此函式將結果儲存在內部,因此下次任何擴充套件程式呼叫 find.highlightResults() 時,此次 find 呼叫將突出顯示其結果,直到下次有人呼叫 find()。
這是一個非同步函式,返回一個 Promise。
語法
browser.find.find(
queryPhrase, // string
options // optional object
)
引數
options可選-
object。一個指定附加選項的物件。它可以包含以下任意屬性,所有屬性都是可選的。caseSensitive-
boolean。如果為true,則搜尋區分大小寫。預設為false。 entireWord-
boolean。僅匹配整個單詞:因此,“Tok”不會在“Tokyo”中匹配。預設為false。 includeRangeData-
boolean。在響應中包含 range 資料,它描述了在頁面 DOM 中找到匹配項的位置。預設為false。 includeRectData-
boolean。在響應中包含 rect 資料,它描述了在渲染頁面中找到匹配項的位置。預設為false。 matchDiacritics-
boolean。如果為true,則搜尋區分帶重音符號的字母及其基本字母。例如,當設定為true時,搜尋“résumé”不會匹配“resume”。預設為false。 tabId-
integer。要搜尋的標籤頁的 ID。預設為活動標籤頁。
queryPhrase-
string。要搜尋的文字。
返回值
一個 Promise,它將以包含最多三個屬性的物件來 fulfilled。
計數-
integer。找到的結果數量。 rangeData可選-
array。如果在options引數中指定了includeRangeData,則將包含此屬性。它以RangeData物件陣列的形式提供,每個匹配項一個。每個RangeData物件描述了在 DOM 樹中找到匹配項的位置。例如,這可以使擴充套件程式獲取每個匹配項周圍的文字,以便為匹配項顯示上下文。專案對應於
rectData中提供的專案,因此rangeData[i]描述的匹配項與rectData[i]相同。每個
RangeData包含以下屬性:endOffset-
匹配項在其文字節點中的結束位置。
endTextNodePos-
匹配項結束的文字節點的順序位置。
framePos-
包含匹配項的框架的索引。0 對應於父視窗。請注意,
rangeData陣列中物件的順序將按幀索引的順序依次排列:例如,第一系列rangeData物件的framePos將是 0,下一系列的framePos將是 1,依此類推。 起始偏移-
匹配項在其文字節點中的開始位置。
startTextNodePos-
匹配項開始的文字節點的順序位置。
rectData可選-
array。如果在options引數中指定了includeRectData,則將包含此屬性。它是一個RectData物件陣列。它包含搜尋中匹配的所有文字的客戶端矩形,相對於視口左上角。擴充套件程式可以使用此來為結果提供自定義高亮顯示。每個
RectData物件包含單個匹配項的矩形資料。它有兩個屬性:rectsAndTexts-
一個包含兩個屬性的物件,兩者都是陣列:
rectList:一個物件陣列,每個物件都有四個整數屬性:top、left、bottom、right。這些描述了相對於視口左上角的矩形。textList:一個字串陣列,對應於rectList陣列。textList[i]中的條目包含由rectList[i]中的矩形所界定的匹配項部分。
例如,考慮網頁的一部分如下所示:

如果搜尋“You may”,則匹配項需要由兩個矩形描述:

在這種情況下,在描述此匹配項的
RectData中,rectsAndTexts.rectList和rectsAndTexts.textList都將有 2 個專案。textList[0]將包含“You ”,而rectList[0]將包含其邊界矩形。textList[1]將包含“may”,而rectList[1]將包含其邊界矩形。
文字-
匹配項的完整文字,“You may”,如上例所示。
示例
基本示例
在活動標籤頁中搜索“banana”,記錄匹配項數量,並突出顯示它們。
function found(results) {
console.log(`There were: ${results.count} matches.`);
if (results.count > 0) {
browser.find.highlightResults();
}
}
browser.find.find("banana").then(found);
在所有標籤頁中搜索“banana”(請注意,這需要“tabs” 許可權或匹配的 主機許可權,因為它訪問 tab.url)。
async function findInAllTabs(allTabs) {
for (const tab of allTabs) {
const results = await browser.find.find("banana", { tabId: tab.id });
console.log(`In page "${tab.url}": ${results.count} matches.`);
}
}
browser.tabs.query({}).then(findInAllTabs);
使用 rangeData
在此示例中,擴充套件程式使用 rangeData 來獲取找到匹配項的上下文。上下文是包含匹配項的節點的完整 textContent。如果匹配項跨越節點,則上下文是所有跨越節點的 textContent 的串聯。
請注意,為簡單起見,此示例不處理包含框架的頁面。要支援這一點,您需要將 rangeData 分組,每幀一組,並在每個框架中執行指令碼。
後臺指令碼
// background.js
async function getContexts(matches) {
// get the active tab ID
const activeTabArray = await browser.tabs.query({
active: true,
currentWindow: true,
});
const tabId = activeTabArray[0].id;
// execute the content script in the active tab
await browser.tabs.executeScript(tabId, { file: "get-context.js" });
// ask the content script to get the contexts for us
const contexts = await browser.tabs.sendMessage(tabId, {
ranges: matches.rangeData,
});
for (const context of contexts) {
console.log(context);
}
}
browser.browserAction.onClicked.addListener((tab) => {
browser.find.find("example", { includeRangeData: true }).then(getContexts);
});
內容指令碼
/**
* Get all the text nodes into a single array
*/
function getNodes() {
const walker = document.createTreeWalker(
document,
window.NodeFilter.SHOW_TEXT,
null,
false,
);
const nodes = [];
while ((node = walker.nextNode())) {
nodes.push(node);
}
return nodes;
}
/**
* Gets all text nodes in the document, then for each match, return the
* complete text content of nodes that contained the match.
* If a match spanned more than one node, concatenate the textContent
* of each node.
*/
function getContexts(ranges) {
const contexts = [];
const nodes = getNodes();
for (const range of ranges) {
let context = nodes[range.startTextNodePos].textContent;
let pos = range.startTextNodePos;
while (pos < range.endTextNodePos) {
pos++;
context += nodes[pos].textContent;
}
contexts.push(context);
}
return contexts;
}
browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
sendResponse(getContexts(message.ranges));
});
使用 rectData
在此示例中,擴充套件程式使用 rectData 來“遮蔽”匹配項,透過在它們的邊界矩形上方新增黑色 DIV。

請注意,在許多方面,這是一種糟糕的遮蔽頁面方式。
後臺指令碼
// background.js
async function redact(matches) {
// get the active tab ID
const activeTabArray = await browser.tabs.query({
active: true,
currentWindow: true,
});
const tabId = activeTabArray[0].id;
// execute the content script in the active tab
await browser.tabs.executeScript(tabId, { file: "redact.js" });
// ask the content script to redact matches for us
await browser.tabs.sendMessage(tabId, { rects: matches.rectData });
}
browser.browserAction.onClicked.addListener((tab) => {
browser.find.find("banana", { includeRectData: true }).then(redact);
});
內容指令碼
// redact.js
/**
* Add a black DIV where the rect is.
*/
function redactRect(rect) {
const redaction = document.createElement("div");
redaction.style.backgroundColor = "black";
redaction.style.position = "absolute";
redaction.style.top = `${rect.top}px`;
redaction.style.left = `${rect.left}px`;
redaction.style.width = `${rect.right - rect.left}px`;
redaction.style.height = `${rect.bottom - rect.top}px`;
document.body.appendChild(redaction);
}
/**
* Go through every rect, redacting them.
*/
function redactAll(rectData) {
for (const match of rectData) {
for (const rect of match.rectsAndTexts.rectList) {
redactRect(rect);
}
}
}
browser.runtime.onMessage.addListener((message) => {
redactAll(message.rects);
});
擴充套件程式示例
瀏覽器相容性
載入中…