我无法在 HTML5 web worker中访问 jQuery 。有没有办法我可以做到这一点?
7 回答
tl;dr:在 jQuery 之前包含这个脚本
JQuery 最初会访问许多document
属性来检查浏览器功能。document
未在 Worker 中定义,此时您实际上无法Document
在 Web Worker 中创建实例。JQuery 并没有为此做好准备 - 正如您在对您的问题的评论中看到的那样,似乎没有人理解您将如何使用没有 DOM 的 JQuery。
正如我所说,因为 JQuery 需要document
初始化,所以我创建了一个虚拟的假文档对象。此对象在 JQuery 测试期间充当真实文档:
var document = self.document = {parentNode: null, nodeType: 9, toString: function() {return "FakeDocument"}};
var window = self.window = self;
var fakeElement = Object.create(document);
fakeElement.nodeType = 1;
fakeElement.toString=function() {return "FakeElement"};
fakeElement.parentNode = fakeElement.firstChild = fakeElement.lastChild = fakeElement;
fakeElement.ownerDocument = document;
document.head = document.body = fakeElement;
document.ownerDocument = document.documentElement = document;
document.getElementById = document.createElement = function() {return fakeElement;};
document.createDocumentFragment = function() {return this;};
document.getElementsByTagName = document.getElementsByClassName = function() {return [fakeElement];};
document.getAttribute = document.setAttribute = document.removeChild =
document.addEventListener = document.removeEventListener =
function() {return null;};
document.cloneNode = document.appendChild = function() {return this;};
document.appendChild = function(child) {return child;};
请注意,这个假文档只是为了允许 jQuery 加载,它不会允许任何真正的 DOM 操作。
示例用法:
importScripts("workerFakeDOM.js");
importScripts('jquery-2.1.4.min.js');
console.log("JQuery version:", $.fn.jquery);
测试脚本
允许您使用我的脚本尝试各种版本的 JQuery。
JSfiddle
检查您是否正在使用http://
,我的域不适用于https://
。
下载为脚本
Tomáš Zato 的答案是正确的,但不再适用于较新的 jQuery 版本。我为 jQuery 3.1.1 添加了更多内容:
var document = self.document = { parentNode: null, nodeType: 9, toString: function () { return "FakeDocument" } };
var window = self.window = self;
var fakeElement = Object.create(document);
fakeElement.nodeType = 1;
fakeElement.toString = function () { return "FakeElement" };
fakeElement.parentNode = fakeElement.firstChild = fakeElement.lastChild = fakeElement;
fakeElement.ownerDocument = document;
document.head = document.body = fakeElement;
document.ownerDocument = document.documentElement = document;
document.getElementById = document.createElement = function () { return fakeElement; };
document.createDocumentFragment = function () { return this; };
document.getElementsByTagName = document.getElementsByClassName = function () { return [fakeElement]; };
document.getAttribute = document.setAttribute = document.removeChild =
document.addEventListener = document.removeEventListener =
function () { return null; };
document.cloneNode = document.appendChild = function () { return this; };
document.appendChild = function (child) { return child; };
document.childNodes = [];
document.implementation = {
createHTMLDocument: function () { return document; }
}
有没有人尝试过 jQuery - No DOM Edition?https://github.com/kpozin/jquery-nodom。
这是 jQuery 库的一小部分,旨在用于 Web Worker 上下文,其中大多数浏览器 API 都不存在。
这主要是通过修改 jQuery 构建指令(Makefile)以仅包含非 DOM 模块来实现的。
这可能有助于解决问题,因为此构建没有 DOM 依赖项,这是在 webworker 中导入 jQuery 时的一个障碍。将尽快为此提供一些示例代码
jQuery 自己的一位领导者提供了一个很好的插件,可以将 Web Worker 与 jQuery 一起使用。在 GitHub 上查看他的插件。
是否使用:
importScripts("jQueryWhatever.js");
$.blahblahblah();
没有按预期工作?我怀疑它会毫无问题地加载 jQuery,但大多数与 good-ole $ 相关的调用将无法按预期工作,因为 WebWorker 内部没有 DOM 访问。
jQuery 3.3.1
我使用了Luke Vo的代码,不得不添加一些额外的代码。我将此功能放在我的网络工作者中并且效果很好:
const webWorkerJQueryFix = () => {
document = self.document = { parentNode: null, nodeType: 9, toString: () => { return "FakeDocument" } };
window = self.window = self;
const fakeElement = Object.create(document);
fakeElement.nodeType = 1;
fakeElement.toString = () => { return "FakeElement" };
fakeElement.parentNode = fakeElement.firstChild = fakeElement.lastChild = fakeElement;
fakeElement.ownerDocument = document;
document.innerHTML = "";
document.head =
document.body =
fakeElement;
document.ownerDocument =
document.documentElement =
document;
document.createElement =
document.getElementById =
document.getElementsByClassName =
document.getElementsByTagName = () => { return [fakeElement]; };
document.appendChild = (child) => { return child; };
document.createDocumentFragment = () => {
this.appendChild = document.appendChild;
return this;
};
document.getAttribute =
document.removeChild =
document.addEventListener =
document.removeEventListener =
document.setAttribute = () => { return null; };
document.cloneNode = () => {
this.cloneNode = document.cloneNode;
this.lastChild = {
checked: false,
}
return this;
};
document.childNodes = [];
document.implementation = {
createHTMLDocument: () => { return document; }
}
}