Error: jQuery requires a window with a document

Jquerynode.js

Jquery Problem Overview


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?

Jquery Solutions


Solution 1 - Jquery

This worked for me

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

Solution 2 - Jquery

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.

Solution 3 - Jquery

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

Solution 4 - Jquery

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.

Solution 5 - 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>

Solution 6 - Jquery

(2018) - New 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

Solution 7 - Jquery

I plopped this on the top of my Node.js (server) file that uses jQuery to help render html text ...

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

and everything comes up roses.

Solution 8 - Jquery

2021 answer

Faced the same issue recently

This works with "jquery": "^3.5.1" and "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())
});

The gist of the solution is parsing your HTML using JSDOM in order to obtain a window object. Then wrap said window object using jquery

And that's it, you can use jquery selector functions in the parsed document

Solution 9 - Jquery

You have to provide a window object. To do this, just pass parentWindow from jsdom:

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

Solution 10 - Jquery

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:

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

Let me know if it's wrong, I just started to work with this framework today.

Solution 11 - Jquery

I am currently using this way: check 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());
    });
  }
});

Solution 12 - Jquery

I used neoRiley's 2 lines on node command line, and tested jQuery promises on command-line. Added jquery to node command line via npm //https://github.com/UncoolAJ86/node-jquery for instructions.

npm install -S 'jquery@>=2.1'
npm install -S '[email protected]'

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

promise resolves to success callback, 'Starting game ..' will be printed console output

Starting game..

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMartinView Question on Stackoverflow
Solution 1 - JqueryAravinthan KView Answer on Stackoverflow
Solution 2 - JqueryLouisView Answer on Stackoverflow
Solution 3 - JqueryMartinView Answer on Stackoverflow
Solution 4 - JqueryHola Soy Edu Feliz NavidadView Answer on Stackoverflow
Solution 5 - JqueryAJ MeyghaniView Answer on Stackoverflow
Solution 6 - JqueryvsyncView Answer on Stackoverflow
Solution 7 - JqueryMark PetersonView Answer on Stackoverflow
Solution 8 - JqueryMartín ZaragozaView Answer on Stackoverflow
Solution 9 - JqueryneoRileyView Answer on Stackoverflow
Solution 10 - JqueryCoralKView Answer on Stackoverflow
Solution 11 - JqueryMuhammad SolimanView Answer on Stackoverflow
Solution 12 - JquerysignonsridharView Answer on Stackoverflow