web-dev-qa-db-fra.com

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

J'ai une page qui charge un script d'un tiers (flux de nouvelles). L'URL src du script est attribué dynamiquement lors du chargement (par code 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 divers éléments du fil d'actualité, avec une jolie mise en forme, etc. dans div1287 (l'identifiant "div1287" est passé dans http://oneBigHairyURL afin que le script sache où charger le contenu).

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

Alors, j'ai pensé 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 est effacée, mais aucun code HTML généré dynamiquement n'est rechargé.

Une idée de ce que je fais mal?

53
Jonathan M

Pourquoi ne pas ajouter une nouvelle balise de 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 de script - vous pouvez supprimer l'ancienne sans conséquence. Vous devrez peut-être ajouter un horodatage à la chaîne de requête en cas de problème de mise en cache.

54
Kelly

Voici une méthode similaire à celle de Kelly, mais qui supprime tout script préexistant avec le même source et 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-element )

31
Luke

Avez-vous essayé de le supprimer du DOM, puis de le réinsérer?

Je viens de le faire, ça ne marche pas. Cependant, créer une nouvelle balise de script et copier le contenu de la balise de script existante, puis l'ajouter, fonctionne bien. 

Voir mon exemple http://jsfiddle.net/mendesjuan/LPFYB/

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, à mon avis, est votre cas. Vous devez suivre la suggestion de Kelly: il suffit de supprimer l'ancienne balise de script (pour que le DOM reste mince, cela n'affectera pas le résultat) et de réinsérer une nouvelle balise de script avec le même code src et un cachebuster.

6
Juan Mendes

Petit Tweak à la réponse de Luke,

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

et appelez comme, 

relaodJs("myFile.js");

Cela n'aura aucun problème lié au chemin.

2
Maleen Abewardana

Utilisez cette fonction pour rechercher tous les éléments de script contenant du Word et les actualiser.

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>

0
stomy