为什么 JQuery 需要全局 "window" 对象?

Why does JQuery require a global "window" object?

我正在使用 jsdomjquery 在 Node.js 应用程序中抓取静态网页内容。

jsdom 将 HTML 字符串转换为 DOM 树,包括 window 属性。我发现我必须将 DOM 的 window 属性 分配给 global.window,否则 JQuery 错误(说全局 window 对象是必须的)。为什么需要这样做?

// Create DOM from HTML
const JSDOM = require('jsdom').JSDOM;
const jsDom = new JSDOM('<html>...</html>')

// Set up JQuery
const { window } = jsDom;
const { document } = window;
global.window = window;
const $ = global.jQuery = require('jquery');

// Scrape content
const tbl = $(document)
  .find('#table-id')
  .find('tr').each(function() {
    // Do something with $(this).html()
  })

此外,我经常看到:const $ = global.jQuery = require('jquery'); 为什么需要 global.jQuery

jQuery 期望在浏览器中 运行ning。在浏览器中 window 存在于全局 space 中,并且 jQuery 将其用于某些功能。在 Node.js 中,您的代码 运行 在为包含它的文件创建的范围内。即使您不认为它是一个 模块 ,Node.js 也不会区分您所有的 const(和 let)声明在文件的顶层声明范围为文件的变量。所以 const { window } = jsDom; 没有将 window 放在全局 space 中,并且 jQuery.

无法访问它

当你运行 jQuery 在 Node:

时你有两个选择
  1. 做你正在做的事情:首先将 window 公开到全局 space,然后加载 jQuery。这很好用。

  2. 您也可以这样做:

    const JSDOM = require('jsdom').JSDOM;
    const jsDom = new JSDOM('<html>...</html>');
    
    const { window } = jsDom;
    const { document } = window;
    const $ = global.jQuery = require("jquery")(window);
    

你也在问 const $ = global.jQuery = require('jquery');。根据我的经验,大多数依赖 jQuery 的库(例如 jQuery 插件)将其称为 jQuery。他们 运行 在这样的 IIFE 中:

(function ($) { // Inside the IIFE, jQuery is bound to $.


}(jQuery)); // jQuery is grabbed from the global space as jQuery.

因此您希望 jQuery 在全局 space 中支持依赖于它的库。

你可以这样做:

const jsDom = new JSDOM('<html>...</html>');
const $ = global.jQuery = (require('jquery'))(jsDom.window);