Продолжайте записывать элементы в iframe даже после его перенаправления на разные URL

0

Я знаю, как писать в iframe:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Writer</title>
    <style>
        textarea,
        iframe {
            display: block;
            width: 800px;
            height: 200px;
        }
    </style>
</head>

<body>
    <textarea id="ta" oninput="writeIt();"></textarea>
    <iframe id="frm"></iframe>
    <script>
        function writeIt() {
            var ta = document.getElementById('ta');
            var frm = document.getElementById('frm');
            var frmDoc = frm.contentDocument;
            frmDoc.open();
            frmDoc.write(ta.value);
            frmDoc.close();
        }
    </script>
</body>

</html>

DEMO

Однако есть проблема. В текстовое поле введите следующее:

<a href="http://www.example.com/">Example.com</a>

Теперь нажмите на ссылку, а затем вернитесь в текстовое поле, чтобы продолжить писать. Это больше не работает из-за ограничения кросс-происхождения. Есть ли способ в этом случае продолжить писать?

Примечание. Я нашел три похожих приложения, которые, похоже, работают по своему усмотрению. Интересно, как они работают по-другому от моей демонстрации и какие изменения мне необходимо внести в моем коде:

Вот код, который я пробовал на них:

<a href="https://googledrive.com/host/0B1iqp0kGPjWsVms5S3JzaUZJYVk/page-template.html" target="_self">Page Template</a>
  • 0
    Поскольку «запись» в iframe таким образом полностью заменяет текущий документ внутри iframe, вы можете также изменить его src обратно на документ из вашего собственного домена, прежде чем писать что-то новое для него. Или замените элемент iframe новым, пустым.
  • 0
    Это то, что вы имеете в виду: демо . Выдает ошибку в консоли и не начинает писать сразу.
Теги:
iframe

1 ответ

1
Лучший ответ

Есть несколько способов добиться этого. Или:

  1. Заставить все ссылки за пределами сайта открывать в новой вкладке/окне; или
  2. Восстановите iframe, установив его источник в локальный URL-адрес, если он больше не может быть записан.

Лучшее решение будет зависеть от ваших точных требований.

Обновление: написав и протестировав оба варианта, я думаю, что вариант 2 лучше, если у вас нет особых требований, которые делают вариант 1 лучше.

Опция 1

Сначала принимаем решение "целевое новое окно", просто сравниваем все ссылки с текущим доменом и, если они за пределами сайта, автоматически устанавливают цель ссылки в пустое окно.

См. Демонстрацию jsfiddle здесь

Javascript:

function setTargets() {
    var links = document.getElementById("frm").contentWindow.document.getElementsByTagName("a");
    var currentDomain = "http://" + document.location.hostname;
    for (var i = 0; i < links.length; i++) {
        if (links[i].href.indexOf(currentDomain) == -1) {
            links[i].target = "_blank";
        }
    }
}

HTML:

<textarea id="ta" onkeyup="writeIt();" onblur="setTargets();">Type here</textarea>

Вариант 2

Принимая подход "вернуть iframe" (лучше!), Вы просто завершите попытку записать iframe в try/catch.

См. Демонстрацию jsfiddle здесь

Javascript:

function writeIt() {
    var ta = document.getElementById('ta');
    var frm = document.getElementById('frm');
    try {
        var frmDoc = frm.contentDocument;
        frmDoc.open();
        frmDoc.write(ta.value);
        frmDoc.close();
    } 
    catch(err) {
        frm.src = "about:blank";
        setTimeout(writeIt,500);
    }
}

Если вы можете заменить "about: blank" на реальную пустую локальную страницу (например, blank.html), которая может сделать ее более совместимой с несколькими браузерами - я тестировал ее только в Chrome до сих пор.

  • 0
    Спасибо за ответ! Второй кажется хорошим. Могу ли я использовать событие onerror : demo ?
  • 0
    Да, использование window.onerror тоже работает хорошо. Я не думаю, что есть из чего выбирать - try / catch будет более специфичным для исходной проблемы, тогда как onerror может потенциально запускаться для других случаев ошибки (что может или не может быть хорошей вещью). Кажется довольно надежным в любом случае.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню