4 votes

IE+jQuery+Ajax+XHTML : Le HTML est coupé après .html() ou .innerHTML

C'est un problème très difficile à exprimer en une phrase brève, alors je m'excuse si je le tue.

J'ai récemment lancé un site qui avait été longuement testé sur mon serveur web local sur toutes les plateformes de navigateur souhaitées, y compris IE8 (mode standard IE8, XHTML Strict). Je n'ai rencontré aucun problème jusqu'à ce que le site soit mis en ligne sur un serveur web dédié.

Le site utilise jQuery.get() en el change pour l'événement input des éléments d'un formulaire, où la réponse est greffée dans un fichier commun <div id="results"></div> .

Malgré les problèmes de mise en cache que j'ai pu lire à propos d'IE et de XMLHTTPRequest, mon problème semble survenir APRÈS le début de l'exécution de ma fonction d'appel ajax. Ma callback (fournie via .get() / .load() -- J'ai essayé les deux) reçoit un fragment HTML renvoyé par mon serveur. Le test du contenu renvoyé dans n'importe quel navigateur révèle exactement ce que j'attends de ce contenu.

Cependant, dès que je place le fragment HTML dans l'arborescence DOM dans le fichier #results En fait, IE supprime les 7 ou 8 premières balises d'ouverture de mon balisage (ainsi que les enfants de la plupart de ces balises). C'est terriblement bizarre. J'ai corrigé ce problème dans une autre partie du site en définissant le contenu HTML via la commande jQuery('#results')[0].innerHTML = content mais pas de dé cette fois.

Exemple de réponse :

<div>
    <a href="#">some link</a>
    <span>stuff, blah blah</span>
    <a href="#">another link</a>

    <ul>
        <li id="item-2342">
            <img src="#" />
            <div class="info">
                <h6> ..title.. </h6>
                <a href="#">View</a>
                <span rel="stats"> ..statistics.. </span>
            </div>
        </li>

        <!-- ... and so on in a loop over items to create more <li> items ... -->
    </ul>
</div>

Littéralement TOUT jusqu'à la balise d'ouverture de ce <span rel="stats"> est tronquée. L'effet est qu'IE affiche mon contenu AJAX retourné comme s'il commençait par le nœud de texte : ..statistics.. </span> . (J'ai essayé de retirer le rel="stats" à la suggestion d'un commentaire ci-dessous, en le changeant en une classe CSS à la place, mais le même résultat se produit).

Si je demande mon url AJAX directement via le champ URL du navigateur, le contenu renvoyé est parfait.

Si j'utilise alert() pour afficher le contenu AJAX retourné, c'est parfait.

Si j'assigne mon contenu AJAX via .html() o .innerHTML il est immédiatement tronqué.

Sooo.... WTF ? Le débogueur (minable) d'IE n'affiche aucune erreur script ou quoi que ce soit de ce genre. Quelqu'un a-t-il déjà eu affaire à ce genre de problème ? Encore une fois, j'insiste sur le fait que sur mon serveur de développement (127.0.0.1), IE n'a aucun problème, et il semble utiliser le même "mode" (IE8 Standards) et tout.

EDIT : Voici le Javascript qui alimente le lookup AJAX :

jQuery('.ajax-panel').live('load', function(event, request_string){
    var panel = jQuery(this).stop(true).fadeTo(100, 0.2).addClass('loading');
    var form = jQuery(panel.attr('rel'));
    jQuery.get(form.attr('action'), request_string ? request_string : form.serialize(), function(response){

        // WTF?
        // panel[0].innerHTML = response;
        panel.empty().append(response);

        // Carry on.
        panel.removeClass('loading').stop(true).fadeTo(100, 1);
    });
});

2voto

Justin Thoo Points 21

J'ai eu un problème similaire où une partie du code html ajouté était coupée, mais si je créais une alerte du html interne, ou si je forçais un défilement, il apparaissait.

Je suis ensuite tombé sur un article qui semblait indiquer qu'IE8 ne redessinait pas correctement le volet. http://ajaxian.com/archives/forcing-a-ui-redraw-from-javascript

Le seul moyen que j'ai trouvé pour le faire fonctionner a été d'ajouter une classe, d'attendre, puis de supprimer la classe. Si je n'attendais pas, il semblait sauter l'exécution.

function Redraw(element)
{
 if ($.browser.msie)
 {
  element.addClass("invisible");
  setTimeout(function(){
    element.removeClass("invisible");
   },1);
 }
}

1voto

Marcel Korpel Points 14633

Que se passe-t-il si vous supprimez rel="stats" ?

El rel n'est pas autorisé à avoir stats en elle, selon MSDN .

1voto

Bob S Points 13

Je peux confirmer le problème. J'ai généré une réponse AJAX similaire à celle de l'expéditeur initial. Quelques informations initiales, puis une boucle à travers les données pour créer 8 div's différents de contenu. Lors de l'exécution de la page, le chargement s'effectuait, mais IE n'affichait qu'une partie des données. Une petite modification a permis de résoudre ce problème.

J'avais un span sur la page (pour un ensemble de balises vidéo) à l'intérieur de chaque div, de sorte que je pouvais tronquer le texte s'il était trop long, et utiliser le span avec l'attribut title comme hovertip. Si la balise span était formatée de cette manière :

<div>Tags: <span title="Miller, Jackson, Brown">Miller, Jackson...</div>

ça ne marcherait pas, alors que :

<div>Tags: Miller, Jackson, Brown</div>

a bien fonctionné. Bien sûr, j'ai remarqué mon erreur : il n'y a pas de balise de fermeture span. La correction de cette erreur a également fonctionné, mais la chose importante que j'ai remarquée est que IE semble être très intolérant aux erreurs de formatage sur AJAX, ou, plus correctement, AHAH.

Après avoir vu cela, je garantis qu'il y a un HTML légèrement malformé dans la chaîne de retour. J'ai eu exactement la même erreur que vous, un fragment d'information renvoyé par le javascript, et la correction de l'erreur a réglé le problème pour moi.

0voto

Ken Redler Points 15204

Je ne sais pas, mais ça m'a aidé une fois avec un problème d'IE :

Au lieu de $('your_container').html( your_content ) , essayez de vider entièrement l'objet conteneur, puis utilisez append() . Donc :

$('your_container').empty().append( your_content );

C'est IE. On ne sait jamais.

0voto

Erik5388 Points 553

Changez toutes vos METHODES en POST. La valeur par défaut est GET.

jQuery.ajax({
    url: form.attr('action'), 
    success: function(){
        panel.empty().append(response);

        // Carry on.
        panel.removeClass('loading').stop(true).fadeTo(100, 1);
    }
});

Ça devrait faire l'affaire... Je sais qu'il me manque des éléments dans vos fonctions, mais c'est l'essentiel.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X