Як змусити сценарій перезавантажити та повторно виконати?


78

У мене є сторінка, яка завантажує сценарій від третьої сторони (стрічка новин). srcURL для сценарію призначаються динамічно навантаження до (за код третьої сторони).

<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 не перезавантажується до нього.

Будь-яка ідея, що я роблю не так?


Не знаю, чи зрозумів браузер, що ви хочете, щоб він знову завантажив js, оскільки ви намагаєтеся завантажувати одну і ту ж URL-адресу знову і знову. це, мабуть, сприймає як те саме і не турбує. спробуйте техніку кешування при зміні src:scrElement.src='http://oneBigHairyURL?v=2'; //auto-increment this value
Matt K

@Matt K. Так, я повинен був написати, що я спробував це, але безрезультатно. На жаль, це не було частиною оригінального допису.
Джонатан М

@JonathanM Я застряг у тому ж, ти знайшов рішення? Додавання версії не працює.
Парт

1
@ Dr..Net, обрана відповідь спрацювала для мене.
Джонатан М

@JonathanM, що, створюючи новий тег сценарію, він працює. Як щодо завантаження того самого тегу, але просто змінити значення атрибута 'src'?
Парт

Відповіді:


74

Як щодо того, щоб додати новий тег сценарію до <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>

Головне - вставити новий тег сценарію - ви можете видалити старий без наслідків. Можливо, вам доведеться додати мітку часу до рядка запиту, якщо у вас є проблеми з кешуванням.


22
Для проблем з кешем найкраще додати мітку часу до URL-адреси'hello.js?cachebuster='+ new Date().getTime()
Хуан Мендес,

@Juan Mendes, це правильно, оскільки стрічку новин потрібно завантажувати знову. Пропустіть це лише тоді, коли потрібен кеш, на випадок, якщо потрібно лише повторне повторне завантаження, а нове несекаторне завантаження буде сповільненням, наприклад сценарій, який не змінюється.

41

Ось метод, подібний до методу Келлі, але видаляє будь-який вже існуючий сценарій з тим самим джерелом і використовує jQuery.

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

Зверніть увагу, що атрибут 'type' більше не потрібен для сценаріїв, починаючи з HTML5. ( http://www.w3.org/html/wg/drafts/html/master/scripting-1.html#the-script-element )


1
Чудово !! Це мені дуже допомагає після довгих пошуків. Дякую.
Мд. Салагуддін,

3
Ви можете додати новий JS, але не можете позбутися старого. Будь-які слухачі тощо з оригінального сценарію залишатимуться активними, навіть якщо ви видалите його тег сценарію.
user984003

9

Ви пробували видалити його з 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);

Це не спрацює, якщо ви очікуєте, що сценарій буде змінюватися щоразу, що, на мою думку, є вашим випадком. Ви повинні слідувати пропозиціям Келлі, просто видаліть старий тег сценарію (лише для того, щоб зберегти DOM в тонкості, це не вплине на результат) і вставте новий тег сценарію з тим самим src, а також кеш-бастером.


4

Невеликий підхід до відповіді Луки,

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

і називати це як,

reloadJs("myFile.js");

Це не матиме жодних проблем, пов’язаних із шляхом.


1
Чи не слід .appendTo('head')замість тіла?
Джонатан М

@JonathanM Ми зазвичай тримаємо наш сценарій у кінці тексту. Коли я публікував це, це працювало для мене. Я думаю, ви також можете додати голову, якщо це потрібно.
Maleen Abewardana

1
Це один

3

Використовуйте цю функцію, щоб знайти всі елементи сценарію, що містять якесь слово, та оновити їх.

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

Я знаю, що пізно, але хочу поділитися своєю відповіддю. Те, що я зробив, це збереження тегів de script у файлі HTML, блокування скриптів у моєму файлі Index у div з ідентифікатором, приблизно так.

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

і коли я хотів освіжити, я просто використовував.

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

  });
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.