在触发JQuery幻灯片之前加载所有图像

时间:2014-05-11 15:58:51

标签: jquery css ruby-on-rails

我修改了Visual Idiot的Unslider(http://unslider.com/)以根据图像比例调整多宽度幻灯片,但在此过程中,我遇到了导致幻灯片的错误以微小的缩略图加载(我认为在图像无法一直加载的情况下)。这个问题#1。所以我试图等到所有图像都加载完毕。但我还没有找到成功做到这一点的方法。这个问题#2。

这是我在Unslider init()函数中添加的代码:

_.init = function(el, o) {
  //  Check whether we're passing any options in to Unslider
  _.o = $.extend(_.o, o);

  _.el = el;
  _.ul = el.find(_.o.items);
  _.max = [el.outerWidth() | 0, el.outerHeight() | 0];
  _.max = [100, 100];
  _.li = _.ul.find(_.o.item).each(function(index) {
    var me = $(this);
    var an_image = me.find('img');
    an_image.load(function() {
      width = an_image[0].naturalWidth,
      height = an_image[0].naturalHeight;

      setSlideHeight(an_image, width, height, 300, 20);
      if ( an_image.parent().parent().is(":last-child") ) {

        _.el.css("width", 900);
      }
    })  

    //  Set the max values
    //if (width > _.max[0]) _.max[0] = width;
    //if (height > _.max[1]) _.max[1] = height;
  });

这是我的Ruby部分内容,脚本内联用于在加载所有图像时触发Unslider。

<% if @page.cap_gallery_images.any? %>
  <script>
    $(document).ready(function() {
      var numLoaded = 0;
      var numToLoad = $('#gallery img').length;
      alert("To Load: " + numToLoad);
      $('#gallery img').load(function(){
        numLoaded += 1;
        alert("Loaded: " + numLoaded);
        if (numLoaded == numToLoad) {
          var gallery = $('#gallery').unslider(),
          data = gallery.data('unslider');
          data.to(0);
        }
      });
      $("#slidecontainer .slide a").click(function(e) {
        destination = $(this).parent().index();
        data.to(destination);
        e.preventDefault;
      });
      $(window).scroll(function() {
        checkGalleryAgainstLogo();
      });
      $(window).resize(function() {
        checkGalleryAgainstLogo();
      });
      checkGalleryAgainstLogo();
      $('#logo.small').addClass('white');
    });
  </script>
<% end %>

问题在于,图像加载处理程序看起来并非全部触发。请在我在http://penumbra-2.herokuapp.com/education

上使用它的页面上下文中查看

6 个答案:

答案 0 :(得分:2)

关于#2:我认为你这太复杂了。您不必像您一样检查个人img资产;你真的只想知道整个画廊何时加载,所以让你的生活变得简单:

  $('#gallerycontainer').load(function(){
      $('#gallery').unslider();
    }
  });

您可能希望将HTML添加到您的问题中,以便人们知道如何定位jQuery:

<div id="gallerycontainer">
  <div id="gallery">
    <div id="slidecontainer">
      <div class="slide">
        <a href="#"><img /></a>
      </div>
    </div>
  </div>
</div>

答案 1 :(得分:2)

当加载事件和所有子元素已完全加载时,会将事件发送到元素。 .load是您所需要的。使用它的一个优点是您可以将其附加到DOM的子集。如果您有像这样的部门中的图像

<div class="slider">
  <img src="image1.jpg"/>
  <img src="image2.jpg"/>
  <img src="image3.jpg"/>
</div>

现在,如果已加载所有图像,则可以在幻灯片容器上使用.load。

$('.slider img').load(function(){
  //Your code goes here
});

注意:如果您使用的是jQuery 1.8,则不推荐使用它。 您可以使用.on和适当的参数 例如.on('load', handler)

答案 2 :(得分:1)

我可以看到两种不同的解决方案,取决于你的目标。

在您正在使用的代码$(document).ready();上,当DOM准备好时触发,而不是在完全下载资源时触发,因此检测图像何时加载是有意义的,但在这种情况下我是d去使用本机Image()对象并避免使用.load()因为我发现它在几种情况下非常不可靠,据我所知,如果从浏览器缓存中加载图像,它有时也不会完全触发

$('#gallery img').each(function() {
    var currentimage = new Image();
    currentimage.src = this.src;
    currentimage.onload = function(){
        numLoaded += 1;
        alert("Loaded: " + numLoaded);
        if (numLoaded == numToLoad) {
            var gallery = $('#gallery').unslider(),
            data = gallery.data('unslider');
            data.to(0);
        }
    };
});

另一个解决方案(我更喜欢在这里使用)是使用window.onload,当你的文档和资产被完全下载时会触发它,你应该以这种方式使用它:

window.onload = function(){
    // Initialise your slider here
}

答案 3 :(得分:1)

试试这个(模式)

HTML

<!-- load images container, images with document, `display:none` -->
        <div id="slidecontainer" style="display:none;">
            <div class="slide"> <a href="#">
              <img alt="Chemistry-1" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/chemistry-1.jpg" />
            </a>

            </div>
            <div class="slide"> <a href="#">
              <img alt="Hamilton" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/Hamilton.jpg" />
            </a>

            </div>
            <div class="slide"> <a href="#">
              <img alt="Platinum6" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/platinum6.jpg" />
            </a>

            </div>
            <div class="slide"> <a href="#">
              <img alt="Lectures-1-2" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/lectures-1-2.jpg" />
            </a>

            </div>
            <div class="slide"> <a href="#">
              <img alt="Lenses-1-2" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/lenses-1-2.jpg" />
            </a>

            </div>
            <div class="slide"> <a href="#">
              <img alt="Bromoil-1" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/bromoil-1.jpg" />
            </a>

            </div>
            <div class="slide"> <a href="#">
              <img alt="Platinum2-1" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/platinum2-1.jpg" />
            </a>

            </div>
            <div class="slide"> <a href="#">
              <img alt="Schaefer2" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/Schaefer2.jpg" />
            </a>

            </div>
            <div class="slide"> <a href="#">
              <img alt="Classroom-1-2" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/classroom-1-2.jpg" />
            </a>

            </div>
            <div class="slide"> <a href="#">
              <img alt="Dagbeq_web" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/dagbeq_web.jpg" />
            </a>

            </div>
            <div class="slide"> <a href="#">
              <img alt="Carbon_schaefer" class="center-slide" src="https://test-penumbra-images-cap.s3.amazonaws.com/uploads/Carbon_Schaefer.jpg" />
            </a>

            </div>
        </div>

    <div id="gallerycontainer">
        <div id="gallery" style="margin-top: 67px;"></div>
    </div>

JS

// hold jquery `ready` `event`
$.holdReady(true);
// load images container, images into `slider` container
$("#gallery").load(document.location.href + " #slidecontainer", 
  function(data, textStatus, jqxhr) {
    // if all images loaded (11), document.ready, release `holdReady`
    return ($("#gallery img").length === 11 
              && $.isReady 
              && jqxhr.state() === "resolved"
            ? $.when($.holdReady(false)).done(function() {                    
                alert($.isReady);  
                $("#slidecontainer").css("display", "block");
                // images appended to document,                  
                // do (`slider`) stuff                   
              }) 
            : alert(!$.isReady) )
});

jsfiddle http://jsfiddle.net/guest271314/tLca3/

答案 4 :(得分:1)

有一个专门为它构建的库,它在处理图像加载时总是使用它,因为它还处理缓存的图像。您可以在https://github.com/desandro/imagesloaded

找到它

您可以在整个图像列表中调用它,jQuery在使用时是可选的。

答案 5 :(得分:1)

DOM ready event等待DOM完全加载,然后再触发它的回调。但是load (window) event在DOM和所有图像完全加载之前不会触发它的回调。这是您要定位的事件:

$(window).load(function() { //Wait till DOM and images are fully loaded
                            //The run the code in here
    //**This is where/when to initialize the plugin.**
});
  

load事件在它和所有子元素发送到元素时发送   已完全装满。此事件可以发送到任何元素   与URL相关联:图像,脚本,框架,iframe和   窗口对象。