React + Picturefill 推荐使用方式

Recommended way of using React + Picturefill

我想使用 Picturefill + React + React Router(同时使用 Webpack)。


上下文:尚无同构架构,因此在初始页面加载(路由更改)后获取数据。

…因此渲染方法被调用了两次。

  1. 默认状态一次
  2. 更新状态一次(获取数据)

代码

render: function () {
    return (
        <picture>
            <!-- You get the idea -->

            <source srcSet={this.props.large} media="(min-width: 1024px)" />
            <source srcSet={this.props.medium} media="(min-width: 640px)" />
            <img srcSet={this.props.small} />
        </picture>
    );
}

示例 1:

<head>
    <!-- Recommended usage -->
    <script src="https://cdn.rawgit.com/scottjehl/picturefill/2.3.1/dist/picturefill.js"></script>
</head>

示例 2:

// Use picturefill JavaScript API
componentDidUpdate() {
    picturefill();
}

更多info/Alternatives?

此解决方案与 Webpack 一起使用,并实现与上面 示例 1 中的推荐用法 相同的功能。

似乎 picturefill() 将在第一次渲染期间初始化(未定义 src),然后在第二次渲染期间跳过(已定义 src)。

所以…阻止图片元素的渲染,直到你有数据,似乎工作。

componentDidUpdate: function () {
    picturefill();
},

render: function () {
    return (
        <div>
            {(function () {
                // You get the idea…
                if (this.props.large === undefined) {
                    return '';
                }

                return (
                    <picture>
                        <!-- You get the idea… -->

                        <source srcSet={this.props.large} media="(min-width: 1024px)" />
                        <source srcSet={this.props.medium} media="(min-width: 640px)" />
                        <img srcSet={this.props.small} />
                    </picture>
                );
            }.bind(this)())}
        </div>
    );
}
  • 适用于 Safari 8.0.8
  • 工作于 Chrome 45
  • 在 Firefox 40.0.3 中工作(仅在刷新时,不在调整大小时)

更新:2016 年 4 月 28 日

现在在 React 中使用同构渲染,所以这个解决方案对我不起作用。

  1. 无法import 'picturefill';,因为依赖于节点中不可用的window
  2. picturefill();,见下文,不适用于 componentDidUpdate for Safari (9.0.3)。
  3. <picture> 由于错误图像 (fowi) 的闪烁,之前描述的策略对我不起作用。
/**
 * OLD
 */

export class MyComponent extends Component {
  componentDidMount() {
    // TODO: remove when updated https://github.com/scottjehl/picturefill/pull/556
    const picturefill = require('picturefill');

    picturefill();
  }
}

/**
 * NEW
 */

// TODO: remove when updated https://github.com/scottjehl/picturefill/pull/556
if (__CLIENT__) {
  require('picturefill');
  require('picturefill/dist/plugins/mutation/pf.mutation'); // not sure if this does anything
}

export class MyComponent extends Component {}

图片已更新为:

<picture>
  <source media="(min-width: 640px)" srcSet={'...'} />
  <source srcSet={'...'} />

  {/* SEE: http://scottjehl.github.io/picturefill/#fowi-safari */}
  <img alt={title} />
</picture>

对于 Safari,内容的闪烁仍然存在...但现在显示替代文本...

至于require('picturefill/dist/plugins/mutation/pf.mutation');:

This plugin automatically detects any DOM mutation and polyfills new or changed responsive images automatically. It also adds support for responsive images IDL attributes/properties. If you have a highly dynamic website or a SPA you probably want to use this plugin. (This plugin does not work with IE8.)

我建议您使用 picturefill 3.0 RC1 in combination with the mutation plugin。这样你就不需要调用picturefill();,一切都自动完成。

这适用于任何浏览器。