[英]Error: jQuery requires a window with a document
因此,在進行 npm update 之前,一切都工作得很好,現在一切都不像以前那樣工作了。
一點背景知識:在我的代碼中,我使用 jquery 來解析文本 html。 我不使用窗口,也不使用 jsdom。 它曾經很好地做到這一點:
$ = require("jquery");
$(html).find("<h1>").html("The title");
但現在我明白了:jQuery 需要一個帶有文檔的窗口
我該如何解決?
這對我有用
var jsdom = require('jsdom');
$ = require('jquery')(new jsdom.JSDOM().window);
node.js-jQuery 定義在一行中:
// definition
var $ = require('jquery')(require("jsdom").jsdom().parentWindow);
// usage
$("body").append("<div>TEST</div>");
console.log($("body").html());
jQuery 的 npm 包肯定曾經包含 jsdom,這就是為什么它可以在 Node 中工作的原因:jQuery 需要有某種 DOM 環境才能使用。
您可以通過執行npm install jquery@1.8.3
檢查舊版本是否曾經擁有它。 你會看到 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
不再工作。
我解決了。 必須先刪除 jsdom 和 jquery,然后 npm install jsdom jquery。
然后這個:
var jsdom = require("jsdom");
$ = require("jquery")(jsdom.jsdom().createWindow());
事實證明,我擁有最新版本很重要。 不然沒用。。
jsdom
似乎有一個新版本,因此現在它的工作方式略有不同。 這里有一個例子:
const { JSDOM } = require("jsdom");
const myJSDom = new JSDOM (html);
const $ = require('jquery')(myJSDom.window);
現在您可以像以前在 jQuery 上一樣進行搜索:
$("<h1>").html("The title");
請注意 jQuery 安裝,因為您應該將jquery
全部小寫,例如npm install jquery
。
您可以在package.json
中使用這些版本設置嘗試以下操作:
"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>
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);
我將它放在我的 Node.js(服務器)文件的頂部,該文件使用 jQuery 來幫助呈現 html 文本......
var jsdom = require("jsdom").jsdom;
jsdom.env({
html : "<html><body></body></html>",
done : function(errs, window) {
global.window = window;
}
});
一切都是玫瑰。
最近遇到同樣的問題
這適用於"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())
});
該解決方案的要點是使用 JSDOM 解析 HTML 以獲得窗口對象。 然后使用 jquery 包裝所述窗口對象
就是這樣,您可以在解析的文檔中使用 jquery 選擇器函數
您必須提供一個窗口對象。 為此,只需從 jsdom 傳遞 parentWindow:
var jsdom = require("jsdom");
var $ = require("jquery")(jsdom.jsdom().parentWindow);
我知道我在這里的年份不正確,但我可能找到了更好的方法,然后是這里提供的方法。 如果您從 .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>
初始化.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);
讓我知道它是否錯了,我今天才開始使用這個框架。
我目前正在使用這種方式:檢查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());
});
}
});
我在 node 命令行上使用了 neoRiley 的 2 行,並在命令行上測試了 jQuery Promise。 通過 npm // https://github.com/UncoolAJ86/node-jquery將 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..
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.