node.js-错误:jQuery需要带有文档的窗口

因此,在进行npm更新之前,一切都工作得很好,现在一切都不再像以前那样正常。

一点背景:在我的代码中,我使用jquery解析文本html。 我不使用窗口,也不使用jsdom。 过去可以很好地做到这一点:

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

但是现在我得到了:jQuery需要带有文档的窗口

我该如何解决?

Martin asked 2020-07-09T18:09:17Z
12个解决方案
33 votes

一行中的node.js-jQuery定义:

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

// usage
$("body").append("<div>TEST</div>");
console.log($("body").html());
Michael answered 2020-07-09T18:09:32Z
15 votes

jQuery的npm软件包肯定曾经包含jsdom,这就是为什么它在Node中完全可以工作的原因:jQuery需要具有某种DOM环境才能使用。

您可以通过执行var window = jsdom.jsdom().parentWindow;来检查以前使用的旧版本。您会看到jsdom随它一起安装。 由于某些原因,他们似乎已从最新版本中删除了jsdom。 我不知道为什么

但是,使用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());
});

路径可以更改为其他版本的jQuery或本地文件。

注意:jsdom的较早版本(包括3.x系列)将需要var window = jsdom.jsdom().parentWindow;行而不是var window = jsdom.jsdom().defaultView;。4.x使其无法运行parentWindow

Louis answered 2020-07-09T18:10:10Z
14 votes

这对我有用

var jsdom = require('jsdom');
$ = require('jquery')(new jsdom.JSDOM().window);
Aravinthan K answered 2020-07-09T18:10:30Z
9 votes

我解决了 必须先删除jsdom和jquery,然后再npm安装jsdom jquery。

然后这样:

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

原来,拥有最新版本很重要。 否则它不起作用..

Martin answered 2020-07-09T18:10:58Z
4 votes

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

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

现在您可以像以前一样在jQuery上进行搜索:

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

注意jQuery安装,因为您应该将jquery都写成小写,例如npm install jquery

Hola Soy Edu Feliz Navidad answered 2020-07-09T18:11:27Z
4 votes

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

参考文献:

  1. 加载外部脚本
  2. 加载本地脚本
vsync answered 2020-07-09T18:12:00Z
3 votes

您可以在page.htm中使用以下版本设置尝试以下操作:

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

假设您有一个名为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>

然后,您可以读取文件,使用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);
});

将输出:

<div class="left">
<p>left content</p>
</div> and ... 
<p>left content</p>
AJ Meyghani answered 2020-07-09T18:12:33Z
3 votes

我将其放在使用jQuery来呈现html文本的Node.js(服务器)文件的顶部。

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

一切都出现了玫瑰。

Mark Peterson answered 2020-07-09T18:12:57Z
0 votes

您必须提供一个窗口对象。 为此,只需从jsdom中传递parentWindow:

var jsdom = require("jsdom"); 
var $ = require("jquery")(jsdom.jsdom().parentWindow);
neoRiley answered 2020-07-09T18:13:17Z
0 votes

我知道我现在不是正确的年份,但是我可能找到了一个比这里提供的更好的方法。 如果您从.html文件中调用脚本,则该脚本将知道该文档,并为我(至少目前)解决了该问题。 例:

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

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

让我知道是否有错,我今天才开始使用此框架。

KorelK answered 2020-07-09T18:13:50Z
-1 votes

我目前正在使用这种方式:检查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());
    });
  }
});
Muhammad Soliman answered 2020-07-09T18:14:10Z
-1 votes

我在节点命令行上使用了neoRiley的2行,并在命令行上测试了jQuery promise。通过npm将jquery添加到节点命令行//[https://github.com/UncoolAJ86/node-jquery]以获取说明。

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

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

承诺解析为成功回调,将显示“开始游戏..”控制台输出

Starting game..
signonsridhar answered 2020-07-09T18:14:39Z
translate from https://stackoverflow.com:/questions/21358015/error-jquery-requires-a-window-with-a-document