javascript 在当前页面上搜索和突出显示 Chrome 扩展的文本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16827817/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 06:09:18  来源:igfitidea点击:

Searching and highlighting text on current page for a Chrome Extension

javascriptgoogle-chromegoogle-chrome-extension

提问by Event_Horizon

How should I connect my pages to search and highlight text on current tab?

我应该如何连接我的页面以搜索和突出显示当前选项卡上的文本?

Currently I have:

目前我有:

  • manifest.json does defining content/backgr/event page do significant things,auto inject code etc?
  • popup.html essentially a shell for the search input which is used by search.js
  • search.js should this be in background/event/content/popup.html page?
  • manifest.json是否定义内容/背景/事件页面做重要的事情,自动注入代码等?
  • popup.html本质上是 search.js 使用的搜索输入的外壳
  • search.js应该在 background/event/content/popup.html 页面中吗?

What I still don't understand after reading:

阅读后我仍然不明白的是:

What is a content page vs. background/event page?

什么是内容页面与背景/事件页面?

I know one is constantly running vs injected, but that's as much as I got from the chrome extension manual, I still don't quite understand if the content script/page is seperate from the popup.html for example and what the difference between a script in the popup.html vs content page/script is.

我知道一个是不断运行 vs 注入,但这和我从 chrome 扩展手册中得到的一样多,我仍然不太明白内容脚本/页面是否与 popup.html 分开,例如popup.html vs 内容页面/脚本中的脚本是。

What I know:

我知道的:

I know how to search for text on a page, and replace it or change its style etc. using JS.

我知道如何在页面上搜索文本,并使用 JS 替换它或更改其样式等。

I need to read up on the messaging API for Chrome Extensions.

我需要阅读 Chrome 扩展的消息传递 API。

I know I need to know how to use the messaging API, is it going to be required for page search and highlighting?

我知道我需要知道如何使用消息传递 API,页面搜索和突出显示是否需要它?

Summary:

概括:

I don't need a walk through or full answer, just a little help visualizing how Chrome extensions work, or at minimum how I should set mine up in relation to page interaction IE:

我不需要演练或完整的答案,只需要一点帮助来可视化 Chrome 扩展程序的工作方式,或者至少我应该如何设置与页面交互 IE 相关的我的:

search.js content page injected >>>>> popup.html

search.js 内容页面注入 >>>>> popup.html

and maybe a short bit about how injection works in chrome extensions(IE, do I only need to specify that it is content page in manifest.json to have it injected or is there more work to it)/expected behavior?

可能还有一点关于注入如何在 chrome 扩展中工作(IE,我是否只需要在 manifest.json 中指定它是内容页面来注入它,或者是否有更多的工作要做)/预期行为?

Apologies for the jumbled thoughts/question/possibly missing the things relevant to my questions while reading the manual.

为阅读手册时混乱的想法/问题/可能遗漏了与我的问题相关的内容而道歉。

回答by BeardFist

I will start with making the purpose of each kind of page/script more clear.

我将首先使每种页面/脚本的目的更加明确。



First is the background page/script. The background scriptis where your extension lives. It isn't required, but in order to do most extension things, you need one. In it you can set up various event listeners and such depending on what you want it to do. It lives in its own little world and can only interact with other pages and scripts using the chrome.*apis. If you set it up as an event page it works exactly the same except that it unloads when not in use and loads back into memory when it has something to do.

首先是background page/script. 这background script是您的分机所在的位置。它不是必需的,但为了执行大多数扩展操作,您需要一个。您可以在其中设置各种事件侦听器等,具体取决于您希望它做什么。它生活在自己的小世界中,只能使用chrome.*api与其他页面和脚本进行交互。如果您将其设置为事件页面,则它的工作原理完全相同,只是在不使用时卸载,并在有事可做时加载回内存。

Content scriptsrefer to injected Javascript and/or css. They are the primary tool used for interacting with web pages. They have very limited access to chrome.*apis, but they have full access to the DOM of the page they are injected into. We will come back to using them in a minute.

Content scripts指注入的 Javascript 和/或 css。它们是用于与网页交互的主要工具。他们对chrome.*api 的访问非常有限,但他们可以完全访问他们注入的页面的 DOM。我们将在一分钟内回来使用它们。

