按位置分组元素

时间:2011-09-15 16:33:25

标签: jquery position

#gal容器加载了大量图像(~60),所有图像都具有定义的CSS高度(100px)和边距5px;

              

现在,从逻辑上讲,图像宽度可能会有所不同,当所有图像都可见时,我们无法计算相同数量的图像 - 每个'线',因为如果没有适合{{1}的空间,它们都会向下浮动} width:

#gal

如何将| ___ __ _____ _ | <--- the #gal with images inside | __ ______ | | ______ _ __ __ | | __ ______ | | _______ ____ _ | 中的所有图像分组到第一行(第二...第三...)?

所以这是第一个想法:   - 加载页面并定位图像后 - 我们可以按照wrap()

对所有图像进行分组
.position().top

EXAMPLE

有什么想法吗?

4 个答案:

答案 0 :(得分:4)

尝试这样的事情:

var div = $('<div />'); // The current working div
var pos = $('#gal img').position().top; // The position of the first image

$('#gal img').each(function(){
    // If the next image has a different position from the one before it
    // then add the working div to #gal and create a new working div.
    if (pos != $(this).position().top) {
        $('#gal').append(div);
        div = $('<div />');  
    }

    // Append a cloned copy of the image to the working div.
    // This is important: we don't want to move the image
    // because it will reflow the other images and mess up
    // the rows.
    div.append($(this).clone());

    // Set the new position
    pos = $(this).position().top;
});

// Now remove all of the old images
$('#gal > img').remove();

小提琴:http://jsfiddle.net/PuqZe/1/

答案 1 :(得分:2)

您可以尝试这样的事情:

var groups = {};

$('#gal img').each(function(){
    var pos = $(this).position().top;
    if(typeof groups[pos] == 'undefined')
    {
        groups[pos] = [];
    }
    groups[pos].push(this);
});

$.each(groups, function (pos, elements) {
    $('#gal').append('<div id="wrapper_'+pos+'" class="wrapper"></div>');
    var wrapper = $('#gal #wrapper_'+pos);
    $.each(elements, function () {
        wrapper.append(this);
    });
});

它将在包装div中包含顶部相同位置的所有图像。

答案 2 :(得分:1)

这样做:http://jsfiddle.net/ebiewener/kr57a/2/

var gal = $('#gal');

gal.children('img').each(function(){
    var el = $(this);
    el[0].Pos = el.position().top;
})
.each(function(){
    var el = $(this);
    var rowWrapper = gal.children('.group' + el[0].Pos);
    if(rowWrapper.length === 0){
        el.wrap('<div class="wrapper group' + el[0].Pos + '"></div>');
    }else{
        el.appendTo(rowWrapper);
    }
});

我们循环两次图像。第一次获取它们的位置,将其作为属性存储在HTML元素对象(el [0])上。第二个循环进行包装。我们需要两个循环的原因是因为包装会影响同一行中其他未包装元素的位置,导致它们不会被该行中的第一个元素包裹。

答案 3 :(得分:0)

  • 创建一个函数,该函数使用jQuery's Object Element creator返回".wrapper"元素。
  • 单循环内部,检查.next()元素的位置是否大于当前位置。
    如果为true,则使用{将 last-known-index current index + 1 范围内的一组元素传递给$wrap()函数{1}}。
  • 将生成的包装器元素插入and数组中,一旦完成工作,将该数组附加到.slice()父对象中。

#gal
const wrapGalImg = () => {

  const $el = $('#gal img'),
    $wrap = ($ch) => $('<div>', {'class':'wrapper', append:$ch}),
    wraps = []; // Array of wrapper elements with children
  let i = 0;

  $el.each((ei, ele) => {
    const $next = $(ele).next();
    if($next[0] && $next.position().top == $(ele).position().top) return;
    wraps.push($wrap($el.slice(i, ei+1)));
    i = ei+1;
  });
  
  $('#gal').append( wraps ); // Append all wrappers. Once.

}

$(window).on('load', wrapGalImg);
*{margin: 0;}

#gal img {
  vertical-align: top;
  height: 60px;
}

.wrapper {
  background: #f00;
  margin: 1px 0;
}


因此,不需要多个循环,克隆或删除元素。