twobin / react-lazyload Goto Github PK
View Code? Open in Web Editor NEWLazy load your component, image or anything matters the performance.
License: MIT License
Lazy load your component, image or anything matters the performance.
License: MIT License
.....
if (overflowRegex.test(overflow + overflowX + overflowY)) {
return parent;
}
....
场景:
当body设置overflowX或者overflowY其中一个为非scroll或auto的时候(如:overflowX:hidden),overflow和另外一个会自动设置为auto,则会导致这个正则判断为真,直接输出body为parent,这样就会导致isOverflow判断为真,可视范围以外的图片就会无法显示
const checkVisible = function checkVisible(component) {
...
const isOverflow = parent !== node.ownerDocument &&
parent !== document &&
parent !== document.documentElement;
...
}
Currently if you provide a placeholder component, it is wrapped in a container DIV with minHeight
set as an inline style:
render() {
return this.visible ?
this.props.children :
this.props.placeholder ?
<div style={{ minHeight: this.props.height }}>{this.props.placeholder}</div> :
<div style={{ height: this.props.height }} className="lazyload-placeholder"></div>;
}
This is problematic in my use case since I'm styling my placeholder to fit an aspect ratio, and the minHeight
leaves some extra whitespace hanging around.
It seems like the styling of the container should either be removed and left to the consumer to implement or at least a class could be added to override any default styling.
If you agree with this and want me to do the PR, I can do that.
In my project,I need load the image src dynamic because it's responsive.
For example,I want to load big img in PC and small img in Phone,so I wish I can use something like
onLoad(e) => {
e.target.src = 'http://www.cdn.images.mySite.com/someImage.jpg?width=e.target.width&height=e.target.height';
}
But I find that React(I am not sure, maybe this respo?) has added load event on image,so therer is a conflict.Are there some good ways to resolve this?If you have,please tell me,thanks a lot!
Hello,
I haven't tried all mobile devices yet, just did a quick test on an iPad Mini 1 / iOS 9.2 Safari. The demo loads but scrolling to the bottom with finger doesn't trigger content loading. I'm guessing wheel events aren't fired in this environment.
The normal demo works as expected in this environment.
The scrollParent method isn't always reliable for finding the correct scrollable Parent element. It will return a false positive is another parent other the scrollable one has an 'overflow' style. Ideally you should be able explicitly specify the parent element you want to use. Something like this:
<LazyLoad overflow={true} scrollParent=".scroll-div" >
within the scrollParent function you could simply return
return document.querySelector(props.scrollParent);
Hi,
Any updates on this version?
Thanks
Hi,
I am using the lazy load component and I have a problem on mobile where after scrolling the placeholders are not updated.
I have the below overflows set in some of the top parents.
overflow-x:hidden; overflow-y: auto;
If I tap on the placeholder it updates and shows the element correctly.
The LazyLoad component is as follows:
<LazyLoad key={index} height={156} offset={156 * 3} placeholder={<ListItemPlaceholder/>} debounce={false} throttle={false} unmountIfInvisible={true} overflow={true} >
Any advice?
Thanks for creating such a great lazyload component for react!
Recently, I tried using this package for the effect of lazyload.
After added this component to a page, I found there's nothing happened.
Then I cloned the provided examples and ran it on my localhost, it just worked.
So I rebuilt my page again step by step using the example as a base, it still worked so great.
Finally, I added a thirty-party css to the page and lazyload broke.
I just add a link tag to page
Could you help debugging which part of the css breaks the lazyload component?
It's a pity that the nice-looking UI framework can't work with lazyload component.
I think perhaps that people will find some other UI frameworks that have the same issue with this component, so maybe it's a good chance to figure it out.
in this line https://github.com/jasonslyvia/react-lazyload/blob/master/src/index.js#L24
'parent' hasn't own scrollTop() function.
It would be awesome if components that use LazyLoad
can specify a callback that would be called when the component is in view for the first time (or just.... any time it comes into view, depending on if the once
prop is used or not)
An example use case would be if a component needed to fetch some data once it comes into view.
First of all - amazing job!
I am using react-lazyload
for a very big table and added the unmountIfInvisible
option. My rows have an unknown height which is based on their content. When I scroll up and down the invisible lines are replaced with the placeholder
, which is of a constant size. This causes the visible lines to "jump" up or down because of the height differences.
Is there any way to make each placeholder
the same height as the component it replaces? or any other way to prevent this behaviour?
Thanks 😄
Great component. Any tips on making simple placeholders appear in a specific ratio? thinking that height for images is always different for responsive contexts.
It would be nice to be abel to pass placeholder as prop to LazyLoad component so that instead of just showing blank spaces while scrolling down (default behavior), it could show custom component. (like loading message or progressing bar)
Does it support react native?
I have been using LazyLoad for a while now and its been fine, i recently pulled my repo down and did a npm install
and all of a sudden all my elements wrapped inside of the Lazy Load component don't work.
I have been hacking away and have come to find that only after setting a large offset can I then achieve the functionality that i once had.
Is there any particular reason why the further down the page i get the higher the offset I need to set. Is the parent element not the immediate parent to the LazyLoad component by default.
I have a set up as follows;
import Section from '../path/to/Section-Component'
...
<div className={'HomePage'}>
<Section>
<Section1 /> /* <= <LazyLoad> component inside of the Section1 component */
</Section>
<Section>
<Section2 />
</Section>
<Section>
<Section3 />
</Section>
</div>
Within most Sections there will be a LazyLoad component, but the further down the page I get the higher the offset value.
is this normal behaviour?
I have a list component where I load in lazyload and I have a filter bar that filters the location. If a location result is not in the current scrolled view the checkVisible method does not get called resulting in the component no getting loaded in.
triggering a scroll event programmatically on the overflow element did not seem to work.
I added a custom event and triggered that when searching, this worked as a quick hack.
Any ideas for being able to pass in a custom event or being able to trigger an event programmatically (maybe just on the window) to trigger checkVisible
I found a serious bug with the lazy loader where sometime images will never load until someone explicitly stops scroll to the view which can trigger lazy loader to load images.
Assume there is a page with mix of images and text.
So if you quickly scroll through the page to the bottom (with multiple images still in lazy load state), with default debounce, you will reach to the bottom of the page but page still has not loaded the image.
This gives user a impression that page is small (without images), expect you implement some placeholder.
If user again scrolls to the top, will not find any image on the way. When you release scroll at the top, lazyload image is not in the viewport hence it will not load.
Trick is you know there is a image in the page, and you scroll to that location and stop scrolling, suddenly image pops up.
I think the logic should be to trigger loading all the lazy resources which has passed through the view, not just where scroll stopped. This is a serious bug to be fixed
just like http://www.jq22.com/yanshi390
I am using react-lazyload within an overflow container for chat messages (newest messages at the very bottom). Is it possible to reverse the direction, so start at the very bottom, scroll upwards and lazy load those items?
Thank you for this library, nice work. I'm using it in my project. Currently it only listens to scroll
and resize
event for update. However, sometimes not only these two events trigger position change.
Imaging a react component renders a grid system which half of grid items are below the viewport. After the component re-renders, if only 1 item is remaining and it was below the viewport before, it is not re-rendered and it's lazyload checkVisible
won't get called even thought is above the fold now.
One solution can be adding a forceCheck function to to check all invisible lazyload components in the parent component's componentDidUpdate
.
Hi,
Im using this library to hide charts in the dom, but never dissapears
LazyLoad unmountIfInvisible={true} height={600}
Plugin doesn't handle case when lazyloaded element is already positioned in viewport on page load (at the top of the page).
It requires at least one scroll event to occur.
I'd like to have the babel6-compatibility upgrades for my use case (aka a build environment that's quite reliant on babel6 - see my previous PR about AMD-ification), is there an ETA on the version upgrade?
when use react-iscroll , react-lazyload is not work ?
Would it be possible to add an onLoad
property that accepts a function? This function would be called when the lazily loaded component is loaded.
My app keeps track of how many items you have not "seen" yet. As you scroll and these items come into view and are loaded, I'd like to mark them as having been "seen".
There are ways I can work around the lack of this feature, but it seems like it might be useful for others as well.
It seems that when you reverse the list that lazyload is rendering, it does not detect the change, so the items that were on the bottom of the list that are now at the top are not loading at all.
lazyload.js
let menus = MeneStore.getMenus();
let allList = menus.map((menu, index) => {
let currentCarts = getCurrentCarts(carts, menu);
return <LazyLoad key={index} height={200} offset={200} once={true} placeholder={<MenuPlaceholder />}>
<WillLazyloadComponent />
</LazyLoad>
}
);
placeholder
组件用的这个库提供的.
问题出现在,如果我将 LazyLoad
组件的 placeholder 属性移除掉,我的 WillLazyloadComponent
就是懒加载的,如果加入 placeholder
属性的话 WillLazyloadComponent
就会默认显示出来
checkOverflowVisible
currently is used if the lazyload component is scrolled in an element. In the function I figured that the element's top is calculated using offsetTop
const elementTop = node.offsetTop;
const elementBottom = elementTop + elementHeight;
offsetTop
returns the distance of the current element relative to the top of the offsetParent
node. So the offsetTop
is not the correct top if the offsetParent
is not the ``scrollParent`.
I recommend just use getBoundingClientRect
to check the visibility of the element. In the checkNormalVisible
function
const { top, height: elementHeight } = node.getBoundingClientRect();
const elementTop = top + scrollTop; // element top relative to document
const elementBottom = elementTop + elementHeight;
const windowInnerHeight = window.innerHeight || document.documentElement.clientHeight;
const documentBottom = scrollTop + windowInnerHeight;
const offsets = Array.isArray(component.props.offset) ?
component.props.offset :
[component.props.offset, component.props.offset]; // Be compatible with previous API
return (elementTop - offsets[0] <= documentBottom) &&
(elementBottom + offsets[1] >= scrollTop);
you can just remove the scrollTop because
elementTop - offset[0] <= documentBottom
--> top + scrollTop - offset[0] <= scrollTop + windowInnerHeight
--> top - offset[0] <= windowInnerHeight
elementBottom + offsets[1] >= scrollTop
--> scrollTop + windowInnerHeight + offsets[1] >= scrollTop
--> windowInnerHeight + offsets[1] >= 0
For the overflow situation, just check the whether the element is in the intersection of its scrollParent and viewport.
并不预先知道高度是多少时可否使用
还有高度单位是否可以支持rem等单位
Hello,
I'm trying to use this component inside of a custom Image component. It's quite simple, a stateless functional component. It looks as follows:
import React, {PropTypes} from 'react';
import classNames from 'classnames';
import LazyLoad from 'react-lazyload';
const Image = ({alt, className, lazyLoad, ...imgAttributes}) => {
const classes = classNames(
'Image',
className
);
const img = <img alt={alt} className={classes} {...imgAttributes} />;
if (lazyLoad) {
return (
<LazyLoad throttle={200} height={300}>
{img}
</LazyLoad>
);
} else {
return img;
}
};
Image.propTypes = {
className: PropTypes.string,
/** Descriptive information about what is in the image. Do not use the words image, photo, or picture. */
alt: PropTypes.string,
lazyLoad: PropTypes.bool
};
Image.defaultProps = {
className: '',
alt: null,
lazyLoad: false
};
export default Image;
I then call it like this:
<Image src="http://placehold.it/550x400" alt="Just a temporary placeholder" lazyLoad />
I don't see the placeholder div and my image automatically gets rendered into the DOM without me scrolling to it (it's pretty far down). Even if I replace all of the logic for testing lazyLoad and displaying the correct thing, or remove it completely and just show the LazyLoad wrapped around an image, I still see the image rendered into the DOM automatically in the elements panel.
Is there anything I'm doing wrong here?
I'm currently using react-lazyload v1.3.2.
I'm trying to add the property once
but it's breaking my code:
<Lazyload once>
<img src="http://lorempixel.com/500/500" className="responsive-img" />
</Lazyload>
Gives me an error (at least on Chrome - didn't check on other browsers):
Uncaught TypeError: Cannot read property 'ownerDocument' of null
This error comes from the function checkVisible
, at the following lines:
var node = _reactDom2['default'].findDOMNode(component);
var parent = _utilsScrollParent2['default'](node);
var isOverflow = parent !== (node.ownerDocument || document); // here
Seems like _reactDom2['default'].findDOMNode(component)
is undefined or null for some reasons.
Hello! I'm sorry for being spammy, but we'd really like to get this fix #41 into our environment to fix the bug it was causing for us.
Currently plugin observes vertical axis only.
How about horizontal one?
On my website I have huge horizontal list and I would like to apply lazyloading for items in those list too.
看了新版本(2.4.1)的代码, 似乎不再需要同时声明 height
和 placeholder
, 相关代码
对比之前版本的实现方法, 发现的确不再需要直接关心这个数值(其实以前也不是直接根据他来判断, 不知道理解错没);
由于对实现不全理解, 可不可以简单的认为:
height
的placeholder
后就不再需要设置组件的height
属性来result better lazyload performance
placeholder
, 可以通过任意方式, 包括 css, style 的各种单位(如 em, px) 来定义它的 height, 这种做法不会导致比以前差的性能谢谢
I'm using the version 42.0 of Firefox for Mac and the lazyload doesn't work well
It stops working when imported into multiple bundles. Only one of it works.
I debug and the reason is only one of the instance receive window.scroll event, others does not receive. Which one receives depends on race condition. I can see one copy of LazyLoad in each bundle
I think you can repro this using two separate react components in two files and lazy loading both
I have a project based on react-boilerplate that uses webpack with babel to build for production. When I include react-lazyload
as a dependency, I get an error when building:
ERROR in ./~/react-lazyload/lib/index.js
Module build failed: ReferenceError: Unknown plugin "transform-decorators-legacy" specified in "/Users/tauren/repos/react-boilerplate/node_modules/react-lazyload/.babelrc" at 0, attempted to resolve relative to "/Users/tauren/repos/react-boilerplate/node_modules/react-lazyload"
I've resolved the issue by adding babel-plugin-transform-decorators-legacy
as a dependency of my project and adding it to my babel plugins configuration. But I would think this shouldn't be necessary since react-lazyload provides already transpiled code.
I'm guessing that when babel runs in my project, it picks up the .babelrc
in react-lazyload
. Perhaps .babelrc
should be added to the .npmignore
file so that it isn't published to NPM?
It would be nice to configure the debounce interval as well as choose between debouncing and throttling behavior.
I can't use it with typescript i get this error
error TS7016: Could not find a declaration file for module 'react-lazyload'
i can't find a declaration ".d.ts" file on github.com/DefinitelyTyped/DefinitelyTyped
Just tried to run npm shrinkwrap
on a project that includes react-lazyload
as a dependency and got this error:
npm ERR! Problems were encountered
npm ERR! Please correct and try again.
npm ERR! extraneous: [email protected] /path/to/node_modules/react-lazyload/node_modules/history
Here's a link to the module on npmcdn.
It seems like the issue with erroneously publishing the history
module should be fixed in recent versions of npm -- see npm/npm#9642.
I submitted this on Stack Overflow as well.
I am building a kind of searchable gallery site using React. It is being tested and continuously deployed at kitnic.it. The relevant source code is here.
I am using react-lazyload to lazy load the thumbnail images. I tried a few other lazy load solutions, the only other one that worked was this simple one but the performance is a lot worse.
The problem I am having is when I do a search the previous images in that place quickly pops up.
I made a short demo video here: https://youtu.be/7Rnye3S0H-w
To reproduce on kitnic.it:
Hi!
I'm currently rendering my react app to a node that isn't the root - it's about 1/3 of the way down the page. It looks like it's grabbing the first div inside body and adding data-lazyload-listened="1"
to it, not the react root, causing everything to load after the first render, even if it isn't in the viewport.
Am I doing anything wrong?
I came to react-lazyload wanting to lazy load images. It took a bit to figure out that I would need to create my own component which gets provided with a visible
prop by react-lazyload
. My expectation was that the LazyLoad
component wouldn't render its children if it weren't visible.
I did something like:
const LazyLoadImage = (props) => props.visible ? <img {...props} /> : <span {...props} />;
<LazyLoad once>
<LazyLoadImage src="/example.jpg" style={{ display: 'block', width: 100: height: 100 }} />
</LazyLoad>
How are other people handling this use-case?
Most of your demo examples not working due to the following errors.
Uncaught TypeError: Cannot call a class as a function
I ran into an issue where the <html>
and <body>
had overflow-x:hidden
because of this slider menu plugin we are using, this was causing lazy load to break when scrolling vertically.
Not sure if it is by design but I thought I'll mentioned here. It may also be related to #33
I need to display a list view with more than 1000 elements, so I need to load the data from 20 to 20.
Can you post an example loading async data with an api rest?
Or any suggest please?
Hi,
i tried the demo page with IE11, nothing get loaded. Is this a known issue?
After debugging this issue i have come to find that parent
variable is being set to either Window or Document but neither of the two contain the getAttribute()
function.
This issue breaks my code and prevents the render of the component. I have defined my LazyLoad
component as so..
<div className={'Section6')}>
<LazyLoad height={333} offset={300} overflow once>
<Picture
image={sectionImage}
imageRetina={sectionImageRetina}
imageMobile={sectionImageMobile}
imageMobileRetina={sectionImage}
screen={SCREEN_SIZES.SCREEN_SM_MAX} />
</LazyLoad>
</div>
The parent div has a position: relative;
styling
Have I not used the overflow prop correctly? because it seems that although the overflow prop os set, the returned object in parent doesn't contain the function which needs to be checked for the condition and therefore breaks at this point and throws an error.
Have i missed something?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.