【问题标题】:How to access jQuery in HTML 5 web worker如何在 HTML 5 Web Worker 中访问 jQuery
【发布时间】:2012-05-08 01:44:34
【问题描述】:

我无法在 HTML5 web worker 中访问 jQuery。有什么办法可以做到吗?

【问题讨论】:

  • 只是好奇...你想从 jQuery 访问什么?
  • 我讨厌你开始需要同步块来访问 dom 元素的那一天 :) 为什么我的 $('div') 需要 1 分钟才能返回?!
  • 我的印象是网络工作者无法访问 DOM。
  • @Marc,我有一些经常访问 Jquery 的函数。这就是我需要 jquery 的原因。还有 Jquery ajax 请求呢?
  • @Marc - 他们没有,或者至少不应该有,我的印象是 webworkers 最适合用于外部脚本计算事情或做你现在可以“外部”做的其他大量工作避免使用长时间的现场脚本,挂起等。为什么你需要一个 webworker 来做一个异步的 ajax 请求?

标签: javascript jquery html web-worker


【解决方案1】:

tl;dr:在 jQuery 之前包含 this script

JQuery 最初会访问大量 document 属性以检查浏览器功能。 document 未在 Worker 中定义,此时您实际上无法在 Web Worker 中创建 Document 实例。 JQuery 并没有为此做好准备 - 正如您在 cmets 中看到的那样,似乎没有人理解您将如何使用没有 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);

Test script

允许您使用我的脚本尝试各种版本的 JQuery。

JSfiddle

检查您使用的是http://,我的域不适用于https://

Download as script

【讨论】:

  • 很好的解决方法。注意:这只适用于 jquery 2+
  • 不幸的是,我发现这对我不起作用,使用 2.2.0.min,jquery 文件中的错误刚刚移到另一行。
  • 是的,这对jQuery 3.1.1 不再有效。我添加了适用于 jQuery 3.1.1 的答案
  • 你拯救了我的一天@Tomáš Zato
【解决方案2】:

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; }
}

【讨论】:

    【解决方案3】:

    有没有人尝试过 jQuery - No DOM Edition? https://github.com/kpozin/jquery-nodom.

    这是 jQuery 库的一小部分,旨在用于 Web Worker 上下文,其中大多数浏览器 API 都不存在。

    这主要是通过修改 jQuery 构建指令 (Makefile) 以仅包含非 DOM 模块来实现的。

    这可能有助于解决问题,因为此构建没有 DOM 依赖项,这是在 webworker 中导入 jQuery 时的一个障碍。将尽快为此提供一些示例代码

    【讨论】:

      【解决方案4】:

      jQuery 自己的一位领导者提供了一个很好的插件,可以将 Web Worker 与 jQuery 一起使用。查看his plugin on GitHub

      【讨论】:

      • 不,不是,它在主线程中的Worker 上添加了 jQuery 包装器。我猜有 5 个人甚至没有点击链接就对这个答案投了赞成票。
      【解决方案5】:

      是否使用:

      importScripts("jQueryWhatever.js");
      $.blahblahblah();
      

      没有按预期工作?我怀疑它会毫无问题地加载 jQuery,但大多数与 good-ole $ 相关的调用将无法按预期工作,因为 WebWorker 内部没有 DOM 访问。

      【讨论】:

      • 给出错误'Uncaught ReferenceError: window is not defined'。
      • 听起来不错。没有太多理由将 jQuery 导入 webworker 领域。
      • document也给出了同样的错误,也没有定义。
      【解决方案6】:

      您也可以使用Cheerio

      核心 jQuery 设计的快速、灵活和精益实现 专门用于服务器。

      您只需要browserify 模块,然后将the resulting file 加载到您的网络工作者中。然后,您将能够解析您的字符串文档并像 jQuery 一样查询它:

      $ = cheerio.load('<h2 class="title">Hello world</h2>')
      

      【讨论】:

        【解决方案7】:

        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; }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2017-06-14
          • 2014-09-21
          • 2012-11-05
          • 2011-06-03
          • 2011-06-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多