图像滑块没有'在我的图像出现之前,请不要正确显示它们'重新缓存

Image slider doesn't show my images properly before they're cached

本文关键字:图像 显示 缓存 新缓存 我的      更新时间:2023-09-26

编辑:MeteorPad演示。(滑块应该可以工作,但它不应该显示第一个图像,只显示其中的一小部分。但这个错误只会在某些时候显示(主要在Safari或所有非Chrome浏览器上显示(,所以要小心(。

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

我使用的是Ken Wheeler的Slick滑块,虽然这是我发现的最好的滑块,但当我想在each循环中加载图像时,它会出现一个非常严重的错误,因为它只显示图像的顶部,直到我按下下一个/prev按钮或拖动到下一个图像。

我的收藏有以下字段:

"galleryImages": [
    {
      "name": "picture1",
      "position": "first"
    },
    {
      "name": "picture2",
      "position": "second",
    },
    {
      "name": "picture3",
      "position": "last"
    }
]

我使用gallery作为slick容器:

<div class="gallery">
  {{#each galleryImages}}
    <div>{{> Images}}</div>
  {{/each}}
</div>
<template name="Images">
  <img src="{{imageUrlMaker name}}" alt="{{name}}">
</template>

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

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

Template.Images.onRendered(function() {
    setTimeout(function() {
        $('.gallery').slick({
            arrows: true,
            dots: true,
            infinite: true,
            mobileFirst: true,
            adaptiveHeight: true
        })
    }, 100)
})

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

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

有人能想出一个变通办法或解决方案吗,也许可以用一些聪明的方式使用position: "last"?有人能理解为什么会出现这个bug吗?

首先:如果我没有弄错的话,您正在初始化每个图像渲染上的整个光滑滑块。因此,最好在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();
    if (firstImage) {
      var img = new Image();
      img.onload = function() {
            $('.gallery').slick({
                infinite: true,
                mobileFirst: true,
                adaptiveHeight: true
            });
      }
      img.src = firstImage.url;
    }
  });
})

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

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

希望这能在任何方面有所帮助。