Javascript 即使在iframe重定向到不同的url之后,也要继续将元素写入iframe

Javascript 即使在iframe重定向到不同的url之后,也要继续将元素写入iframe,javascript,html,iframe,Javascript,Html,Iframe,我知道如何在iframe中写入: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Writer</title> <style> textarea, iframe { display: block; width: 800

我知道如何在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>

作家
文本区,
iframe{
显示:块;
宽度:800px;
高度:200px;
}
函数writeIt(){
var ta=document.getElementById('ta');
var frm=document.getElementById('frm');
var frmDoc=frm.contentDocument;
frmDoc.open();
frmDoc.写入(ta.值);
frmDoc.close();
}

不过有个问题。在文本区域中输入以下内容:

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

现在点击链接,然后返回文本区继续写作。由于交叉来源限制,它不再工作。在这种情况下,有没有办法继续写作

注意:我发现了三个类似的应用程序,它们的功能似乎与我所希望的一样。我想知道它们与我的演示有什么不同,我需要在代码中做哪些更改:

下面是我在他们身上试过的代码:

<a href="https://googledrive.com/host/0B1iqp0kGPjWsVms5S3JzaUZJYVk/page-template.html" target="_self">Page Template</a>

有几种方法可以实现这一点。要么:

  • 强制在新选项卡/窗口中打开所有场外链接;或
  • 如果无法再写入iframe,则通过将其源设置为本地URL来回收iframe 最佳解决方案将取决于您的确切要求

    更新:在编写和测试了这两个选项之后,我认为选项2是最好的,除非您有非常具体的要求使选项1更好

    选项1

    首先采用“目标新窗口”解决方案,只需将所有链接与当前域进行比较,如果它们不在现场,则自动将链接目标设置为空白窗口

    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";
            }
        }
    }
    
    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);
        }
    }
    

    如果你可以用一个真正的空白本地页面(例如blank.html)来替换“about:blank”,这可能会使它更兼容跨浏览器-到目前为止,我只在Chrome中测试过它。

    因为以这种方式“写入”iframe会完全替换iframe中的当前文档,在编写任何新文档之前,您还可以将其
    src
    从自己的域更改回文档。或者将iframe元素替换为新的空元素。这就是您的意思:。它在控制台中出现错误,不会立即开始写入。谢谢您的回答!第二个看起来不错。我可以使用
    onerror
    event:?是的,使用window.onerror似乎也能很好地工作。我不认为它们之间有太多的选择——try/catch将更具体地针对原始问题,而onerror可能会触发其他错误情况(这可能是一件好事,也可能不是一件好事)。请再问一个问题:在大多数资料中,我看到的是
    catch(e)
    ,而不是
    catch(err)
    。这有区别吗?有什么规格吗?没有区别。它只是存储错误的变量,因此如果需要,可以执行警报(err.message)。如果你有兴趣,这里有一个很好的总结。我刚刚通过模拟器在Safari 7中试用了它,它似乎在控制台中抛出了一个错误,尽管它可以正常工作:iframe重定向到Example.com,然后在您开始键入时返回原始来源。这似乎是野生动物园里的一只虫子。
    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);
        }
    }