web-dev-qa-db-fra.com

Comment "activer" les éléments HTML5 dans IE 8 qui ont été insérés par AJAX appel?

Voir la solution au bas de la question.

Internet Explorer 8 (et inférieur) ne fonctionne pas bien avec des éléments inconnus (par exemple, des éléments HTML5), on ne peut pas les styliser ni accéder à la plupart de leurs accessoires. Il existe de nombreux contournements pour cela, par exemple: http://remysharp.com/2009/01/07/html5-enabling-script/

Le problème est que cela fonctionne très bien pour le code HTML statique disponible lors du chargement de la page, mais lorsque vous créez ensuite des éléments HTML5 (par exemple, l'appel AJAX les contenant, ou simplement la création avec JS), il les marquera pour la dernière fois. ajouté des éléments comme HTMLUnknownElement comme supposé à HTMLGenericElement (dans IE débogueur).

Est-ce que quelqu'un connaît une solution pour cela, de sorte que les éléments nouvellement ajoutés soient reconnus/activés par IE 8?

Voici une page de test:

<html><head><title>TIME TEST</title>
    <!--[if IE]>
    <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
</head>

<body>
    <time>some time</time>
    <hr>
    <script type="text/javascript">
        $("time").text("WORKS GREAT");
        $("body").append("<time>NEW ELEMENT</time>"); //simulates AJAX callback insertion
        $("time").text("UPDATE");
    </script>
</body>
</html>

Dans IE, vous verrez les éléments: UPDATE et NEW ELEMENT. Dans tout autre navigateur moderne, vous verrez UPDATE et UPDATE.

28
Gidon

pour tous les problèmes html5 dans IE7, j'utilise html5shiv et pour prendre en charge les éléments html5 qui reviennent en appels ajax, j'utilise innershiv .

ces deux petits plugins ont fonctionné pour moi jusqu'à présent comme un charme.

- Praveen Gunasekara

25
Praveen

jQuery a des façons sombres et magiques de créer des éléments. Utiliser document.createElement à la place devrait faire toute la différence:

var time = document.createElement("time");
time.innerHTML = "WORKS GREAT";
document.appendChild(time);

Je ne pense pas que vous puissiez utiliser la syntaxe .append() (comme .innerHTML += "") avec HTML5 et IE. Le problème n'est pas la capacité d'IE à utiliser ou à afficher les éléments HTML5, mais sa capacité à les analyser. Chaque fois que vous instanciez un élément HTML5 par programme, vous devez le faire avec document.createElement.

4
mattbasta

J'ai aussi eu des problèmes lors de l'extraction d'un groupe de HTML contenant des éléments HTML5 à partir du serveur à l'aide d'AJAX. html5shiv n'a pas pu sauver ma journée. Mon modèle de projet est basé sur html5boilerplate et utilise Modernizr pour corriger le comportement des balises HTML5 dans IE <9. Après avoir lu ce fil de discussion, j'ai eu intuition et gestion pour que mon code fonctionne.

Le code problématique injectant le code HTML fraîchement compressé dans le DOM était le suivant:

var wrapper = $('<div />')
    .addClass('wrapper')
    .html(data.html)
    .appendTo(wrapper);

Fondamentalement, ce qui se passe ici est:

  1. créer un nouvel élément
  2. le innerHTML du nouvel élément est mis à jour
  3. le nouvel élément avec son innerHTML est ajouté à un élément existant dans le DOM

Le changer en ce qui suit corrige mon problème:

var wrapper = $('<div />')
    .addClass('wrapper')
    .appendTo(el);
wrapper.html(data.html);

Qu'est-ce qui se passe maintenant est:

  1. créer un nouvel élément
  2. le nouvel élément vide est ajouté à un élément existant dans le DOM
  3. le innerHTML du nouvel élément ajouté est mis à jour

Maintenant, même IE7 n'a d'autre choix que d'afficher les éléments HTML5 chargés de manière asynchrone comme je le souhaite :)

Merci Julio, gardez votre plugin à portée de main au cas où j'en aurais besoin à l'avenir. Mais pour l'instant, je suis heureux de ne pas ajouter les frais généraux liés aux manipulations supplémentaires du DOM. 

Peut-être que cette solution de contournement fonctionne pour d'autres personnes également.

2
jiggybit

notez que la fonctionnalité innershiv est intégrée à jquery à partir de la version 1.7 http://blog.jquery.com/2011/11/03/jquery-1-7-released/

2
schellmax

Je laisse juste cela pour contribuer à la discussion.

Le script prévoyait que @Gidon semble ne pas fonctionner dans IE8 (testé sur deux machines différentes). J'ai dû refaire le plugin jQuery d'une autre manière, voir ci-dessous:

/**
 * Enable HTML5 Elements on the fly. IE needs to create html5 elements every time.
 * @author Gidon
 * @author Julio Vedovatto <[email protected]>
 * @see http://stackoverflow.com/questions/2363040/how-to-enable-html5-elements-in-ie-that-were-inserted-by-ajax-call
 */
(function ($) {
    jQuery.fn.html5Enabler = function () {
        var element = this;

        if (!$.browser.msie)
            return element;

            $.each(
                ['abbr','article','aside','audio','canvas','details','figcaption','figure','footer','header','hgroup','mark','menu','meter','nav','output','progress','section','summary','time','video'],
                function() {
                    if ($(element).find(this).size() > 0) {
                        $(element).find(this).each(function(k,child){
                            var el = $(document.createElement(child.tagName));

                            for (var i = 0; i < child.attributes.length; i++)
                                el.attr(child.attributes[i].nodeName, child.attributes[i].nodeValue);

                            el.html(child.innerHTML);

                            $(child).replaceWith(el);
                        });
                    }
                }
            );
    };
})(jQuery);
0
Julio Vedovatto