107 votes

Comment forcer un script à se recharger et à se réexécuter ?

J'ai une page qui charge un script d'une tierce partie (fil d'actualité). Le src L'url du script est attribuée dynamiquement au chargement (par le code d'un tiers).

<div id="div1287">
    <!-- dynamically-generated elements will go here. -->
</div>

<script id="script0348710783" type="javascript/text">
</script>

<script type="javascript/text">
    document.getElementById('script0348710783').src='http://oneBigHairyURL';
</script>

Le script chargé à partir de http://oneBigHairyURL crée et charge ensuite des éléments avec les différents éléments du flux d'actualités, avec un joli formatage, etc. dans div1287 (l'identifiant "div1287" est transmis en http://oneBigHairyURL afin que le script sache où charger le contenu).

Le seul problème est qu'il ne le charge qu'une seule fois. J'aimerais qu'il se recharge (et donc qu'il affiche un nouveau contenu) toutes les n secondes.

Je me suis donc dit que j'allais essayer ceci :

<div id="div1287">
    <!-- dynamically-generated elements will go here. -->
</div>

<script id="script0348710783" type="javascript/text">
</script>

<script type="javascript/text">
    loadItUp=function() {
        alert('loading...');
        var divElement = document.getElementById('div1287');
        var scrElement = document.getElementById('script0348710783');

        divElement.innerHTML='';
        scrElement.innerHTML='';
        scrElement.src='';
        scrElement.src='http://oneBigHairyURL';
        setTimeout(loadItUp, 10000);
    };
    loadItUp();
</script>

Je reçois l'alerte, la div s'efface, mais aucun code HTML généré dynamiquement n'est rechargé dans la div.

Une idée de ce que je fais mal ?

94voto

Kelly Points 8780

Pourquoi ne pas ajouter une nouvelle balise script à <head> avec le script à (re)charger ? Quelque chose comme ci-dessous :

<script>
   function load_js()
   {
      var head= document.getElementsByTagName('head')[0];
      var script= document.createElement('script');
      script.src= 'source_file.js';
      head.appendChild(script);
   }
   load_js();
</script>

Le point principal est l'insertion d'une nouvelle balise script -- vous pouvez supprimer l'ancienne sans conséquence. Vous devrez peut-être ajouter un horodatage à la chaîne de requête si vous avez des problèmes de mise en cache.

46voto

Luke Points 1780

Voici une méthode similaire à celle de Kelly, mais qui supprime tout script préexistant avec la même source, et qui utilise jQuery.

<script>
    function reload_js(src) {
        $('script[src="' + src + '"]').remove();
        $('<script>').attr('src', src).appendTo('head');
    }
    reload_js('source_file.js');
</script>

Notez que l'attribut "type" n'est plus nécessaire pour les scripts à partir de HTML5. ( http://www.w3.org/html/wg/drafts/html/master/scripting-1.html#the-script-élément )

16voto

Juan Mendes Points 31678

La création d'une nouvelle balise script et la copie du contenu de la balise script existante, puis l'ajout de cette balise, fonctionnent bien.

var scriptTag = document.createElement('script');
scriptTag.innerText = "document.body.innerHTML += 'Here again ---<BR>';";
var head = document.getElementsByTagName('head')[0];
head.appendChild(scriptTag);

setInterval(function() {
    head.removeChild(scriptTag);
    var newScriptTag = document.createElement('script');
    newScriptTag.innerText = scriptTag.innerText;
    head.appendChild(newScriptTag);
    scriptTag = newScriptTag;    
}, 1000);

Cela ne fonctionnera pas si vous vous attendez à ce que le script change à chaque fois, ce qui, je pense, est votre cas. Vous devriez suivre la suggestion de Kelly, supprimer l'ancienne balise script (juste pour garder le DOM mince, cela n'affectera pas le résultat) et réinsérer une nouvelle balise script avec le même src, plus un cachebuster.

7voto

Maleenc Points 401

Petite modification de la réponse de Luke,

 function reloadJs(src) {
    src = $('script[src$="' + src + '"]').attr("src");
    $('script[src$="' + src + '"]').remove();
    $('<script/>').attr('src', src).appendTo('head');
}

et l'appeler comme,

reloadJs("myFile.js");

Il n'y aura pas de problèmes liés au chemin d'accès.

6voto

stomy Points 851

Cette fonction permet de trouver tous les éléments script contenant un certain mot et de les rafraîchir.

function forceReloadJS(srcUrlContains) {
  $.each($('script:empty[src*="' + srcUrlContains + '"]'), function(index, el) {
    var oldSrc = $(el).attr('src');
    var t = +new Date();
    var newSrc = oldSrc + '?' + t;

    console.log(oldSrc, ' to ', newSrc);

    $(el).remove();
    $('<script/>').attr('src', newSrc).appendTo('head');
  });
}

forceReloadJS('/libs/');

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

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