Динамическая вставка JavaScript в HTML, использующий document.write.

StackOverflow https://stackoverflow.com/questions/53945

  •  09-06-2019
  •  | 
  •  

Вопрос

В настоящее время я загружаю всплывающее окно в стиле лайтбокса, которое загружает HTML из вызова XHR.Затем этот контент отображается в «модальном» всплывающем окне с помощью element.innerHTML = content Это работает как шарм.

В другом разделе этого сайта я использую «значок» Flickr (http://www.elliotswan.com/2006/08/06/custom-flickr-badge-api-documentation/) для динамической загрузки изображений Flickr.Это делается с помощью тега сценария, который загружает javascript flickr, который, в свою очередь, выполняет некоторые document.write заявления.

Оба они отлично работают, если включены в HTML.Только при загрузке кода значка flickr внутри лайтбокс, контент вообще не отображается.Кажется, что использование innerHTML написать document.write операторы заходят слишком далеко, но я не могу найти никакой подсказки в реализациях javascript (FF2&3, IE6&7) этого поведения.

Может ли кто-нибудь уточнить, должно или не должно это работать?Спасибо.

Это было полезно?

Решение

Как правило, теги скриптов не выполняются при использовании InnerHTML.В вашем случае это хорошо, потому что document.write вызов уничтожит все, что уже есть на странице.Однако это оставляет вас без того, что HTML document.write должен был добавить.

Методы манипулирования HTML jQuery будут выполнять за вас сценарии в HTML, затем весь фокус в том, чтобы перехватить вызовы document.write и получение HTML в нужном месте.Если это достаточно просто, то подойдет что-то вроде этого:

var content = '';
document.write = function(s) {
    content += s;
};
// execute the script
$('#foo').html(markupWithScriptInIt);
$('#foo .whereverTheDocumentWriteContentGoes').html(content);

Однако это становится сложнее.Если скрипт находится в другом домене, он будет загружен асинхронно, поэтому вам придется подождать, пока он завершится, чтобы получить контент.А что, если он просто запишет HTML-код в середину фрагмента без элемента-обертки, который можно легко выбрать? writeCapture.js (полное раскрытие:Я это написал) решает все эти проблемы.Я бы рекомендовал просто использовать его, но, по крайней мере, вы можете посмотреть код, чтобы увидеть, как он со всем справляется.

РЕДАКТИРОВАТЬ:Вот страница демонстрируя, как звучит желаемый эффект.

Другие советы

Я создал простую тестовую страницу, которая иллюстрирует проблему:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
        <title>Document Write Testcase</title>
    </head>
    <body>
        <div id="container">
        </div>
        <div id="container2">
        </div>

        <script>
            // This doesn't work!
            var container = document.getElementById('container');
            container.innerHTML = "<script type='text/javascript'>alert('foo');document.write('bar');<\/script>";

            // This does!
            var container2 = document.getElementById('container2');
            var script = document.createElement("script");
            script.type = 'text/javascript';
            script.innerHTML = "alert('bar');document.write('foo');";
            container.appendChild(script);
        </script>
    </body>
</html>

Эта страница выдает предупреждение «bar» и печатает «foo», хотя я ожидал, что она также выдаст предупреждение «foo» и напечатает «bar».Но, к сожалению, поскольку script является частью более крупной HTML-страницы, я не могу выделить этот тег и добавить его, как в примере выше.Ну, я могу, но для этого потребуется сканирование. innerHTML контент для script теги и заменяя их в строке заполнителями, а затем вставляя их с помощью DOM.Звучит не что тривиально.

Использовать document.writeln(content); вместо document.write(content).

Однако лучший метод — использовать конкатенацию innerHTML, так:

element.innerHTML += content;

А element.innerHTML = content; метод, который заменит старое содержимое новым, он перезапишет InnerHTML вашего элемента!

В то время как += оператор в element.innerHTML += content; добавит ваш текст после старого контента.(как что document.write делает.)

document.write примерно так же устарели, как и они.Однако благодаря чудесам JavaScript вы можете просто назначить свою собственную функцию write метод document объект, который использует innerHTML к элементу по вашему выбору, чтобы добавить предоставленный контент.

Могу ли я сначала получить некоторые разъяснения, чтобы убедиться, что я понял проблему?

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

Поэтому для того чтобы это работало вообще Flickr document.write заявления должны быть частью content в element.innerHTML = content.Это определенно так?

Вы можете быстро проверить, должно ли это вообще работать, добавив один простой document.write вызвать содержимое, которое установлено как innerHTML и посмотрите, что это делает:

<script>
  var content = "<p>1st para</p><script>document.write('<p>2nd para</p>');</script>"
  element.innerHTML = content;
</script>

Если это сработает, концепция document.write работа с контентом, установленным как innerHTML элемента может просто сработать.

Я нутром чувствую, что это не сработает, но протестировать эту концепцию должно быть довольно просто.

Итак, вы используете метод DOM для создания script элемент и добавьте его к существующему элементу, а затем это приведет к тому, что содержимое добавленного элемента script элемент для выполнения?Это звучит неплохо.

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

Теоретически да, я могу таким образом выделить тег сценария.Проблема в том, что потенциально у нас есть десятки ситуаций, когда это происходит, поэтому я пытаюсь найти какую-то причину или документацию такого поведения.

Так же script Тег больше не является частью DOM после загрузки.В нашей среде мой container div остается пустым, поэтому я не могу получить script ярлык.Однако это должно сработать, потому что в моем примере выше скрипт не выполняется, но все еще является частью DOM.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top