为什么JQuery需要全局“窗口”对象?

时间:2018-09-30 17:51:08

标签: javascript jquery dom jsdom

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

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

// 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是必需的?

2 个答案:

答案 0 :(得分:3)

jQuery期望在浏览器中运行。在浏览器中,window存在于全局空间中,而jQuery将其用于某些功能。在Node.js中,您的代码在为包含它的文件创建的作用域中运行。即使您不认为它是 module ,Node.js也不会在您的所有const(和let)声明中都区分出顶层您的文件声明了范围为文件的变量。因此,const { window } = jsDom;不会将window放在全局空间中,并且jQuery无法访问它。

在Node中运行jQuery时,您有两种选择:

  1. 执行您的操作:首先将window暴露到全局空间中,然后加载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在全局空间中支持依赖它的库。

答案 1 :(得分:0)

您可以这样做:

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