Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add clearCache method #103

Closed
hspinks opened this issue Oct 23, 2013 · 9 comments
Closed

add clearCache method #103

hspinks opened this issue Oct 23, 2013 · 9 comments

Comments

@hspinks
Copy link

hspinks commented Oct 23, 2013

First of all, let me say a huge THANK YOU for the imagesLoaded and Masonry modules - truly awesome, very easy to plug in and get started, and have significantly improved the design and development speed on my web projects.

I have run into a particular issue here with Rails 3.1, Unobtrusive JS submitting forms via Ajax, and imagesLoaded.

Essentially, I am displaying a grid of products with filters so you can display only the ones that fit certain criteria. A watered down version of the code that I use can be found in this gist.

The search filter form sends its request to the same products page, and when it uses Ajax it responds with a JS file that replaces the HTML of a products-grid container with the new, matching products. Of course, the images for all of these products are different sizes, so I use Masonry to lay them out nicely, which works great on the initial Ajax-less page load. However, after getting the new set of products with Ajax, the imagesLoaded fires way too early, and I get a layout that is not very pretty.

I have done enough testing to know that the issue is not with Masonry, but with imagesLoaded. The simplest test that confirmed this was simply putting a longer timeout before calling Masonry, and when I did that, the Masonry laid the div out flawlessly.

I have isolated the issue to only occurring when it is the same images that are in both the initial HTML and the Ajax-loaded HTML. My guess is that imagesLoaded somehow caches whether or not these images have been loaded, and therefore does not do any sort of re-check when it sees the same image URL a second time.

Looking at the imagesLoaded project page, I don't see anything that immediately jumps out at me as a solution, so I figured I would ask here:
Is there a way to reset the imagesLoaded module so that it doesn't "remember" whether the same image reloaded in the page has been rendered?

@desandro
Copy link
Owner

Yup. Along with #92, you make the case clear that there needs to be a clearCache method. I've updated the name of this issue to match.

@hspinks
Copy link
Author

hspinks commented Oct 24, 2013

I'll look forward to that additional functionality, and hope to have the time to fork and contribute at some point soon myself.

In the meantime, just in case anyone else is using Rails 3, Ajax, imagesLoaded, and Masonry together and gets to this page looking for a solution, I've implemented a very simple workaround that seems to take care of this issue for the most part. When the Ajax returns successfully, I set a couple of timeouts at different intervals to lay the masonry out again like so:

var msnry = new Masonry(document.getElementById("products-grid"));

setTimeout(function() {
    msnry.layout();
}, 500);

setTimeout(function() {
    msnry.layout();
}, 5000);

Users are not going to scroll down far enough to get to any of the items whose images haven't loaded within half a second, so the first .layout() takes care of the first block of images, then approx 5 seconds later when all of the images have loaded, it lays the page out again. You can probably fine-tune this to figure out the right number of timeouts and length of timeouts that work for your page. Pretty simple, but thought I might as well post for anyone else looking for a solution here.

@olegkurchin
Copy link

I think you don't necessarily need to clear cache in order to avoid false positives from imagesLoaded. I had the same problem and the solution was to use fix proposed in pull request #114 from neroDyv. I believe it's more user-friendly rather than force browser to clear cache and reload images.

@akyoto
Copy link

akyoto commented Jan 24, 2014

Just wanted to say that I've run into this issue as well. Desperately trying to find a solution for the problem that cached images are triggering the event too early (in Chrome only).

@cucharacha
Copy link

I having this issue too with chrome only. My ajax call return dynamic container and dynamic images inside the container. The first time imagesloaded works fine, however 2nd time onward ajax return, the images loaded but container height is smaller compare to image inside the container. That make the image cut off by container.
It will be able to fix if the images are fix with height. However, not the case with dynamic images.
I tried the setTimeout solution mentioned above, it works, but, if the page stay longer, and ajax call again, the same problem happen again.
Any advice if imagesLoaded PACKAGED v3.1.1 already cache included? If it is, it may due to my way of using masonry and imagesloaded is wrong.

@cucharacha
Copy link

I am using jquery and php, so, to detect only chrome, I use simple javascript way. Maybe it sound un-professional, but it works for now by calling again masonry imagesLoaded if it is chrome, after imgLoading done.

                                       var isChromium = window.chrome,
                        vendorName = window.navigator.vendor;
                        if(isChromium !== null && vendorName === "Google Inc.") { 
                            setTimeout(function() {
                                pin_cont.masonry({
                                    itemSelector: ".bestdeal_item",
                                    columnWidth: 2,
                                });                     
                            }, 500); 
                        } 

The full imagesLoaded call looks like below:

                var pin_cont = $("#shopbestblock");  
                var imgLoading = pin_cont.imagesLoaded( function() {

                    pin_cont.masonry({
                        itemSelector: ".bestdeal_item",
                        columnWidth: 2,

                    });                     
                    pin_cont.masonry('reloadItems');

                    });

                    imgLoading.done( function() {
                        $("#overlay").hide();

                        //only for chrome call masonry again due to image cache time
                        var isChromium = window.chrome,
                        vendorName = window.navigator.vendor;
                        if(isChromium !== null && vendorName === "Google Inc.") {

                            setTimeout(function() {
                                pin_cont.masonry({
                                    itemSelector: ".bestdeal_item",
                                    columnWidth: 2,

                                });                     

                            }, 500); 
                        } 
                        //end chrome image cache work
                    });
                    imgLoading.fail( function() {
                        $("#overlay").hide();
                    });
                    imgLoading.progress( function( instance, image ) {
                        var result = image.isLoaded ? 'loaded' : 'broken';
                        console.log( 'image is ' + result + ' for ' + image.img.src);
                    });

@desandro
Copy link
Owner

I did cut a branch that removes the cache completely, no-cache. I'm evaluating whether its worth merging in this branch to master. It sounds like it would be useful for your use case. You wouldn't need the clearCache method at all.

@cperryk
Copy link

cperryk commented Jan 2, 2015

I was facing a similar issue. The imagesLoaded callback was firing before the images themselves had dimensions in cases in which the images had been displayed before. But the no-cache branch resolved it.

@desandro
Copy link
Owner

imagesLoaded v3.2.0 has removed the cache. Try it out. Closing this issue. 🐳

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants