Wie erzwinge ich das Neuladen und erneute Ausführen eines Skripts?

78

Ich habe eine Seite, die ein Skript von einem Drittanbieter lädt (Newsfeed). Die srcURL für das Skript wird beim Laden dynamisch zugewiesen (pro Code eines Drittanbieters).

<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>

Das von dort geladene Skript http://oneBigHairyURLerstellt und lädt Elemente mit den verschiedenen Inhalten aus dem div1287Newsfeed , mit hübscher Formatierung usw. in (die ID "div1287" wird übergeben, http://oneBigHairyURLdamit das Skript weiß, wo der Inhalt geladen werden soll).

Das einzige Problem ist, dass es nur einmal geladen wird. Ich möchte, dass es alle n Sekunden neu geladen wird (und somit neue Inhalte anzeigt).

Also dachte ich, ich würde es versuchen:

<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>

Ich erhalte die Warnung, das div wird gelöscht, aber es wird kein dynamisch generiertes HTML erneut geladen.

Irgendeine Idee, was ich falsch mache?

Jonathan M.
quelle
Ich weiß nicht, ob der Browser versteht, dass er die js erneut herunterladen soll, da Sie immer wieder versuchen, dieselbe URL zu laden. es sieht es wahrscheinlich genauso und stört nicht. Versuchen Sie eine Caching-Technik, wenn Sie die src ändern:scrElement.src='http://oneBigHairyURL?v=2'; //auto-increment this value
Matt K
@ Matt K. Ja, ich hätte posten sollen, dass ich das versucht habe, aber ohne Erfolg. Entschuldigung, es war nicht Teil des ursprünglichen Beitrags.
Jonathan M
@ JonathanM Ich stecke bei der gleichen Sache fest, hast du eine Lösung gefunden? Das Hinzufügen einer Version funktioniert nicht.
Parth
1
@ Dr..Net, die ausgewählte Antwort hat bei mir funktioniert.
Jonathan M
@ JonathanM, dass es durch das Generieren eines neuen Skript-Tags funktioniert. Wie wäre es, wenn Sie dasselbe Tag laden, aber nur den Wert des Attributs 'src' ändern?
Parth

Antworten:

73

Wie wäre es mit dem Hinzufügen eines neuen Skript-Tags zu <head> mit dem Skript zum (erneuten) Laden? So etwas wie unten:

<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>

Der Hauptpunkt ist das Einfügen eines neuen Skript-Tags - Sie können das alte ohne Konsequenz entfernen. Möglicherweise müssen Sie der Abfragezeichenfolge einen Zeitstempel hinzufügen, wenn Caching-Probleme auftreten.

Kelly
quelle
22
Bei Cache-Problemen ist es am besten, der URL einen Zeitstempel hinzuzufügen'hello.js?cachebuster='+ new Date().getTime()
Juan Mendes
@ Juan Mendes, das ist richtig, weil ein Newsfeed erneut geladen werden muss. Überspringen Sie es nur, wenn der Cache gewünscht wird, falls nur eine erneute Ausführung erforderlich ist und ein neues unnötiges Laden eine Verlangsamung darstellt, z. B. ein Skript, das sich nicht ändert.
41

Hier ist eine Methode, die der von Kelly ähnelt, jedoch alle bereits vorhandenen Skripte mit derselben Quelle entfernt und jQuery verwendet.

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

Beachten Sie, dass das Attribut 'type' ab HTML5 für Skripte nicht mehr benötigt wird. ( http://www.w3.org/html/wg/drafts/html/master/scripting-1.html#the-script-element )

Luke
quelle
1
Toll!! Es hilft mir sehr nach vielem Suchen. Vielen Dank.
Md. Salahuddin
2
Sie können neues JS hinzufügen, aber das alte nicht entfernen. Alle Listener usw. aus dem ursprünglichen Skript bleiben auch dann aktiv, wenn Sie das Skript-Tag entfernen.
user984003
9

Haben Sie versucht, es aus dem DOM zu entfernen und dann wieder einzufügen?

Ich habe es einfach getan, das funktioniert nicht. Das Erstellen eines neuen Skript-Tags und das Kopieren des Inhalts des vorhandenen Skript-Tags und das anschließende Hinzufügen funktionieren jedoch gut.

Siehe mein Beispiel 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);

Dies funktioniert nicht, wenn Sie erwarten, dass sich das Skript jedes Mal ändert, was meiner Meinung nach Ihr Fall ist. Sie sollten Kellys Vorschlag folgen, einfach das alte Skript-Tag entfernen (nur um das DOM schlank zu halten, es hat keinen Einfluss auf das Ergebnis) und ein neues Skript-Tag mit demselben src sowie einem Cachebuster erneut einfügen.

Juan Mendes
quelle
4

Kleine Änderung an Lukes Antwort,

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

und nenne es wie,

reloadJs("myFile.js");

Dies hat keine pfadbezogenen Probleme.

Maleen Abewardana
quelle
1
Sollte es nicht .appendTo('head')anstelle des Körpers sein?
Jonathan M
@ JonathanM Normalerweise behalten wir unser Skript am Ende des Körpers. Als ich das gepostet habe, hat das bei mir funktioniert. Ich denke, Sie können bei Bedarf auch an den Kopf anhängen.
Maleen Abewardana
1
Dies ist der eine
2

Verwenden Sie diese Funktion, um alle Skriptelemente zu finden, die ein Wort enthalten, und sie zu aktualisieren.

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>

Stomie
quelle
0

Ich weiß, dass das zu spät ist, aber ich möchte meine Antwort teilen. Ich habe die Tags des Skripts in einer HTML-Datei gespeichert und die Skripte in meiner Indexdatei in einem Div mit einer ID gesperrt.

<div id="ScriptsReload"><script src="js/script.js"></script></div>

und als ich mich erfrischen wollte habe ich gerade benutzt.

$("#ScriptsReload").load("html_with_scripts_tags.html", "", function(
    response,
    status,
    request
  ) {

  });
Andres Hilario Vidal
quelle