简体   繁体   English

错误:jQuery 需要一个带有文档的窗口

[英]Error: jQuery requires a window with a document

So everything was working just fine and great until doing npm update and now things do not work quite as they used to.因此,在进行 npm update 之前,一切都工作得很好,现在一切都不像以前那样工作了。

A little background: in my code I use jquery to parse textual html.一点背景知识:在我的代码中,我使用 jquery 来解析文本 html。 I do not use a window and I don't use jsdom.我不使用窗口,也不使用 jsdom。 It used to work just fine to do this:它曾经很好地做到这一点:

$ = require("jquery"); 
$(html).find("<h1>").html("The title"); 

But now I get this: jQuery requires a window with a document但现在我明白了:jQuery 需要一个带有文档的窗口

How do I fix this?我该如何解决?

This worked for me这对我有用

var jsdom = require('jsdom');
$ = require('jquery')(new jsdom.JSDOM().window);

node.js-jQuery definition in one line: node.js-jQuery 定义在一行中:

// definition
var $ = require('jquery')(require("jsdom").jsdom().parentWindow);

// usage
$("body").append("<div>TEST</div>");
console.log($("body").html());

The npm package for jQuery definitely used to include jsdom with it, which is why it would work at all in Node: jQuery needs to have some kind of DOM environment to work with. jQuery 的 npm 包肯定曾经包含 jsdom,这就是为什么它可以在 Node 中工作的原因:jQuery 需要有某种 DOM 环境才能使用。

You can check that old versions used to have it by doing npm install jquery@1.8.3 .您可以通过执行npm install jquery@1.8.3检查旧版本是否曾经拥有它。 You'll see jsdom being installed with it.你会看到 jsdom 被安装了。 For some reason they seem to have removed jsdom from the recent releases.出于某种原因,他们似乎已经从最近的版本中删除了 jsdom。 I don't know why.我不知道为什么。

However, using jsdom 7.x to run jQuery code is simple:但是,使用 jsdom 7.x 运行 jQuery 代码很简单:

var jsdom = require("jsdom");
var window = jsdom.jsdom().defaultView;

jsdom.jQueryify(window, "http://code.jquery.com/jquery.js", function () {
  var $ = window.$;
  $("body").prepend("<h1>The title</h1>");
  console.log($("h1").html());
});

The path could be changed to a different version of jQuery or to a local file.路径可以更改为不同版本的 jQuery 或本地文件。

Note: Earlier versions of jsdom, including the 3.x series, would need the line var window = jsdom.jsdom().parentWindow;注意:早期版本的 jsdom,包括 3.x 系列,需要行var window = jsdom.jsdom().parentWindow; instead of var window = jsdom.jsdom().defaultView;而不是var window = jsdom.jsdom().defaultView; . . 4.x made it so that parentWindow no longer works. 4.x 使parentWindow不再工作。

I solved it.我解决了。 had to first remove jsdom and jquery then npm install jsdom jquery.必须先删除 jsdom 和 jquery,然后 npm install jsdom jquery。

Then this:然后这个:

var jsdom = require("jsdom"); 
$ = require("jquery")(jsdom.jsdom().createWindow()); 

Turns out that it was important that I had the latest version.事实证明,我拥有最新版本很重要。 Otherwise it didn't work..不然没用。。

jsdom seems to have a new version therefore now it works on a slightly different way. jsdom似乎有一个新版本,因此现在它的工作方式略有不同。 Here you have an example:这里有一个例子:

const { JSDOM } = require("jsdom");
const myJSDom = new JSDOM (html);
const $ = require('jquery')(myJSDom.window);

Now you can search as you used to do on jQuery:现在您可以像以前在 jQuery 上一样进行搜索:

$("<h1>").html("The title");

Mind the jQuery installation as you should write jquery all lowercase, like npm install jquery .请注意 jQuery 安装,因为您应该将jquery全部小写,例如npm install jquery

You can try the following with these version settings in your package.json :您可以在package.json中使用这些版本设置尝试以下操作:

