Javascript 延迟加载ReactJS渲染内容中的图像、视频和iFrame

Javascript 延迟加载ReactJS渲染内容中的图像、视频和iFrame,javascript,jquery,reactjs,Javascript,Jquery,Reactjs,我在页面加载时有一个react组件呈现。内容包括很多富媒体,我只想在内容出现在屏幕上时延迟加载,然后在内容不出现时卸载。用户滚动时会加载更多内容 我使用了多种技术组合来处理延迟加载iFrame、视频和图像,并且在通过React呈现的内容之外工作得很好。主要是自定义jQuery和库 我的主要问题是,我不能让我的延迟加载函数在刚刚放入dom的内容上触发。一旦用户调整大小/滚动,它就会工作(我有一个相应触发的事件)。当内容可用时,如何使其触发 我尝试过从componentDidMount触发它,但这似

我在页面加载时有一个react组件呈现。内容包括很多富媒体,我只想在内容出现在屏幕上时延迟加载,然后在内容不出现时卸载。用户滚动时会加载更多内容

我使用了多种技术组合来处理延迟加载iFrame、视频和图像,并且在通过React呈现的内容之外工作得很好。主要是自定义jQuery和库

我的主要问题是,我不能让我的延迟加载函数在刚刚放入dom的内容上触发。一旦用户调整大小/滚动,它就会工作(我有一个相应触发的事件)。当内容可用时,如何使其触发

我尝试过从componentDidMount触发它,但这似乎不起作用,因为内容还没有放入DOM

我想我可以每n秒检查一次内容,但出于性能原因,我希望避免这样做

以下是我的简化代码:

var EntriesList = React.createClass({
    render: function() {
        var entries = this.props.items.map(function(entry) {
            return (
                <div className="entry list-group-item" key={entry.id}>
                    // lazy items video, image, iframe...
                    <img src="1px.gif" className="lazy" datasource="/path/to/original" />
                    <video poster="1px.gif" data-poster-orig="/path/to/original" preload="none">{entry.sources}</video>
                </div>
            );
        });

        return(<div>{entries}</div>);
    }
});


var App = React.createClass({
    componentDidMount: function() {
        $.get('/path/to/json', function(data) {
            this.setState({entryItems: data.entries});
        }.bind(this));

        // What do I put here to trigger lazy load? for the rendered content?
        myLazyLoad(); // does not work on the new content.

    },
    getInitialState: function() {
        return ({
            entryItems: []
        });
    },
    render: function() {
        return (<div><EntriesList items={this.state.entryItems} /></div>);
    }
});

