EDIT: MeteorPad demo here. (The slider should work but it shouldn't show the first image, only a sliver of it. But the bug only shows sometimes (and primarily on Safari or everything that isn't Chrome), so beware).
EDIT: The bug is that the first image in the slider is not displayed properly, only the very top of it, until you swipe or click the next/prev button. This bug only turns up if you load the images from a database source, not when you use the slider "normally".
I'm using Ken Wheeler's Slick slider, and while it's the best I've found it comes with a pretty nasty bug when I want to load images in an each
loop in that it only shows the top of them until I press either the next/prev buttons or drag to the next image.
My collection has the following field:
"galleryImages": [
{
"name": "picture1",
"position": "first"
},
{
"name": "picture2",
"position": "second",
},
{
"name": "picture3",
"position": "last"
}
]
I use gallery
as the slick
container:
<div class="gallery">
{{#each galleryImages}}
<div>{{> Images}}</div>
{{/each}}
</div>
<template name="Images">
<img src="{{imageUrlMaker name}}" alt="{{name}}">
</template>
The imageUrlMaker
just creates the correct url to fetch them at, not an issue.
And when Images
is rendered I initialize the slider:
Template.Images.onRendered(function() {
setTimeout(function() {
$('.gallery').slick({
arrows: true,
dots: true,
infinite: true,
mobileFirst: true,
adaptiveHeight: true
})
}, 100)
})
The reason for the setTimeout
is that I find it erases some of the times the slider initializes before the images are loaded (for some reason).
As I said, the first time I visit a page that has images, they won't show (only the top) until they are dragged or the prev/next buttons are clicked. Or I could reload the page and everything will work.
Can anyone think of a workaround or fix, maybe using position: "last"
in some clever way? Can anyone figure out why this bug shows?
First of all: you're initializing your entire slick slider on every image render, if I'm not mistaken.
Therefore it would be better to run $('.gallery').slick
within Template.Gallery.onRendered()
rather than Template.Images.onRendered()
.
The issue is that you'll have to wait for (1) the Gallery Collection to be ready and (2) the images to be loaded.
The only thing I could come up with to address both of those issues is to access the collection within a Meteor.autorun()
and make sure the first image is loaded by the browser using an Image.onload
:
Template.Gallery.onRendered(function() {
Meteor.autorun(function() {
var firstImage = Gallery.findOne();
if (firstImage) {
var img = new Image();
img.onload = function() {
$('.gallery').slick({
infinite: true,
mobileFirst: true,
adaptiveHeight: true
});
}
img.src = firstImage.url;
}
});
})
I see two possible issues with this approach, though:
Meteor.autorun()
it will run every time there's a change on the Gallery datasource. This may or may not be a problem.Meteor.timeout()
with a timeout of 0
just to make sure it runs within the next cycle. By then the renderer should have reacted to the datasource and created all the image DOM nodes.Hope this helps in any way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With