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.
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:
$ = require("jquery");
$(html).find("<h1>").html("The title");
But now I get this: jQuery requires a window with a document
How do I fix this?
This worked for me
var jsdom = require('jsdom');
$ = require('jquery')(new jsdom.JSDOM().window);
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.
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.
However, using jsdom 7.x to run jQuery code is simple:
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.
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 parentWindow
no longer works.
I solved it. had to first remove jsdom and jquery then 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. 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:
$("<h1>").html("The title");
Mind the jQuery installation as you should write jquery
all lowercase, like npm install jquery
.
You can try the following with these version settings in your package.json
:
"jquery": "^2.1.1",
"jsdom": "^1.0.0-pre.3"
Say you have a file called 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:
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>