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

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

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

这是我的难题:

  1. 我有一个包含 table
  2. 的集合页面
  3. 我想让 table 可搜索(不是 sortable,只是可搜索)
  4. 我正在使用 Manifest.JS 中指定的脚本将一些 JS 代码直接注入页面,该脚本将 table 克隆到具有正确 [=75] 的 DIV =],正在将 'list' class 添加到 table 的正文,并将相应的 classes 添加到 table 正文 'td' 元素 -只有一列我想在其上进行搜索。
  5. 下一步涉及单击扩展程序的图标,执行循环 XHR 请求(遗憾的是同步,因为我无法理解如何使其异步)并且 table 的行是彩色的,一些'td' 个单元格已填充。我希望能够根据那些 'td' 新内容过滤 table。

不管我放

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

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

'Uncaught ReferenceError: List is not defined'

更新:代码如下。

我怎样才能使 table 可搜索?我做错了什么,应该在什么之前注入或写入什么?

代码如下:

Html:


<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.JS开启)


[...]
"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 

INCLUDEDSTUFF.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);

background.js:

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

你需要掌握isolated world的概念:

Content scripts execute in a special environment called an isolated world. They have access to the DOM of the page they are injected into, but not to any JavaScript variables or functions created by the page. It looks to each content script as if there is no other JavaScript executing on the page it is running on. The same is true in reverse: JavaScript running on the page cannot call any functions or access any variables defined by content scripts.

当您的 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;它对页面本身是不可见的,但不会影响您的代码。