web-dev-qa-db-fra.com

Erreur: jQuery nécessite une fenêtre avec un document

Donc tout fonctionnait parfaitement jusqu'à la mise à jour de npm et maintenant les choses ne fonctionnent plus comme avant. 

Un peu de fond: dans mon code, jquery est utilisé pour analyser du texte HTML. Je n'utilise pas de fenêtre et je n'utilise pas jsdom. Cela fonctionnait très bien pour faire ceci: 

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

Mais maintenant je reçois ceci: JQuery nécessite une fenêtre avec un document

Comment puis-je réparer ça? 

40
Martin

définition de node.js-jQuery sur une ligne:

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

// usage
$("body").append("<div>TEST</div>");
console.log($("body").html());
35
Michael

Le paquet npm pour jQuery incluait certainement jsdom, ce qui explique pourquoi cela fonctionnerait dans Node: jQuery doit disposer d’un environnement DOM pour fonctionner.

Vous pouvez vérifier que les anciennes versions l’avaient, en utilisant npm install [email protected]. Vous verrez que jsdom est installé avec. Pour une raison quelconque, ils semblent avoir supprimé jsdom des versions récentes. Je ne sais pas pourquoi.

Cependant, utiliser jsdom 7.x pour exécuter le code jQuery est 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());
});

Le chemin peut être changé pour une version différente de jQuery ou un fichier local.

Remarque: Les versions précédentes de jsdom, y compris la série 3.x, auraient besoin de la ligne var window = jsdom.jsdom().parentWindow; au lieu de var window = jsdom.jsdom().defaultView;. 4.x a fait en sorte que parentWindow ne fonctionne plus.

15
Louis

Je l'ai résolu. d'abord dû supprimer jsdom et jquery puis npm installer jsdom jquery 

Ensuite ceci: 

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

Il s'avère qu'il était important que je dispose de la dernière version. Sinon ça n'a pas marché .. 

9
Martin

Cela a fonctionné pour moi

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

(2018) - Nouvelle API jsdom

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

Références:

  1. Chargement de scripts externes
  2. Chargement de scripts locaux
4
vsync

Vous pouvez essayer ce qui suit avec ces paramètres de version dans votre package.json:

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

Disons que vous avez un fichier appelé 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>

Ensuite, vous pouvez lire un fichier, créer un DOM et une fenêtre avec JSDOM et le transmettre à 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);
});

affichera:

<div class="left">
<p>left content</p>
</div> and ... 
<p>left content</p>
3
AJ Meyghani

jsdom semble avoir une nouvelle version donc cela fonctionne maintenant d'une manière légèrement différente. Ici vous avez un exemple:

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

Vous pouvez maintenant rechercher comme vous le faisiez sur jQuery:

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

Attention à l’installation de jQuery car vous devriez écrire jquery tout en minuscule, comme npm install jquery.

J'ai placé ceci sur le dessus de mon fichier Node.js (serveur) qui utilise jQuery pour faciliter le rendu du texte HTML ...

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

et tout vient des roses.

3
Mark Peterson

Vous devez fournir un objet window. Pour ce faire, il suffit de passer parentWindow à partir de jsdom:

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

Je sais que je ne suis pas dans la bonne année ici, mais j’ai peut-être trouvé un meilleur moyen, puis les moyens proposés ici. Si vous appelez les scripts à partir du fichier .html, le script connaîtra le document et le problème sera résolu pour moi (du moins pour le moment). Exemple:

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

Faites-moi savoir si c'est faux, je viens de commencer à travailler avec ce framework aujourd'hui.

0
KorelK