Now for Popup pages. Unlike the background scriptand content script, popups have both a HTMLand JSportion. The HTMLpart is just like any other page, just small and as a overlay popup coming out from the icon. The script portion of it, however, can do all the things the background page does, except that it unloads whenever the popup is closed.

现在对于Popup pages. 与background scriptand不同content script,弹出窗口既有 aHTML又有JS部分。该HTML部分就像任何其他页面一样,只是很小,并且是从图标中弹出的覆盖弹出窗口。然而,它的脚本部分可以完成后台页面所做的所有事情,除了它在弹出窗口关闭时卸载。



Now that the distinctions are more clear let's move on to what you want to do. It sounds like you want to open the popup, have the user enter text to search for in the current tab, then highlight that text on the page. Since you said that you already know how you plan on highlighting the text, I will leave that part to you.

现在区别更清楚了,让我们继续讨论您想要做什么。听起来您想打开弹出窗口,让用户在当前选项卡中输入要搜索的文本,然后在页面上突出显示该文本。既然你说你已经知道如何突出显示文本,我会把这部分留给你。

First to set up our manifest file. For this particular action, we don't need a background script. What we do need is both the "tabs"and "activeTab"permissions. These will enable us to inject our script later. We also need to define the browser action with it's popup. Altogether it would look something like this:

首先设置我们的清单文件。对于此特定操作,我们不需要后台脚本。我们需要的是权限"tabs""activeTab"权限。这些将使我们能够稍后注入我们的脚本。我们还需要定义带有弹出窗口的浏览器操作。总而言之,它看起来像这样:

"browser_action": {
  "default_icon": "icon.png",
  "default_popup": "popup.html" 
},
"permissions": [
  "tabs", "activeTab"
]

Now in our popup.htmlfile, we can only have markup and css, no inline code at all. We will put it all in our jsfile and include it. Something like this should work:

现在在我们的popup.html文件中,我们只能有标记和 css,根本没有内联代码。我们将把它全部放在我们的js文件中并包含它。这样的事情应该工作:

<!DOCTYPE html> 
<html>
  <head>
    <script src="popup.js"></script>
  </head>
  <body>
    <input type="text" id="searchText">
    <button id="searchButton">Search</button>
  </body>
</html>

This is where we come back to the content script stuff. There are two ways to inject a content script, first is to define it in the manifest. This works best when you always want to inject it for a particular set of url's. Second, to use the chrome.tabs.executeScriptmethod to inject it when we need to. That is what we will use.

这是我们回到内容脚本的地方。有两种方法可以注入内容脚本,第一种是在清单中定义它。当您总是想为一组特定的 url 注入它时,这最有效。其次,chrome.tabs.executeScript在需要的时候使用方法注入。这就是我们将要使用的。

window.onload = function(){
  document.getElementById('searchButton').onclick = searchText;
};
function searchText(){
  var search = document.getElementById('searchText').value;
  if(search){
    chrome.tabs.query({active:true,currentWindow:true},function(tabs){
      chrome.tabs.executeScript(tabs[0].id,{file:search.js});
      chrome.tabs.sendMessage(tabs[0].id,{method:'search',searchText:search});
    });
  }
}

With this, we have successfully injected our script and then send the search text to that script. Just make sure that the script is wrapped in a onMessagelistener like this:

这样,我们就成功地注入了我们的脚本,然后将搜索文本发送到该脚本。只需确保脚本包含在这样的onMessage侦听器中:

chrome.runtime.onMessage.addListener(function(message,sender,sendResponse){
  // message.searchText is the text that was captured in the popup    
  // Search/Highlight code goes here
});

And that pretty much sums it up. With that, you should be able to get it working. If something is still not clear let me know and I will fix it.

这几乎总结了它。有了这个,你应该能够让它工作。如果仍有不清楚的地方,请告诉我,我会修复它。

回答by Jude Osborn

I think what's confusing you is the non-existant concept of a "content page". There is no such thing. What you're likely referring to is a "content script". Let me explain the three main components of an extension:

我认为让您感到困惑的是“内容页面”这个不存在的概念。哪有这回事。您可能指的是“内容脚本”。让我解释一下扩展的三个主要组成部分:

