Предупреждение: вызов document.write () из асинхронно загруженного внешнего скрипта был проигнорирован. Как это исправить? - PullRequest
4 голосов
/ 18 октября 2011

В моем приложении Ruby on Rails я использую плагин Facebox для всплывающего окна Ajax.У меня есть 2 страницы, которые называются add_retail_stores/new.html.erb и add_retail_stores/new.js.Страница new.js наследует все элементы страницы new.html.erb, поэтому она выглядит точно так же.У меня есть скрипт карты Google на странице HTML, который работает как надо.Но страница new.js, которая появляется на моей другой странице под названием add_store_prices.html.erb page (<%= link_to add_retail_store_path, :remote => true %>)

Я получаю сообщение об ошибке:

Предупреждение: вызов документа.write () из асинхронно загруженного внешнего скрипта был проигнорирован.Исходный файл: http://localhost:3000/add_store_prices Строка: 0

Я считаю, потому что он пытается пройти через 2 функции / скрипты.Первый для Facebox, а затем сценарий Google.Кто-нибудь знает, как обработать эту ошибку?

РЕДАКТИРОВАТЬ:

Я считаю, что плагин Facebox использует document.write, но я не уверен, где, возможно, в одной из этих 2 строк на моей странице?

new.js:

$.facebox('<%= escape_javascript(render :template => 'business_retail_stores/new.html') %>')
$('#facebox form').data('remote','true');

Ответы [ 3 ]

11 голосов
/ 18 октября 2011

Не используйте document.write.Скрипт загружается асинхронно, что означает, что он отключен от состояния анализа документа.Для движка JS буквально НЕТ СПОСОБА знать, ГДЕ должен быть выполнен document.write на странице.

Внешний скрипт может загружаться мгновенно, и document.write выполняется там, где находится тег <script src="...">, или он может попасть в net.burp и загрузить через час, что означает, что document.write будет помечен вконец страницы.Это буквально условие гонки, поэтому движки JS будут игнорировать document.writes из сценариев, загружаемых асинхронно.

Преобразование document.write для использования обычных операций DOM, защищенных обработчиком типа document.onload.

3 голосов
/ 18 октября 2011

Если у вас есть доступ к рассматриваемому файлу .js, лучшим решением будет изменение метода «document.write ()» и его замена на все, что имеет смысл, для распространения содержимого, содержащегося внутри. 1001 *

Причины этого очень хорошо описаны выше.

Если вы используете document.write для записи HTML-тегов на страницу:

document.write("<script src=...></script>");

или

document.write("<img href=... />");

Подумайте об использовании того же вида асинхронного формата, который вы уже использовали:

// Add/Remove/Sugar these components to taste
script = document.createElement("script");
script.onload = function () { namespaced.func.init(); };    
script.src = "http://...";
document.getElementsByTagName("script")[0].parentNode.appendChild(script);

Если вы хотите добавить элементы DOM, чтобы пользователь мог видеть их и взаимодействовать с ними, то вам лучше либо:

a) Получение определенного контейнера (section / div) по id и добавление вашего контента:

document.getElementById("price").innerHTML = "<span>$39.95</span>";

b) Создание содержимого вне DOM и внедрение его в ваш контейнер:

var frag = document.createDocumentFragment(),
    span = document.createElement("span");
span.innerText = "39.95";
frag.appendChild(span);
document.getElementById("price").appendChild(frag);

Опять же, сахар по вкусу.

Если у вас нет доступа к модулю этого второго файла .js, я бы посоветовал взять его с собой.

1 голос
/ 23 октября 2014

У меня была такая же проблема при загрузке карт Google с библиотекой мест. Я временно перезаписываю функцию записи, чтобы создать новый элемент скрипта в голове.

(function() {
  var docWrite = document.write;
  document.write = function(text) {
    var res = /^<script[^>]*src="([^"]*)"[^>]*><\/script>$/.exec(text);
    if (res) {
      console.log("Adding script " + res[1]);
      var head = document.getElementsByTagName('head')[0];
      var script = document.createElement("script");
      script.src = res[1];
      head.appendChild(script);
    } else {
      docWrite(text);
    }
  }
})();

Теперь все, что мне нужно сделать для асинхронной загрузки скрипта, это

document.write('<script src="http://maps.googleapis.com/maps/api/js?libraries=places"></script>');
...