"jquery": "^2.1.1",
"jsdom": "^1.0.0-pre.3"

Say you have a file called page.htm :假设您有一个名为page.htm的文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>Html page</h1>
    <div class="left">
        <p>left content</p>
    </div>
</body>
</html>

Then, you can read from file, create a DOM and window from it with JSDOM and pass it to jquery:然后,您可以从文件中读取,使用 JSDOM 从中创建一个 DOM 和窗口并将其传递给 jquery:

var jsdom = require("jsdom").jsdom;
var fs = require('fs');
fs.readFile('page.htm', {encoding: "utf8"}, function (err, markup) {
  if (err) throw err;
  var doc = jsdom(markup);
  var window = doc.parentWindow;
  var $ = require('jquery')(window)
  var outerLeft = $(".left").clone().wrap('<div></div>').parent().html();
  var innerLeft = $(".left").html();
  console.log(outerLeft, "and ...", innerLeft);
});

will output:将输出:

<div class="left">
<p>left content</p>
</div> and ... 
<p>left content</p>

(2018) - New jsdom API (2018) - 新的 jsdom API

var jsdom = require('jsdom'),
    { JSDOM } = jsdom,
    jsdom_options = {
      runScripts: "dangerously",
      resources: "usable"
    };

// external script example:
var DOM = new JSDOM(`<!DOCTYPE html><html><head><script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script></head><body></body></html>`, jsdom_options);

// local script example:
var jQuery = fs.readFileSync("../../jQuery.js", { encoding: "utf-8" });
var DOM = new JSDOM(``, { runScripts: "dangerously" });

var scriptElm = window.document.createElement("script");
scriptElm.textContent = jQuery;
DOM.window.document.head.appendChild(scriptElm);

References:参考:

  1. Loading external scripts加载外部脚本
  2. Loading local scripts 加载本地脚本

I plopped this on the top of my Node.js (server) file that uses jQuery to help render html text ...我将它放在我的 Node.js(服务器)文件的顶部,该文件使用 jQuery 来帮助呈现 html 文本......

var jsdom = require("jsdom").jsdom;
jsdom.env({
    html : "<html><body></body></html>",
    done : function(errs, window) {
        global.window = window;
    }
});

and everything comes up roses.一切都是玫瑰。

2021 answer 2021年答案

Faced the same issue recently最近遇到同样的问题

This works with "jquery": "^3.5.1" and "jsdom": "^16.4.0"这适用于"jquery": "^3.5.1""jsdom": "^16.4.0"

const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const jquery = require('jquery')

getHtmlFromSomewhere(function (err, data) {
    handleError(err)
    
    console.log("html is ", data)
    const dom = new JSDOM(data);

    const $ = jquery(dom.window);
    const someData = $("#dataTable tbody tr:last td:eq(1)")

    console.log("some data is: ", someData.text())
});

The gist of the solution is parsing your HTML using JSDOM in order to obtain a window object.该解决方案的要点是使用 JSDOM 解析 HTML 以获得窗口对象。 Then wrap said window object using jquery然后使用 jquery 包装所述窗口对象

And that's it, you can use jquery selector functions in the parsed document就是这样,您可以在解析的文档中使用 jquery 选择器函数

You have to provide a window object.您必须提供一个窗口对象。 To do this, just pass parentWindow from jsdom:为此,只需从 jsdom 传递 parentWindow:

var jsdom = require("jsdom"); 
var $ = require("jquery")(jsdom.jsdom().parentWindow);

I know that I am not in the correct year here, but I may have found a better way, then the ways that offered here.我知道我在这里的年份不正确,但我可能找到了更好的方法,然后是这里提供的方法。 If you call the scripts from the .html file, the script will know the document, and it solved the problem for me (at least for now).如果您从 .html 文件调用脚本,脚本将知道该文档,并且它为我解决了问题(至少目前如此)。 example:例子:

index.html:索引.html:

<html>
<head>
<meta charset="UTF-8">
<!--Scripts-->
<script>
    window.$ = window.jQuery = require('../js/libs/jQuery.js');
