web-dev-qa-db-fra.com

jquery html () supprime les balises de script

J'ai besoin de remplacer le contenu d'un div dans ma page par le résultat html d'un appel ajax. Le problème est que le html contient certains scripts nécessaires et il semble que la fonction jquery html () les supprime, j'ai besoin de filtrer la réponse et d'obtenir uniquement un div spécifique.

Je pense à une solution de contournement qui consiste à extraire toutes les balises de script de la réponse ajax, puis à les ajouter au DOM, mais j'ai du mal à le faire.

Voici mon code;

   $('a.link-vote').live('click',function(){
        var idfeedback = $(this).attr('id').split('-')[1];
        var href = $(this).attr('href');
        $('.feedback-' + idfeedback + '-loader').show();
        $.ajax({
            type: "POST",
            url: href,
            success: function(response){
               var x = $(response).find('#feedback-'+ idfeedback).html();
               $('.feedback-' + idfeedback + '-loader').hide();
               $('#feedback-'+ idfeedback).html(x);

            }
        });
        return false;
    });

J'ai trouvé cet ancien sujet: jQuery - les balises de script dans le HTML sont analysées par jQuery et non exécutées

mais c'est une conclusion. J'ai essayé les solutions suggérées mais aucune ne fonctionne.

EDIT: Il me semble avoir trouvé une solution de contournement basée sur ce vieux sujet mais ce n'est pas joli;

  var dom = $(response);
                // var x = $(response).find('#feedback-'+ idfeedback).html();
                $('.feedback-' + idfeedback + '-loader').hide();
                //$('#feedback-'+ idfeedback).html(x);

                $('#feedback-'+ idfeedback).html(dom.find('#feedback-'+ idfeedback).html());

                dom.filter('script').each(function(){
                    var obj = $(this);
                    $('#feedback-'+ idfeedback + ' .feedback-comments').append(obj);
                });

Il doit y avoir un moyen simple.

29
brpaz

Edit: je suis fatigué et ne pense pas. Vous pouvez simplement utiliser la méthode native innerHTML au lieu de .html():

$('#feedback-' + idfeedback)[0].innerHTML = x;

Réponse originale:

Mon intuition est que la réponse que vous avez liée ne fonctionne pas pour vous car les scripts inclus sont appelés avec un attribut src plutôt que du contenu de script entre les <script> et </script> Mots clés. Cela pourrait fonctionner:

$.ajax({
    url: 'example.html',
    type: 'GET',
    success: function(data) {

        var dom = $(data);

        dom.filter('script').each(function(){
            if(this.src) {
                var script = document.createElement('script'), i, attrName, attrValue, attrs = this.attributes;
                for(i = 0; i < attrs.length; i++) {
                    attrName = attrs[i].name;
                    attrValue = attrs[i].value;
                    script[attrName] = attrValue;
                }
                document.body.appendChild(script);
            } else {
                $.globalEval(this.text || this.textContent || this.innerHTML || '');
            }
        });

        $('#mydiv').html(dom.find('#something').html());

    }
});

Notez que cela n'a été testé pour rien et peut manger des bébés.

27
eyelidlessness

J'ai eu le même problème, mais avec plus de problèmes que je ne pouvais pas résoudre facilement. Mais j'ai trouvé une solution:

Ceci est ma pseudo-source (HTML) que je ne pouvais pas changer en aucune façon.

<html>
  <body>
    <div id="identifier1">
      <script>foo(123)</script>
    </div>
    <div id="identifier2">
      <script>bar(456)</script>
    </div>
  </body>
</html>

J'ai utilisé $.get() pour récupérer cette page HTML. Maintenant que j'ai le code sous forme de chaîne, il est temps de le rechercher avec jQuery. Mon objectif était d'isoler le Javascript-Code à l'intérieur de la balise <script>, Qui appartient au DIV identifier2, Mais pas à identifier1. Donc, ce que je voulais obtenir, c'est bar(456) comme chaîne de résultat. En raison de la raison pour laquelle jQuery supprime toutes les balises de script, vous ne pouvez plus rechercher comme ceci:

var dom = $(data); //data is the $.get() - Response as a string
var js = dom.filter('div#identifier2 script').html();

La solution est une solution de contournement simple. Au début, nous remplacerons tous les <script> - Tags par quelque chose comme <sometag>:

var code = data.replace(/(<script)(.*?)(<\/script>)/gi, '<sometag$2</sometag>');
var dom = $(code);
var result = dom.find('div#identifier2 sometag').html(); 

//result = bar(456)

C'est un simple hack, mais ça marche!

3
Fidelis

C'est la solution la plus simple:

var keepScripts;
keepScripts = true;
$.parseHTML(yourHtmlString, keepScripts);

Cela gardera les balises de script dans;)

1
Peter Hrebik