2010-11-02 4 views
27

Je dois 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 a quelques scripts nécessaires et il semble que la fonction jquery html() les raye, J'ai besoin de filtrer la réponse et obtenir seulement une div spécifique.jquery html() supprime les balises de script

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é ce vieux sujet: jQuery - script tags in the HTML are parsed out by jQuery and not executed

mais est une conclusion. J'ai essayé les solutions proposées mais aucune d'entre elles ne fonctionne.

EDIT: Je 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 facile.

Répondre

25

Modifier: Je suis fatigué et je ne réfléchis pas. Vous pouvez simplement utiliser la méthode innerHTML native au lieu de .html():

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

réponse originale:

Mon intuition est que la réponse que vous ne lié fonctionne pas pour vous parce que les scripts inclus sont appelés à un attribut src plutôt qu'un contenu de script entre les balises <script> et </script>. 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, cela n'a pas été testé pour n'importe quoi et peut manger des bébés.

+13

mange des bébés, haahaha! –

+1

'.innerHTML' fonctionne ok mais le script à l'intérieur du nouveau contenu ne s'exécute pas ... une idée? – agpt

+0

@Aman, s'il vous plaît postez une question avec une explication de ce que vous essayez de faire, ce que vous avez essayé, et comment il échoue. – eyelidlessness

-2

Essayez

$('#feedback-'+ idfeedback).empty().append(response); 

Je ne l'ai pas testé. Je ne sais pas si .html() vraiment dépouille <script> mais essayez-le.

+1

Cela fonctionne de cette façon, mais j'ai besoin de filtrer la réponse avant d'ajouter au DOM. J'ai essayé cette var x = $ (réponse) .find ('# feedback -' + idfeedback); $ ('# feedback -' + idfeedback) .empty(). Append (x); mais alors les scripts sont à nouveau déshabillés – brpaz

-8

Pouvez-vous me montrer le résultat structure html?

MISE À JOUR 2010/11/03

Vous pouvez éliminer <script> tag de .html() résultat avec une expression régulière.
De votre premier code, après cette ligne.

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

Vous pouvez faire quelque chose comme ceci.

x = x.replace(/\n/g, '{n}') 
.replace(/<script.*?<\/script>/g, '') 
.replace(/{n}/g, '\n'); 
+1

Comment est-ce une réponse? –

+0

la réponse apparaît correctement avec tous les scripts. mais tout filtre que j'applique après que dans les bandes les étiquettes de script. – brpaz

+0

Je mets à jour ma solution ci-dessus. – diewland

2

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 pouvait pas changer de quelque façon.

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

J'utilisé $.get() pour aller chercher cette page HTML. Maintenant que j'ai le code sous forme de chaîne, il est temps de faire une recherche avec jQuery. Mon but était d'isoler le code Javascript à l'intérieur du <script> -Tag, qui appartient au DIV identifier2, mais pas au identifier1. Donc, ce que je voulais obtenir est bar(456) comme chaîne de résultat. En raison de la raison, que jQuery bandes tous les script-tags, vous ne pouvez pas recherche plus 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 simple. Au début, nous remplacerons tous <script> -Tags avec 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) 

Il est un simple hack, mais ça fonctionne!

+2

Je méprise ce bidouillage mais ça marche donc j'ai voté. Le HTML vous force parfois à faire de telles choses. – usr

Questions connexes