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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21358015/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 01:32:35  来源:igfitidea点击:

Error: jQuery requires a window with a document

jquerynode.js

提问by Martin

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. I do not use a window and I don't use jsdom. It used to work just fine to do this:

一点背景:在我的代码中,我使用 jquery 来解析文本 html。我不使用窗口,也不使用 jsdom。它曾经可以很好地执行此操作:

$ = 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?

我该如何解决?

回答by Michael

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());

回答by Aravinthan K

This worked for me

这对我有用

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

回答by Louis

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 [email protected]. You'll see jsdom being installed with it. For some reason they seem to have removed jsdom from the recent releases. I don't know why.

您可以通过执行npm install [email protected]. 您将看到 jsdom 与它一起安装。出于某种原因,他们似乎已经从最近的版本中删除了 jsdom。我不知道为什么。

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;instead of var window = jsdom.jsdom().defaultView;. 4.x made it so that parentWindowno longer works.

注意: jsdom 的早期版本,包括 3.x 系列,需要该行var window = jsdom.jsdom().parentWindow;而不是var window = jsdom.jsdom().defaultView;. 4.x 使它parentWindow不再起作用。

回答by Martin

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..

事实证明,我拥有最新版本很重要。否则它不起作用..

回答by Hola Soy Edu Feliz Navidad

jsdomseems to have a new version therefore now it works on a slightly different way. Here you have an example:

jsdom似乎有一个新版本,因此现在它的工作方式略有不同。这里有一个例子:

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 jqueryall lowercase, like npm install jquery.

注意 jQuery 安装,因为您应该jquery全部写成小写,例如npm install jquery.

回答by vsync

(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
  1. 加载外部脚本
  2. 加载本地脚本

回答by AJ Meyghani

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>

回答by Mark Peterson

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.

一切都出现了玫瑰。

回答by neoRiley

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

回答by KorelK

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). example:

我知道我在这里的年份不正确,但我可能已经找到了更好的方法,然后是这里提供的方法。如果您从 .html 文件调用脚本,脚本将知道该文档,并且它为我解决了问题(至少现在是这样)。例子:

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.

如果有错请告诉我,我今天才开始使用这个框架。