同位素:加载后附加每个图像(按时间顺序)

Isotope: append each image after loading (in chronological order)

几天前,我尝试将 Isotope 合并到我的网站中,并将其与 Fancybox 2 结合以创建一个具有 filtering/sorting 可能性的漂亮画廊。由于许多页面包含大量图像,我更喜欢在完成加载后直接显示和附加每个图像,而不是在加载所有图像之前显示加载器。

为了实现这一点,到目前为止我想出了这段代码:

    $( function() {
  // init isotope  
  var $container = $('.isotope_container').isotope({
    itemSelector: '.isotope_image',
    layoutMode: 'fitRows',
    transitionDuration: '0.7s'
  });

// reveal initial images
$container.isotopeImagesReveal($('#images_container').find('.isotope_image'));
});

$.fn.isotopeImagesReveal = function( $items ) {
  var iso = this.data('isotope');
 var itemSelector = iso.options.itemSelector;
  // hide by default
  $items.hide();
  // append to container
  this.append( $items );
  $items.imagesLoaded().progress( function( imgLoad, image ) {
    // get item
    // image is imagesLoaded class, not <img>, <img> is image.img
    var $item = $( image.img ).parents( itemSelector );
    // un-hide item
    $item.show();
    // isotope does its thing
    iso.appended( $item );
  });

  return this;
};

});

上面的代码在某种程度上已经完成了我所追求的。它 'pulls' 最初出现在 <div id='images_container'> 中的图像,并在图像完成加载后将一个项目附加到同位素。然而,问题是代码附加和显示图像 按照它们完成加载的顺序 (首先加载的图像在网格中变为 #1,然后是 #2 等)。将 sortby 参数添加到同位素选项不起作用,因为在启动同位素时未加载图像。在以这种方式附加所有图像后,用同位素对它们重新排序是可能的,但看起来非常混乱。

我想要实现的是让图像 按照它们在 <div id='images_container'> 中出现的顺序加载。可以说,按时间顺序排列原始文档顺序。所以基本上开始加载图像 1,加载后显示并附加它。然后进行图2,loading后show和append等等,直到处理完所有图片。

我认为解决方案是更改 $.fn.isotopeImagesReveal 函数以按时间顺序处理每个 div 项目,但我不知道该怎么做。

更新:添加了当前代码的示例。 http://codepen.io/micksanders/pen/KwXmwO

首先,您需要在标记中添加一个排序字段。我向所有具有 .isotope_image class 的元素添加了一个 data-order="xxxx" 属性,如下所示:

<div class='isotope_image' data-order="1">
<p>1</p>
<img src='http://lorempixel.com/600/600/sports'>
</div>
...

然后您需要将该排序字段添加到您的同位素初始化代码中...需要 getSortDatasortBy 选项:

var $container = $('.isotope_container').isotope({
    itemSelector: '.isotope_image',
    layoutMode: 'fitRows',
    transitionDuration: '0.7s',
    getSortData: {
      order: "[data-order]"
    },
    sortBy: 'order'
  });

最后在 imagesLoaded.progress() 函数的末尾,使用 iso.insert($item) 而不是 iso.appended($item)

这里是修改后的完整代码: http://codepen.io/BenStevens/pen/MYEmBb

$( function() {

  var $container = $('#container').isotope({
    itemSelector: '.item',
    masonry: {
      columnWidth: 200  
    }
  });

  $('#load-images').click( function() {
    var $items = getItems();
    $container.isotopeImagesReveal( $items );
  });

});

$.fn.isotopeImagesReveal = function( $items ) {
  var iso = this.data('isotope');
  var itemSelector = iso.options.itemSelector;
  // hide by default
  $items.hide();
  // append to container
  this.append( $items );
  $items.imagesLoaded().progress( function( imgLoad, image ) {
    // get item
    // image is imagesLoaded class, not <img>, <img> is image.img
    var $item = $( image.img ).parents( itemSelector );
    // un-hide item
    $item.show();
    // isotope does its thing
    iso.appended( $item );
  });

  return this;
};

function randomInt( min, max ) {
  return Math.floor( Math.random() * max + min );
}

function getItem() {
  var width = randomInt( 150, 400 );
  var height = randomInt( 150, 250 );
  var item = '<div class="item">'+
    '<img src="http://lorempixel.com/' + 
      width + '/' + height + '/nature" /></div>';
  return item;
}

function getItems() {
  var items = '';
  for ( var i=0; i < 12; i++ ) {
    items += getItem();
  }
  // return jQuery object
  return $( items );
}

See reveal each image as they load