所以一切都很好,直到做npm更新,现在事情不像以前那样有效。
一点背景:在我的代码中,我使用jquery来解析文本html。我不使用窗口,我不使用jsdom。过去工作得很好:
$ = require("jquery");
$(html).find("<h1>").html("The title");
但现在我明白了: jQuery需要一个带文档的窗口
我该如何解决这个问题?
答案 0 :(得分:34)
node.js-jQuery定义在一行:
// definition
var $ = require('jquery')(require("jsdom").jsdom().parentWindow);
// usage
$("body").append("<div>TEST</div>");
console.log($("body").html());
答案 1 :(得分:15)
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
不再有效。
答案 2 :(得分:10)
这对我有用
var jsdom = require('jsdom');
$ = require('jquery')(new jsdom.JSDOM().window);
答案 3 :(得分:9)
我解决了。不得不首先删除jsdom和jquery然后npm安装jsdom jquery。
然后这个:
var jsdom = require("jsdom");
$ = require("jquery")(jsdom.jsdom().createWindow());
事实证明,我拥有最新版本非常重要。否则它不起作用..
答案 4 :(得分:4)
if(isset($var)){
// do something
}
答案 5 :(得分:3)
您可以在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>
答案 6 :(得分:3)
我把它放在我的Node.js(服务器)文件的顶部,该文件使用jQuery来帮助渲染html文本......
var jsdom = require("jsdom").jsdom;
jsdom.env({
html : "<html><body></body></html>",
done : function(errs, window) {
global.window = window;
}
});
一切都出现了玫瑰。
答案 7 :(得分:3)
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
。
答案 8 :(得分:2)
最近遇到了同样的问题
这适用于 "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 以获得一个 window 对象。然后使用 jquery 包装所述窗口对象
就是这样,您可以在解析的文档中使用 jquery 选择器函数
答案 9 :(得分:0)
您必须提供一个窗口对象。要做到这一点,只需从jsdom传递parentWindow:
var jsdom = require("jsdom");
var $ = require("jquery")(jsdom.jsdom().parentWindow);
答案 10 :(得分:0)
我知道我今年没有在正确的一年,但我可能找到了更好的方式,然后是这里提供的方式。如果从.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);
让我知道如果错了,我今天才开始使用这个框架。
答案 11 :(得分:-1)
我目前正在使用这种方式:检查jsdom's documentation
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());
});
}
});
答案 12 :(得分:-1)
我在节点命令行上使用了neoRiley的2行,并在命令行上测试了jQuery promise。 通过npm向节点命令行添加了jquery // http://developer.android.com/tools/help/adb.html#Enabling获取指示。
npm install -S 'jquery@>=2.1'
npm install -S 'jsdom@3.1.2'
/ home / sridhar $ node
// 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();
承诺解决成功回调,&#39;开始游戏..&#39;将被打印 控制台输出
Starting game..