List.JS 在通过 Chrome 扩展程序注入时不起作用

List.JS doesn't work when injected via a Chrome extension

本文关键字:程序 注入 不起作用 扩展 Chrome JS List      更新时间:2023-09-26

我没有发现类似的问题 - 我确实在SO和Google上广泛搜索了这个主题,但找不到答案。

这是我的难题:

  1. 我有一个包含表格的设置页面
  2. 我想使该表可搜索(不可排序,只是可搜索(
  3. 我使用Manifest.JS中指定的脚本将一些JS代码直接注入页面,并且该脚本将表克隆到具有正确类的DIV中,将"list"类添加到表的主体中,并将相应的类添加到表体"td"元素 - 只是我想在其上进行搜索的一列。
  4. 下一步涉及单击扩展的图标,执行循环 XHR 请求(可悲的是同步,因为我无法弄清楚如何使其异步(,并且该表的行是彩色的,并填充了一些"td"单元格。我希望能够根据这些"td"新内容过滤表格。

无论我是否把

 var options = {
        valueNames: ["searchterm"]
        };
    var eventsList = new List("events", options);

在 manifest.js 中指定的预注入代码中,或者在单击扩展程序图标时运行的其他脚本中,我在 Chrome 控制台中收到相同的错误:

'Uncaught ReferenceError: List is not defined'

更新:代码如下。

如何使该表可搜索?我做错了什么,应该在什么之前注入或写什么?

代码如下:

目录:


<html>
<head>
<meta http-equiv = "Content-Type" content = "text/html; charset = utf-8">
</head>
<body>
<title> a title</title>
<table>a table</table>
<table>
<thead>
<tr>
<th>someContent</th>
/*14 <th> elements corresponding to 14 columns, the last one being: */
<th>contentIWantToSearch</th>
</tr>
</thead>
<tbody>
<tr id = "some ID" class = "someClass" style = "someStyle">
/*14 <td> elements, with the last one being:*/
<td> the actual content I want to filter the table after</td>
</tr>
/*next, a long list of <tr>s, same structure, part of the table */
</tbody>
<tfoot>
/*one <tr>, 11 <td> */
</tfoot>
</table>
</body>

Chrome 扩展程序清单 (Manifest.JSON(


[...]
"permissions": [
"URL I want it to inject the script automatically",
"declarativeContent"
],
"background": {
"scripts": ["background.js"],
"persistent": false
},
"content_scripts": [
{
"matches": ["URL I want to run it on*"],
"js": ["includedstuff.js"],
"css": ["list.css", "someothercss"]
}
[... rest of manifest.json 

包含的东西

.JS
/*appending the list.js CDN on page load*/
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://cdnjs.cloudflare.com/ajax/libs/list.js/1.1.1/list.min.js";
head.appendChild(script);
/*creating the required list.js classes, only for pages with the structure mentioned above - I cannot match it perfectly based on URL*/
if(document.getElementsByTagName("table").length >1) {
var fulltable = document.getElementsByTagName("table")[1];
var searchboxelem = document.createElement("input");
var events = document.createElement("div");
events.id = "events";
searchboxelem.setAttribute("class", "search");
searchboxelem.setAttribute("placeholder", "Input Search Term");
events.appendChild(searchboxelem);
events.appendChild(fulltable.cloneNode(true));
fulltable.parentNode.replaceChild(events, fulltable);
var defineachrow = document.getElementsByTagName("table")[1].getElementsByTagName("tbody")[0].getElementsByTagName("tr");
document.getElementsByTagName("table")[1].getElementsByTagName("tbody")[0].setAttribute("class", "list");
for(x=0; x<defineachrow.length; x++) {
defineachrow[x].getElementsByTagName("td")[13].setAttribute("class", "searchterm");
}
}

content_script.js:


/*some script with XHR loop requests - and sadly sync, as I could not get around it to make it async, it works however, and then:*/
var options = {
valueNames:["searchterm"]
};
var eventsList = new List("events", options);

背景.js:

chrome.browserAction.onCLicked.addListener(
function(tab) {
chrome.tabs.executeScript(null, {file:
"content_script.js"});
});
你需要

掌握隔离世界的概念:

内容脚本在称为隔离世界的特殊环境中执行。他们可以访问他们被注入的页面的 DOM,但不能访问页面创建的任何 JavaScript 变量或函数。它看起来每个内容脚本,就好像在运行它的页面上没有其他 JavaScript 在执行一样。反过来也是如此:在页面上运行的 JavaScript 不能调用任何函数或访问内容脚本定义的任何变量。

首次注入includedstuff.js时,将为文档创建一个单独的 JS 上下文,并在其中执行。

但是,当您插入 <script> 标记时,它会在页面的上下文中执行代码。因此,所有List内容仅对页面本身可见。

当您的content_script执行时,它会在与 includedstuff.js 相同的上下文中执行,其中不包括 List


故事的士气:你真的需要向页面展示List吗?可能不是 - 您添加它,因此您是使用它的人。

从 CDN 加载它没有任何优势 - 事实上,您正在请求特定版本,因此它不会更改。它添加了另一个网络请求。你不需要那个。

相反,请在扩展的文件中包含list.min.js,并修改清单:

"content_scripts": [
  {
    "matches": ["http://example.com/*"],
    "js": ["list.min.js", "includedstuff.js"],
    "css": ["list.css", /*...*/]
  }

这将在代码正在执行的上下文中加载List;它对页面本身是不可见的,但不会影响您的代码。