120 votes

Exécution du <script injecté par innerHTML après un appel AJAX

Il y a une division appelée "Contenu" :

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

Il doit être rempli avec des données provenant d'un fichier PHP, par AJAX, comprenant un <script> étiquette. Cependant, le script à l'intérieur de cette balise n'est pas exécuté.

<div id="content"><!-- After AJAX loads the stuff that goes here -->
   <script type="text/javascript">
     //code
   </script>
   <!-- More stuff that DOES work here -->
</div>

0 votes

Comment chargez-vous le div ? Cela dépend de la bibliothèque que vous utilisez, vous pouvez normalement contrôler si vous voulez juste exécuter les scripts après le chargement ajax.

1 votes

Après window.onload Je crée un XMTHttpRequest pour demander une autre page (php) qui contient le contenu du div, y compris un script. Je fais cela avec du simple JS, pas de bibliothèque (autre que la mienne).

81voto

Firas Nizam Points 340

J'ai utilisé ce code, il fonctionne bien

var arr = MyDiv.getElementsByTagName('script')
for (var n = 0; n < arr.length; n++)
    eval(arr[n].innerHTML)//run script inside div

5 votes

Si vous voulez mon avis, c'est une bien meilleure réponse que celle qui a été acceptée. C'est à peu près l'injection de JavaScript.

0 votes

Bien qu'utile, cela ne répond pas vraiment à la question du pourquoi des scripts. ne serait pas courir. Voir par exemple jsfiddle.net/fkqmcaz7 y jsfiddle.net/wnn5fz3m/1 Il doit absolument fonctionner, et je ne trouve pas de cas simplifié où il ne fonctionne pas.

1 votes

@NaoiseGolden Le PO demande littéralement l'exécution de script, donc je pense que c'est bon ici :-)

73voto

Chocula Points 824

Le JavaScript inséré en tant que texte DOM ne s'exécutera pas. Cependant, vous pouvez utiliser la fonction Modèle dynamique de script. pour atteindre votre objectif. L'idée de base est de déplacer le script que vous voulez exécuter dans un fichier externe et de créer une balise script lorsque vous obtenez votre réponse Ajax. Vous définissez ensuite la balise src de votre balise script et voilà, il charge et exécute le script externe.

Cet autre article de StackOverflow peut également vous être utile : Peut-on insérer des scripts avec innerHTML ? .

0 votes

Vous pouvez sélectionner tous les scripts chargés et les exécuter par la fonction eval() : $('#audit-view script').each(function (index, element) { eval(element.innerHTML); })

1 votes

Le Javascript ajouté à la page doit absolument s'exécuter. ( jsfiddle.net/wnn5fz3m/1 par exemple). La question est de savoir pourquoi ce n'est pas le cas parfois.

0 votes

@Chocula j'ai déplacé mon script dans un fichier séparé mais il ne fonctionne toujours pas à partir du partiel pouvez-vous m'aider ? stackoverflow.com/questions/42941856/

15voto

Christopher Tokar Points 3112

Si vous chargez un bloc script dans votre div via Ajax comme ceci :

<div id="content">
    <script type="text/javascript">
    function myFunction() {
      //do something
    }
    myFunction();
    </script>
</div>

... il met simplement à jour le DOM de votre page, myFunction() n'est pas nécessairement appelé.

Vous pouvez utiliser une méthode de rappel Ajax, telle que celle du module jQuery ajax() pour définir ce qu'il faut exécuter lorsque la requête se termine.

Ce que vous faites est différent du chargement d'une page avec JavaScript inclus dès le départ (qui est exécuté).

Un exemple de la façon d'utiliser le rappel de réussite et le rappel d'erreur après avoir récupéré du contenu :

  $.ajax({
    type: 'GET',
    url: 'response.php',
    timeout: 2000,
    success: function(data) {
      $("#content").html(data);
      myFunction();
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
      alert("error retrieving content");
    }

Une autre façon rapide et sale est d'utiliser eval() pour exécuter tout code script que vous avez inséré comme texte DOM si vous ne voulez pas utiliser jQuery ou une autre bibliothèque.

0 votes

En utilisant le callback de jQuery, comment pourrais-je "exécuter" le code à l'intérieur du nouveau <script> ?

0 votes

J'ai ajouté un exemple d'utilisation du rappel de réussite :

1 votes

Merci beaucoup ! La partie "myFunction() ;" était ce que je laissais de côté dans mon code.

11voto

Evgeny Points 2765

Voici le script qui évaluera toutes les balises script dans le texte.

function evalJSFromHtml(html) {
  var newElement = document.createElement('div');
  newElement.innerHTML = html;

  var scripts = newElement.getElementsByTagName("script");
  for (var i = 0; i < scripts.length; ++i) {
    var script = scripts[i];
    eval(script.innerHTML);
  }
}

Il suffit d'appeler cette fonction après avoir reçu votre HTML du serveur. Attention : l'utilisation de eval peut être dangereux.

Démonstration : http://plnkr.co/edit/LA7OPkRfAtgOhwcAnLrl?p=preview

6voto

Phrogz Points 112337

Cela fonctionne pour moi en utilisant jQuery, à condition que vous n'essayiez pas d'ajouter un sous-ensemble du HTML renvoyé par le XHR au document. (Voir ce rapport de bogue montrant le problème avec jQuery).

Voici un exemple montrant son fonctionnement :

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html lang="en"> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
    <title>test_1.4</title> 
    <script type="text/javascript" charset="utf-8" src="jquery.1.4.2.js"></script> 
    <script type="text/javascript" charset="utf-8"> 
        var snippet = "<div><span id='a'>JS did not run<\/span><script type='text/javascript'>" +
        "$('#a').html('Hooray! JS ran!');" +
        "<\/script><\/div>";
        $(function(){
            $('#replaceable').replaceWith($(snippet));
        });
    </script> 
</head> 
<body> 
    <div id="replaceable">I'm going away.</div> 
</body> 
</html>

Voici l'équivalent de ce qui précède : http://jsfiddle.net/2CTLH/

1 votes

Il est très peu probable que ce soit la solution au problème actuellement, car il s'agissait d'un bogue avec une très ancienne version de jQuery.

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