Background Page

背景页

As you said, this is the persistent aspect of a Chrome Extension. Even though it can be HTML page it is never rendered. You simply use it to run JavaScript and other content that stays persistent. The only way to "refresh" the background page is to refresh the extension in the extension manager, or to re-install the extension.

正如您所说,这是 Chrome 扩展程序的持久性方面。即使它可以是 HTML 页面,它也永远不会呈现。您只需使用它来运行 JavaScript 和其他保持持久性的内容。“刷新”后台页面的唯一方法是在扩展管理器中刷新扩展,或者重新安装扩展。

This is most useful for saving information that should remain persistent, such as authentication credentials, or counters that should build up over time. Only use the background page when absolutely necessary, though, because it consumes resources as long as the user is running your extension.

这对于保存应该保持持久的信息最有用,例如身份验证凭据或应该随着时间推移而建立的计数器。但是,仅在绝对必要时才使用后台页面,因为只要用户运行您的扩展程序,它就会消耗资源。

You can add a background script like to manafest file like this:

您可以像这样添加一个后台脚本来管理文件:

"background": {
    "scripts": [
        "background.js"
    ]
},

Or like this:

或者像这样:

"background": {
    "page": "background.html"
},

Then simply add background.js to background.html via a typical tag.

然后通过一个典型的标签简单地将 background.js 添加到 background.html。

Popup

弹出

This is what you see when you click the icon on the toolbar. It's simply a popup window with some HTML. It can contain HTML, JavaScript, CSS, and whatever you would put in a normal web page.

这就是您单击工具栏上的图标时看到的内容。它只是一个带有一些 HTML 的弹出窗口。它可以包含 HTML、JavaScript、CSS 以及您可以放在普通网页中的任何内容。

Not all extension need a popup window, but many do. For example, your highlight extension may not need a popup if all it's doing is highlighting text on a page. However, if you need to collect a search result (which seems likely) or provide the user with some settings or other UI then a popup is a good way to go about this.

并非所有扩展都需要弹出窗口,但很多都需要。例如,如果您的突出显示扩展程序所做的只是突出显示页面上的文本,则它可能不需要弹出窗口。但是,如果您需要收集搜索结果(这似乎很可能)或为用户提供一些设置或其他 UI,那么弹出窗口是解决此问题的好方法。

You can add a popup to the manifest file like this:

您可以像这样在清单文件中添加一个弹出窗口:

"browser_action": {
    "default_popup": "popup.html"
},

Content script

内容脚本

As I mentioned, this is not a "page" per se -- it a script, or set of scripts. A content script is what you use to infuse JavaScript into pages the user is browser. For example, a user goes to Facebook and a content script could change the background to red. This is almost certainly what you'll need to use to highlight text on a page. Simply infuse some JavaScript and any necessarily libraries to search the page or crawl the dom, and render changes to that page.

正如我所提到的,这本身并不是一个“页面”——它是一个脚本或一组脚本。内容脚本是您用来将 JavaScript 注入用户浏览器页面的内容。例如,用户访问 Facebook,内容脚本可以将背景更改为红色。这几乎肯定是您需要用来突出显示页面上的文本的内容。只需注入一些 JavaScript 和任何必要的库来搜索页面或抓取 dom,并呈现对该页面的更改。

You can inject content scripts every time a user opens any URL like this:

每次用户打开任何 URL 时,您都可以注入内容脚本,如下所示:

"content_scripts": [
    {
        "matches" : [
            "<all_urls>"
        ],
        "js" : [
            "content.js"
        ]
    }
],

The above injects "content.js" into "all urls".

以上将“content.js”注入“所有网址”。

You'll also need to add this to the permissions:

您还需要将其添加到权限中:

"permissions": [
    "<all_urls>",
]

You can even add JQuery to the list of content scripts. The nice thing about extensions is that the content scripts are sandboxed, so the version of JQuery you inject will not collide with JQuery on pages the user visits.

您甚至可以将 JQuery 添加到内容脚本列表中。扩展的好处在于内容脚本是沙盒化的,因此您注入的 JQuery 版本不会与用户访问的页面上的 JQuery 发生冲突。