</script>
<script src="../js/libs/materialize.js"></script>
<script>
    const init = require("../js/initialize/initialize.js");
    init.initializer.main_init();
</script>

<!--Styles-->
<!--Libraries-->
<link rel="stylesheet" href="../scss/libs/materialize.css" />
</head>
</html>

initialize.js:初始化.js:

var jQuery = require('jquery');

(function($, global, undefined) {
    "use strict";

    var Initialize = function() {
        var initializer;          
        initializer = {
            materialize_init: function () {
            console.log(document.getElementsByClassName("tooltipped"));
            },

            main_initialize: function () {
                this.materialize_init();
            }
        };

        return {
            main_init: function () {
                initializer.main_initialize();
                return this;
            }
        };
    };

    // AMD and window support
    if (typeof define === "function") {
        define([], function () { return new Initialize(); });
    } else if (typeof global.initializer === "undefined") {
        global.initializer = new Initialize();
    }

})(jQuery, this);

Let me know if it's wrong, I just started to work with this framework today.让我知道它是否错了,我今天才开始使用这个框架。

I am currently using this way: check jsdom's documentation我目前正在使用这种方式:检查jsdom 的文档

 var html = fs.readFileSync("./your_html_file.html");

 jsdom.env({
  //url: "http://url_here", //in case you want to load specific url 
  //html property is used in case of you need to load html string here
  html: html,
  scripts: ["http://code.jquery.com/jquery.js"],
  done: function (err, window) {
    var $ = window.$;
    //start using jquery now 
    $("p").each(function(index) {
      console.log("paragraph ", index, $(this).text());
    });
  }
});

I used neoRiley's 2 lines on node command line, and tested jQuery promises on command-line.我在 node 命令行上使用了 neoRiley 的 2 行,并在命令行上测试了 jQuery Promise。 Added jquery to node command line via npm // https://github.com/UncoolAJ86/node-jquery for instructions.通过 npm // https://github.com/UncoolAJ86/node-jquery将 jquery 添加到节点命令行以获取说明。

npm install -S 'jquery@>=2.1'
npm install -S 'jsdom@3.1.2'

/home/sridhar$ node /home/sridhar$ 节点

// make $ available on node commandline
>var jsdom = require("jsdom"); 
>var $ = require("jquery")(jsdom.jsdom().parentWindow);
>var promise = new $.Deferred();
>promise.done(function(){console.log('Starting game ..');});
>promise.resolve();

promise resolves to success callback, 'Starting game ..' will be printed console output承诺解析成功回调,“开始游戏..”将打印控制台输出

Starting game..

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何解决“jQuery需要一个带文档的窗口”错误? - How to solve “jQuery requires a window with a document” error? “ jQuery需要带有文档的窗口” Webpack 2错误 - “jQuery requires a window with a document” webpack 2 error 错误:“ jQuery需要带有文档的窗口”以及Mocha和Typescript? - Error: “jQuery requires a window with a document” with mocha and typescript? 操作 jQuery 得到一个错误:“jQuery 需要一个窗口和一个文档” - Manipulating jQuery to get an error: "jQuery requires a window and a document" 带有Jquery集成的Nightwatch失败,并显示以下错误:jQuery需要带有文档的窗口 - Nightwatch with Jquery integration fails with the error jQuery requires a window with a document Webpack添加jQuery插件:错误:jQuery需要带有文档的窗口 - Webpack adding jQuery plugin: Error: jQuery requires a window with a document Browserify with jQuery> = 2产生“jQuery需要一个带文档的窗口” - Browserify with jQuery >= 2 produces “jQuery requires a window with a document” jQuery 需要一个 window 和 vue native 中的文档 - jQuery requires a window with a document in vue native 错误:jQuery需要一个window带证件。 使用ejs和javascript创建刽子手web app - Error : jQuery requires a window with a document. Using ejs and javascript to create a hangman web app 窗口和文档作为jQuery选择器 - Window and document as jQuery selectors
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM