【问题标题】:Creating a new DOM node instead of re-rendering创建一个新的 DOM 节点而不是重新渲染
【发布时间】:2018-01-26 11:19:20
【问题描述】:

我正在使用一个 iframe 组件来加载通过 props 传递的跨域 url。通过 props 将 iframe 导航到新 url 会将新条目推送到 iframe 的历史记录中,这会劫持浏览器的“后退”按钮。这是跨域 iframe 的预期行为,只要它们的 src url 发生变化。

那么,是否有可能简单地创建一个新的 iframe 而不是更改 src?我的假设是,这会破坏 iframe 的任何内部状态,从而阻止新条目进入“后退”按钮的历史记录。

iframe 组件(改编自react-iframe):

// ETA: using React.Component instead of 
// PureComponent yields the same back button behavior
const Iframe = class extends PureComponent {
    render() {
        return React.createElement('iframe', {
            ref: 'iframe',
            frameBorder: '0',
            src: this.props.url,
            sandbox: this.props.sandbox,
            referrerpolicy: 'no-referrer',
            target: '_parent',
            allowFullScreen: this.props.allowFullScreen || false,
            style: Object.assign(
                {},
                {
                    position: this.props.position || 'absolute',
                    display: this.props.display || 'block',
                    height: this.props.height || '100%',
                    width: this.props.width || '100%'
                },
                this.props.styles || {}
            ),
            height: this.props.height || '100%',
            width: this.props.width || '100%'
        });
    }
};

ETA:我假设创建一个新的底层 iframe 将阻止进入历史记录 based on this answer,内容如下:

不要更改src,用新的iframe替换旧的iframe? 没有历史状态。相同的功能。每个人都赢了。

 <!doctype html>

 <style> iframe {
     width: 300px;
     height:300px; } </style>

 <script> var urls = ["http://bing.com", "http://google.com",
 "http://duckduckgo.com"];

 function next() {
     if(urls.length==0) return;
    var original = document.getElementsByTagName("iframe")[0];
     var newFrame = document.createElement("iframe");
     newFrame.src = urls.pop();
     var parent = original.parentNode;
     parent.replaceChild(newFrame, original); } </script>

 <p>let's test some iframes</p> <button onclick="next()">next</button>
 <iframe /> 

【问题讨论】:

    标签: javascript html reactjs iframe


    【解决方案1】:

    在这种情况下,您应该使用Component 而不是PureComponent,或者改为使用forceupdate 方法。

    PureComponent 实现了 shouldComponentUpdate() 与浅 prop 和状态比较,这导致您的组件不重新渲染。

    【讨论】:

    • 感谢@Dekel。我将其更改为Component,但后退按钮仍在导航 iframe 的历史记录,而不是父页面。我是否错误地认为创建一个新的底层 iframe 会阻止 iframe 的历史记录累积条目?
    • 我认为这与反应完全无关——这是浏览器使用 iframe 的方式。你没有用反应应用检查吗? :)
    • 我没有直接检查过,但我的假设基于这篇文章中的答案(我将添加到 OP):stackoverflow.com/questions/14737365/…
    • 恐怕答案会是“否”:(jsfiddle.net/h2rt2pwu 这里是一个例子,但是因为那里有多层 iframe - 这里是关于如何检查它的说明。1 . 点击下一步(你会得到duckduckgo)。 2. 搜索一些东西。 3. 点击“下一步”(你会得到绑定)。 4. 在“结果” iframe 内(绑定 iframe 外)单击鼠标. 在浏览器中点击“返回”——你会在 iframe 中返回duckduckgo。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-28
    • 2018-01-13
    • 1970-01-01
    • 2018-03-10
    相关资源
    最近更新 更多