web-dev-qa-db-fra.com

Comment sélectionner des éléments de <template> avec jQuery

J'ai deux sélections similaires. Le premier utilise une balise <div>, ce qui fonctionne bien, le second utilise une nouvelle balise <template>, qui ne fonctionne plus.

Quelqu'un peut-il me dire comment faire fonctionner ceci avec jQuery en utilisant la balise <template>?

HTML

<div id="div">
    <div>content</div>
</div>

<template id="template">
    <div>content</div>
</template>

JavaScript

var $div = $('#div');
var $content = $div.find('div');
console.log($content); //works ($content.length == 1)

var $template = $('#template');
var $content = $template.find('div');
console.log($content); //doesn't work ($content.length == 0)

http://jsfiddle.net/s8b5w0Le/1/

20
Simon Ferndriger

HTMLTemplateElement enregistre le DOM dans un attribut séparé:

JQuery

<script src="jquery-3.1.0.js"></script>
<script type="text/javascript">
    $(document).ready(function()
    {
        var $div = $('#div');
        var $content = $div.find('div');
        console.log($content.text()); // output "content", inner div

        var $template = $('#template');
        var node = $template.prop('content');
        var $content = $(node).find('div');
        console.log($content.text()); // output "content", inner template
    });

JavaScript

document.createElement('template').content
17
Martin Wantke

Je suis à peu près sûr que cela a à voir avec l'utilisation de Shadow Dom par Chrome (merci à Polymer ...)

Vous pouvez soit tenter votre chance en utilisant le combinateur /deep/ (cela ne fonctionnera probablement pas sur d'autres navigateurs), mais je pense que la solution la plus robuste serait $template[0].outerHTML comme dans votre commentaire si vous avez juste besoin du texte.

Si vous avez besoin de la fonctionnalité jQuery, utiliser $.parseXML (pour éviter la construction de dom native de Chrome) conviendrait probablement pour tous les navigateurs (peut confirmer Chrome + FF).

Exemple ici: http://jsfiddle.net/3fe9jjfj

var tc = $('#template')[0].outerHTML;

$template = $($.parseXML(tc)).contents();

console.log($template);
console.log($template.find('div'));

Les deux journaux sont renvoyés comme prévu et $template peut désormais être traité comme un objet jQuery ordinaire.

6
Aaron Hammond

Comme d'autres l'ont noté, Chrome place les éléments enfants <template> dans un DOM fantôme. Pour y accéder:

// Access the JavaScript object for the template content
$('template')[0]

// Make a jQuery selection out of it
$($('template')[0])

// Now you can search it
$($('template')[0]).find('div.someclass').css('color','#000');
2
Jake Wilson