簡體   English   中英

react - 確保在 iframe 渲染之前加載 css

[英]react - ensure css loaded before iframe renders

處理一閃而過的無樣式內容問題。 我有一個注入用戶頁面的聊天小部件。 這樣我就不會與現有的樣式發生沖突。 我正在使用react-frame-component在 iframe 中渲染。 這很好用,但我遇到的一個問題是 CSS。

react-frame-component接受一個 prop head ,您可以使用它來將鏈接傳遞到樣式表。 使用 MiniCSSExtractPlugin,我可以將我的 css 放入一個單獨的文件中,然后我可以鏈接到:

render(props, state) {
  return (
    <Frame 
      head={<link rel="stylesheet" type="text/css" href="style.css" />}
      scrolling="no"
    >
      <ChatWidget />
    </Frame>
  );
}

有了這個,我得到了可怕的無樣式內容的閃光。 我認為這是因為包括<ChatWidget>在內的所有內容都在 css 可以完全下載之前呈現。

有沒有辦法可以確保在一切呈現之前下載 CSS?

另外,不確定它是否重要,但我正在使用 Preact。

我最終編寫了我自己的 iframe 組件,使用了react-frame-component一些技巧,但以一種我可以確定我可以控制它的呈現方式的方式編寫它。 這是我的 iframe 組件的樣子(注意這里使用的是 Preact,它與 React 有一些細微的差別——在 React 中復制它會很容易):

import {h, Component, createRef} from 'preact';
import {createPortal} from 'preact/compat';
import {cssLink} from '../utilities';

export default class Frame extends Component {
  iframeNode = createRef();
  iframeTest = document.createElement('iframe');

  static initialContent() {
    return `<!DOCTYPE html><head><link rel="stylesheet" type="text/css" href="${cssLink}"></head><body></body></html>`;
  }

  componentDidMount() {
    this.iframeNode.addEventListener('load', this.handleLoad);
  }

  handleLoad = () => {
    this.iframeRoot = this.iframeNode.contentDocument.body;
    this.forceUpdate();
  };

  sourceProp() {
    const canUseSrcDoc = 'srcdoc' in this.iframeTest;

    if (canUseSrcDoc) {
      return {
        srcdoc: Frame.initialContent(),
      };
    }

    // inserting Frame.initialContent() as the src is a hack for older browsers
    // to allow inserting our stylesheet before the children render, preventing
    // flashes of unstyled content
    return {
      src: `javascript: '${Frame.initialContent()}'`,
    };
  }

  render(props) {
    const {children, ...rest} = props;

    return (
      <iframe
        {...rest}
        {...this.sourceProp()}
        ref={ref => (this.iframeNode = ref)}
      >
        {this.iframeRoot && createPortal(children, this.iframeRoot)}
      </iframe>
    );
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM