Question utiliser document.createDocumentFragment () et innerHTML pour manipuler un DOM


Je crée un fragment de document comme suit:

var aWholeHTMLDocument = '<!doctype html> <html><head></head><body><h1>hello world</h1></body></html>';
var frag = document.createDocumentFragment();
frag.innerHTML = aWholeHTMLDocument;

La variable aWholeHTMLDocument contient une longue chaîne qui correspond au document HTML complet d'une page et je souhaite l'insérer dans mon fragment afin de générer et de manipuler le dom de manière dynamique.

Ma question est la suivante: une fois que j'ai ajouté cette chaîne à frag.innerHTML, ne devrait-elle pas charger cette chaîne et la convertir en objet DOM? Après avoir défini innerHTML, ne devrais-je pas avoir accès au DOM via une propriété? J'ai essayé frag.childNodes mais il ne semble pas contenir quoi que ce soit, et tout ce que je veux, c'est accéder à ce nouveau DOM.


25
2017-11-20 14:32


origine


Réponses:


Vous ne pouvez pas définir le innerHTML d'un fragment de document comme vous le feriez avec un nœud normal, c'est le problème. L'ajout d'une div standard et la définition de innerHTML constituent la solution commune.


22
2017-11-20 14:37



Je sais que cette question est ancienne, mais j'ai rencontré le même problème en jouant avec un fragment de document car je n'avais pas réalisé que je devais lui ajouter une div et utiliser les div innerHTML charger des chaînes de HTML dans et obtenir des éléments DOM de celui-ci. J'ai eu d'autres réponses sur comment faire ce genre de chose, mieux adapté pour entier documents.

Dans Firefox (23.0.1), il semble que la définition de la propriété innerHTML du fragment de document ne génère pas automatiquement les éléments. Ce n'est qu'après l'ajout du fragment au document que les éléments sont créés.

Créer un entier document utiliser le document.implementation méthodes si elles sont supportées. J'ai réussi à le faire sur Firefox, mais je ne l'ai pas vraiment testé sur d'autres navigateurs. Vous pouvez regarder HTMLParser.js dans AtropaToolbox pour un exemple d'utilisation document.implementation méthodes. J'ai utilisé ce morceau de script pour XMLHttpRequest pages et les manipuler ou en extraire des données. Les scripts de la page ne sont cependant pas exécutés, ce que je voulais bien que ce ne soit pas ce que vous voulez. La raison pour laquelle je suis allé avec cette méthode plutôt verbeuse au lieu d'essayer d'utiliser l'analyse disponible à partir du XMLHttpRequest L'objet était directement que je rencontrais pas mal de problèmes d'analyse syntaxique à l'époque et je voulais préciser que la doc devrait être analysée en HTML 4 Transitional car elle semble prendre toutes sortes de slop et produire un DOM.

Il y a aussi DOMParser disponible qui peut être plus facile à utiliser. Il y a une implémentation d'Eli Gray sur la page de MDN pour les navigateurs qui n'ont pas la DOMParser mais supporte document.implementation.createHTMLDocument. Les spécifications pour DOMParser spécifiez que les scripts de la page ne sont pas exécutés et que le contenu des balises noscript doit être rendu.

Si vous avez vraiment besoin de scripts activés dans la page, vous pouvez créer un iFrame avec 0 hauteur, 0 largeur, pas de bordure, etc. Il serait toujours dans la page mais vous pourriez le cacher assez bien.

Il y a aussi la possibilité d'utiliser window.open() avec document.write, Les méthodes DOM ou ce que vous voulez. Certains navigateurs vous permettent même de faire des données URI maintenant.

var x = window.open( 'data:text/html;base64,' + btoa('<h1>hi</h1>') );
// wait for the document to load. It only takes a few milliseconds
// but we'll wait for 5 seconds so you can watch the child window
// change.
setTimeout(function () {
    console.log(x.document.documentElement.outerHTML);
    x.console.log('this is the console in the child window');
    x.document.body.innerHTML = 'oh wow';
}, 5000);

Donc, vous avez quelques options pour créer entierdocuments hors écran / cachés et les manipuler, tous prenant en charge le chargement du document à partir de chaînes.

Il y a aussi phantomjs, un projet génial produisant un navigateur Web scriptable sans tête basé sur webkit. Vous aurez accès au système de fichiers local et pourrez faire à peu près tout ce que vous voulez. Je ne sais pas vraiment ce que vous essayez d'accomplir avec votre script et votre manipulation de page complète.


4
2017-09-04 02:25



Pour un module complémentaire Firefox, il est probablement plus judicieux d'utiliser document.implementation.createHTMLDocument méthode, puis aller du DOM qui vous donne.


2
2018-03-08 10:47



Tandis que DocumentFragment ne supporte pas innerHTML, <template>  Est-ce que.

le content propriété d'un <template> l'élément est un DocumentFragment donc il se comporte de la même manière. Par exemple, vous pouvez faire:

var tpl = document.createElement('template');
tpl.innerHTML = '<tr><td>Hello</td><td>world</td></tr>';
document.querySelector('table').appendChild(tpl.content);

L’exemple ci-dessus est important car vous ne pouvez pas le faire avec innerHTML et par ex. une <div>, parce qu'un <div> ne permet pas de <tr> éléments en tant qu'enfants.


REMARQUE: UNE DocumentFragment va toujours dépouiller le <head> et <body> tags, il ne fera pas ce que vous voulez non plus. Vous devez vraiment créer un tout nouveau Document.


2
2017-11-21 20:00



Avec un fragment de document, vous ajouteriez des éléments que vous aviez créés avec document.createElement('yourElement'). aWholeHTMLDocument est simplement du texte. De plus, à moins que vous n'utilisiez des cadres, je ne sais pas pourquoi vous devez créer le document HTML complet, utilisez simplement ce qui se trouve à l'intérieur du document. <body> Mots clés.


1
2017-11-20 14:40



Utilisation appendChild

voir https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment

var fragment = document.createDocumentFragment();
... fragment.appendChild(some element);
document.querySelector('blah').appendChild(fragment);

1
2018-05-04 16:27



Utilisez querySelector () pour obtenir un enfant du fragment de document (vous voulez probablement le corps ou un enfant du corps). Ensuite, obtenez le innerHTML.

document.body.innerHTML = aWholeHTMLDocument.querySelector("body").innerHTML

ou

aWholeHTMLDocument.querySelector("body").childNodes;

Voir https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment.querySelector


0
2018-01-06 01:09