web-dev-qa-db-ja.com

スクリプトを強制的にリロードして再実行する方法は?

サードパーティ(ニュースフィード)からスクリプトを読み込んでいるページがあります。スクリプトのsrc URLは、ロード時に動的に割り当てられます(サードパーティコードごと)。

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

http://oneBigHairyURLから読み込まれたスクリプトは、ニュースフィードのさまざまな要素、きれいなフォーマットなどを含む要素を作成してdiv1287に読み込みます(ID「div1287」はhttp://oneBigHairyURLに渡されます。スクリプトはコンテンツをロードする場所を認識しています)。

唯一の問題は、一度しかロードしないことです。 n秒ごとにリロード(したがって新しいコンテンツを表示)したいです。

だから、私はこれを試してみると思った:

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

私はアラートを受け取り、divはクリアしますが、動的に生成されたHTMLはリロードされません。

私が間違っていることを知っていますか?

59
Jonathan M

(再)ロードするスクリプトを使用して、新しいスクリプトタグを<head>に追加してみませんか?以下のようなもの:

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

主なポイントは、新しいスクリプトタグを挿入することです。古いタグは結果なしで削除できます。キャッシュの問題がある場合は、クエリ文字列にタイムスタンプを追加する必要があります。

60
Kelly

Kellyのメソッドに似ていますが、同じソースの既存のスクリプトを削除し、jQueryを使用するメソッドを次に示します。

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

HTML5以降、スクリプトには「type」属性が不要になっていることに注意してください。 ( http://www.w3.org/html/wg/drafts/html/master/scripting-1.html#the-script-element

35
Luke

DOMから削除して、もう一度挿入してみましたか?

私はちょうどやった、それは動作しません。ただし、新しいスクリプトタグを作成し、既存のスクリプトタグの内容をコピーしてから追加すると、うまく機能します。

私の例を参照してください 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);

スクリプトが毎回変更されると予想される場合、これは機能しません。 Kellyの提案に従い、古いスクリプトタグを削除するだけで(DOMをスリムに保つため、結果に影響しません)、同じsrcとキャッシュ無効化を使用して新しいスクリプトタグを再挿入する必要があります。

7
Juan Mendes

ルークの答えを微調整し、

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

そしてそれを

reloadJs("myFile.js");

これにはパス関連の問題はありません。

3

この関数を使用して、Wordを含むすべてのスクリプト要素を検索し、更新します。

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