视频播放器在响应式响应Web应用程序中调整窗口大小后重置?

时间:2018-03-18 17:49:30

标签: reactjs responsive-design antd

在我的自适应网络应用中调整窗口大小后,我无法让视频播放器继续播放。我正在使用响应式响应库来帮助解决这个问题。我有一个不同的MediaQuery元素处理我的外部“内容”组件中的每个窗口大小范围,它使用antd布局组件处理整个页面布局,所以我猜测正在发生的是组件的不同部分显示每个范围,每次检测到新范围时,视频也会“重置”。 (当我删除媒体查询时,问题就消失了。)

如何制作视频播放器当前正在播放视频(这是一个呈现api资源的iframe)时,它会继续通过窗口调整大小到另一个范围?我猜我可以改变媒体查询范围并以某种特定的方式嵌套它们,但我无法弄清楚如何做到这一点。

内容组件中的页面布局:

const Inside = props => (
  <Layout.Content
    style={{
      background: '#fff',
      padding: '10px 10px',
      width: props.width,
      margin: '0 auto 50px',
    }}
  >
    <main>
      <Route exact path="/" component={Home} />
      <Route path="/quicklooks" component={Quicklooks} />
      <Route path="/features" component={Features} />
      <Route path="/bombcasts" component={Bombcasts} />
    </main>
  </Layout.Content>
);

const Content = () => (
  <div>
    <XS><Inside width="100%" /></XS>
    <SM><Inside width="100%" /></SM>
    <MD><Inside width="740px" /></MD>
    <LG><Inside width="940px" /></LG>
    <XL><Inside width="1160px" /></XL>
    <XXL><Inside width="1160px" /></XXL>
  </div>
);

视频播放器:

const CurrentVideo = (props) => {
  const pubDateFormatted = Moment(props.pub_date).format('MMM. D, YYYY h:mma');

  return (
    <div style={{ background: '#000', margin: '0 auto', width: '100%' }}>
      <Row type="flex" justify="center">
        <Col xs={24} lg={8}>
          <div style={{ padding: '16px', color: '#fff' }}>
            <h2 style={{ color: '#fff' }}>{props.name}</h2>
            <p><i> Posted by {props.user} | {pubDateFormatted}</i></p>
            <p>{props.deck}</p>
          </div>
        </Col>
        <Col xs={24} lg={16} >
          <div className="intrinsic-container intrinsic-container-16x9">
            <iframe
              frameBorder={0}
              allowFullScreen
              title={props.name}
              src={props.embed_player}
            />
          </div>
        </Col>
      </Row>
    </div>
  );
};

CurrentVideo.propTypes = {
  name: PropTypes.string.isRequired,
  user: PropTypes.string.isRequired,
  pub_date: PropTypes.string.isRequired,
  deck: PropTypes.string.isRequired,
  embed_player: PropTypes.string.isRequired,
};

export default CurrentVideo;

设置为特定窗口宽度的不同媒体查询:

export const XXL = props => (
  <Responsive minWidth={1600}>
    {props.children}
  </Responsive>
);

export const XL = props => (
  <Responsive minWidth={1200} maxWidth={1599}>
    {props.children}
  </Responsive>
);

export const LG = props => (
  <Responsive minWidth={992} maxWidth={1199}>
    {props.children}
  </Responsive>
);
export const MD = props => (
  <Responsive minWidth={768} maxWidth={991}>
    {props.children}
  </Responsive>
);

export const SM = props => (
  <Responsive minWidth={576} maxWidth={767}>
    {props.children}
  </Responsive>
);

export const XS = props => (
  <Responsive maxWidth={575}>
    {props.children}
  </Responsive>
);

2 个答案:

答案 0 :(得分:2)

你应该看一下React rules for reconciliation。他们说:“只要根元素有不同的类型,React就会拆掉旧树并从头开始构建新树。”

看起来这里发生的事情是,当屏幕尺寸发生变化时,会创建一个具有不同类型的新组件,最终导致CurrentVideo被拆除并替换。

不要在这里使用反应敏感。使用React设置dom元素,然后使用normal CSS media queries根据窗口大小更改显示。

如果您真的坚持使用响应式响应,可以尝试在iframe中呈现Inside,并传递ref参数以允许您存储对dom元素的引用(查看Refs and the DOM),然后将该引用传递给CurrentVideo

答案 1 :(得分:0)

如果不深入研究您的实现,我的猜测是响应敏感会导致CurrentVideo组件重新渲染。

缓解这种情况的一种可能方法是使用shouldComponentUpdate()方法来阻止重新渲染,然后检查组件的道具或状态是否实际上已经发生了足够的变化,以便需要重新渲染。有关生命周期方法的更多信息以及React Docs

中具体的shouldComponentUpdate()