проблемы с iframe: - PullRequest
       3

проблемы с iframe:

0 голосов
/ 02 июня 2018

У меня есть несколько проблем с использованием iframe.Я буду задавать один вопрос за раз.Я работаю на площадке LaTeX.js и хотел добавить JavaScript для обработки \marginpar s, но что бы я ни делал, ни Chrome, ни Firefox даже не пытаются загрузить скрипт.Это работает, если точно такой же код используется вне каких-либо кадров.

Я пробовал как абсолютные, так и относительные пути, и я пробовал file, http и https протоколы.Всегда один и тот же результат.

Вот соответствующий код:

<iframe id="preview" sandbox="allow-same-origin allow-scripts">
  <html>
    <head>
      <title>LaTeX.js Show&shy;case</title>
      <meta charset="UTF-8">
      <link type="text/css" rel="stylesheet" href="css/katex.css">
      <link type="text/css" rel="stylesheet" href="css/article.css">
      <link type="text/css" rel="stylesheet" href="css/error.css">

      <script src="https://latex.js.org/js/base.js"></script>
    </head>
    ...

Проблема base.js.Инструменты разработчика не показывают никаких ошибок в консоли, никаких записей на вкладке источников и никаких записей на вкладке сети.

ОБНОВЛЕНИЕ: как я уже говорил в комментариях, приведенный выше код является результатом модификации DOMиспользуя JavaScript;однако установка iframe.contentWindow.document.documentElement, похоже, не вызывает загрузку сценариев в <head>, у меня работает только вариант 2 в ответе.

1 Ответ

0 голосов
/ 02 июня 2018

Вариант 1: использование DOM

Для меня iframe.contentWindow.replaceChild(newDocumentElement, iframe.contentWindow.documentElement) не сработало (replaceChild не было методом, а iframe.contentWindow.documentElement.parentNode равно нулю).Мне удалось заменить голову и тело iframe:

var iframe = document.getElementById('preview');
var iframeDocument = iframe.contentDocument;
var head = document.createElement('head');
var body = document.createElement('body');
var library = document.createElement('script');

//library.src = 'https://latex.js.org/js/base.js';
library.src = 'https://d3js.org/d3.v4.min.js';
head.appendChild(library);
body.appendChild(document.createTextNode('Hello, World!'));
iframeDocument.head.parentNode.replaceChild(head, iframeDocument.head);
iframeDocument.body.parentNode.replaceChild(body, iframeDocument.body);

Вот скрипка: https://jsfiddle.net/zkb91faf/

Чтобы убедиться, что d3.v4.min.js загружен правильно, перейдите в iframe вотладчик (см. здесь для Chrome и здесь для Firefox ) и введите d3 в консоли.

Вариант 2: Использование src / srcdoc

Я был бы упущен, если бы не упомянул iframe.srcdoc.Похоже, вы просто используете статический HTML, поэтому это может быть уместно.

Вы просто установите его с помощью чего-то вроде:

iframe.srcdoc = newDocumentElement.outerHTML;

В качестве альтернативы,если вы хотите поддерживать старые браузеры, вы можете установить его через iframe.src и URI данных:

iframe.src = 'data:text;base64,' + btoa(newDocumentElement.outerHTML);

Если вам нужна поддержка юникода, обратитесь к https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding

Примечание Использование относительных URL-адресов:

Вероятно, вы столкнетесь с проблемами при использовании относительных URL-адресов, например, в <link type="text/css" rel="stylesheet" href="css/article.css">, потому что у вашего iframe не будет правильного URI.Вы, вероятно, должны использовать абсолютные URL-адреса.

Обновление: добавление тегов скрипта после загрузки документа:

Похоже, виновник находится в base.js, , где вы присоединяете и запускаете код, основанный на событии DOMContentLoaded.DOM уже загружен, поэтому это событие не сработает.Что вы можете сделать, это проверить, загружено ли уже окно, и затем запустить код инициализации, если он есть.Через https://stackoverflow.com/a/9457996/6184972:

if (document.readyState === "complete" || document.readyState === "loaded") {
     completed();
}

В этом случае вам может понадобиться заменить тело перед головой, на случай, если completed() выполнит какие-либо прямые манипуляции с DOM.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...