React.render(<App />, document.getElementById('entries'));
var EntriesList=React.createClass({
render:function(){
var entries=this.props.items.map(函数(条目){
返回(
//惰性项目视频、图像、iframe。。。
{entry.sources}
);
});
返回({entries});
}
});
var App=React.createClass({
componentDidMount:function(){
$.get('/path/to/json',函数(数据){
this.setState({entryItems:data.entries});
}.约束(这个);
//我在这里放了什么来触发延迟加载?对于呈现的内容?
myLazyLoad();//无法处理新内容。
},
getInitialState:函数(){
返回({
入口项:[]
});
},
render:function(){
返回();
}
});
React.render(,document.getElementById('entries');

尝试将滚动事件检查到您的div父容器(在应用程序类中呈现的div:

var App = React.createClass({
    componentDidMount: function() {
        $.get('/path/to/json', function(data) {
            this.setState({entryItems: data.entries});
        }.bind(this));
    },

    myLazyLoad: function(e) {
        // here do actions that you need: load new content, do ajax request, ...
        // example: check you scrolling and load new content from page 1, 2, 3 ... N
        var self = this;
        $.get('path/to/json/?page=N', function(data) {
            self.setState({entryItems: data.entries});
        });
    },

    getInitialState: function() {
        return ({
            entryItems: []
        });
    },
    render: function() {
        return (<div onScroll={this.myLazyLoad}><EntriesList items={this.state.entryItems} /></div>);
    }
});
var-App=React.createClass({
componentDidMount:function(){
$.get('/path/to/json',函数(数据){
this.setState({entryItems:data.entries});
}.约束(这个);
},
myLazyLoad:函数(e){
//下面是您需要执行的操作:加载新内容、执行ajax请求。。。
//示例:检查滚动并从第1、2、3…页加载新内容
var self=这个;
$.get('path/to/json/?page=N',函数(数据){
self.setState({entryItems:data.entries});
});
},
getInitialState:函数(){
返回({
入口项:[]
});
},
render:function(){
返回();
}
});

如果您试图使用jquery插件,可能会导致DOM与React呈现的DOM不同步。同样,在您的情况下,应该在
EntriesList
组件中调用延迟加载函数,而不是从其父组件调用

您可以使用一个非常简单的组件作为负载:

或者只是从它的源代码中获得灵感来实现自己的

var EntriesList = React.createClass({
    render: function() {
        var entries = this.props.items.map(function(entry) {
            return (
                <div className="entry list-group-item" key={entry.id}>

                    // lazy items video, image, iframe...
                    <LazyLoad>
                       <img src="1px.gif" datasource="/path/to/original" />
                       <video poster="1px.gif" data-poster-orig="/path/to/original" preload="none">{entry.sources}</video>
                    </LazyLoad>

                </div>
            );
        });

        return(<div>{entries}</div>);
    }
});
var EntriesList=React.createClass({
render:function(){
var entries=this.props.items.map(函数(条目){
返回(
//惰性项目视频、图像、iframe。。。
{entry.sources}
);
});
返回({entries});
}
});
延迟加载反应

组件可以在其使用者不知道使用高阶函数的情况下延迟加载依赖项,或者使用者可以在其子级不知道使用接受函数和模块集合的组件或两者的某种组合的情况下延迟加载其子级

使用npm软件包,您只需将要延迟加载的组件封装在
中,它就可以在没有任何其他配置的情况下工作

import { LazyLoadComponent } from 'react-lazy-load-image-component';

var EntriesList = React.createClass({
    render: function() {
        var entries = this.props.items.map(function(entry) {
            return (
                <LazyLoadComponent>
                    <div className="entry list-group-item" key={entry.id}>
                        // lazy items video, image, iframe...
                        <img src="1px.gif" className="lazy" />
                        <video poster="1px.gif" data-poster-orig="/path/to/original" preload="none">{entry.sources}</video>
                    </div>
                </LazyLoadComponent>
            );
        });

        return(<div>{entries}</div>);
    }
});


var App = React.createClass({
    componentDidMount: function() {
        $.get('/path/to/json', function(data) {
            this.setState({entryItems: data.entries});
        }.bind(this));

    },
    getInitialState: function() {
        return ({
            entryItems: []
        });
    },
    render: function() {
        return (<div><EntriesList items={this.state.entryItems} /></div>);
    }
});

React.render(<App />, document.getElementById('entries'));
从'react lazyload image component'导入{LazyLoadComponent};
var EntriesList=React.createClass({
render:function(){
var entries=this.props.items.map(函数(条目){
返回(
//惰性项目视频、图像、iframe。。。
{entry.sources}
);
});
返回({entries});
}
});
var App=React.createClass({
componentDidMount:function(){
$.get('/path/to/json',函数(数据){
this.setState({entryItems:data.entries});
}.约束(这个);
},
getInitialState:函数(){
返回({
入口项:[]
});
},
render:function(){
返回();
}
});
React.render(,document.getElementById('entries');

免责声明:我是该软件包的作者。

似乎不起作用。滚动不会触发myLazyLoad。我还认为这会导致相同的问题,因为我需要在内容放入DOM后触发事件,而不是滚动或调整大小(这是有效的)。这很奇怪,因为若父div有scroll,那个么事件将是fire…请在JSFIDLE上创建一个示例来看看