图像滑块在缓存之前无法正确显示我的图像 [英] Image slider doesn't show my images properly before they're cached

查看:32
本文介绍了图像滑块在缓存之前无法正确显示我的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

MeteorPad 演示在这里.(滑块​​应该可以工作但它不应该显示第一张图片,只显示其中的一小部分.但该错误仅在某些时候显示(主要在 Safari 或所有非 Chrome 上显示),因此请注意).

错误是滑块中的第一张图像显示不正确,只有最顶部,直到您滑动或单击下一个/上一个按钮.只有当您从数据库源加载图像时才会出现此错误,而不会在您正常"使用滑块时出现.

我正在使用 Ken Wheeler 的 Slick 滑块,虽然它是我发现的最好的当我想在 each 循环中加载图像时,有一个非常讨厌的错误,因为它只显示它们的顶部,直到我按下下一个/上一个按钮或拖动到下一个图像.

我的收藏有以下字段:

"galleryImages": [{"name": "图片1",位置":第一"},{"name": "图片2","位置": "第二",},{"name": "picture3",位置":最后"}]

我使用 gallery 作为 slick 容器:

{{/每个}}

<模板名称="图像"><img src="{{imageUrlMaker name}}" alt="{{name}}">

imageUrlMaker 只是创建了正确的 url 来获取它们,这不是问题.

Images 被渲染时,我会初始化滑块:

Template.Images.onRendered(function() {设置超时(函数(){$('.gallery').slick({箭头:真实,点:对,无限:真实,移动优先:真,自适应高度:真})}, 100)})

setTimeout 的原因是我发现它会在加载图像之前擦除滑块初始化的一些时间(出于某种原因).

正如我所说,当我第一次访问包含图像的页面时,它们不会显示(仅顶部),直到它们被拖动或点击上一个/下一个按钮.或者我可以重新加载页面,一切都会正常.

任何人都可以想出一种解决方法或修复方法,也许以某种巧妙的方式使用 position: "last" ?谁能弄清楚为什么会显示此错误?

解决方案

首先:如果我没记错的话,您正在每个图像渲染上初始化整个光滑的滑块.因此最好在 Template.Gallery.onRendered() 中运行 $('.gallery').slick 而不是 Template.Images.onRendered().

问题是您必须等待 (1) Gallery Collection 准备就绪和 (2) 图片加载.

为了解决这两个问题,我唯一能想到的就是访问 Meteor.autorun() 中的集合,并确保浏览器使用 代码>Image.onload:

Template.Gallery.onRendered(function() {Meteor.autorun(function() {var firstImage = Gallery.findOne();如果(第一张图片){var img = new Image();img.onload = 函数(){$('.gallery').slick({无限:真实,移动优先:真,自适应高度:真});}img.src = firstImage.url;}});})

不过,我认为这种方法有两个可能的问题:

  • 由于灵活的初始化程序位于 Meteor.autorun() 中,因此每当 Gallery 数据源发生更改时,它都会运行.这可能是也可能不是问题.
  • 实际上并不能保证在光滑的初始化程序运行时渲染图像.您可能希望将某些代码封装在 Meteor.timeout() 中,超时时间为 0 以确保它在下一个周期内运行.到那时,渲染器应该已经对数据源做出反应并创建了所有图像 DOM 节点.

希望这对您有所帮助.

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:

  • Since the slick initializer is within a Meteor.autorun() it will run every time there's a change on the Gallery datasource. This may or may not be a problem.
  • It's not actually guaranteed that the images are rendered by the time the slick initializer runs. You may want to encapsulate some of the code within a 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.

这篇关于图像滑块在缓存之前无法正确显示我的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