您能简化并概括这个有用的 jQuery 函数吗?

发布于 2024-08-29 03:38:57 字数 2445 浏览 5 评论 0原文

我正在做一个网上商店,商品像往常一样在网格中显示为“图块”。我只想使用各种尺寸的图块并确保(通过 jQuery)没有可用空间。

在基本情况下,我有一个 960px 包装器,想要使用 240x180px(类 .grid_4)图块和 480x360px(类 .grid_8)图块。查看图像(想象那里没有边距/填充):

替代文本 http://img580.imageshack .us/img580/2828/screenshot2010041508h52.png

没有 jQuery 的问题:

  • 当 CMS 提供大图块为第 6 个时,第 5 个图块下方会有一个可用空间
  • 当 CMS 提供大图块为第 7 个时,会出现 第 5 和第 6 下有一个可用空间
  • 当 CMS 提供第 8 个大图块时,

,它将移动到下一行,使第 8 号位置空闲我的解决方案到目前为止看起来像这样:

$(".grid_8").each(function(){
        //console.log("BIG on position "+($(this).index()+1)+" which is "+(($(this).index()+1)%2?"ODD":"EVEN"));

        switch (($(this).index()+1)%4) {

            case 1:
                // nothing needed
                //console.log("case 1");
                break;

            case 2:
                //need to shift one position and wrap into 240px div
                //console.log("case 2");
                $(this).insertAfter($(this).next()); //swaps this with next
                $(this).prevAll(":nth(0), :nth(1)").wrapAll("<div class=\"grid_4\" />");

                break;

            case 3:
                //need to shift two positions and wrap into 480px div
                //console.log("case 3");
                $(this).prevAll(":nth(0), :nth(1)").wrapAll("<div class=\"grid_4\" />"); //wraps previous two - forcing them into column 
                $(this).nextAll(":nth(0), :nth(1)").wrapAll("<div class=\"grid_4\" />"); //wraps next two - forcing them into column
                $(this).insertAfter($(this).next()); //moves behind the second column
                break;

            case 0:
                //need to shift one position
                //console.log("case 4");
                $(this).insertAfter($(this).next());
                //console.log("shifted to next line");
                break;

        }

    }); 

从评论中应该可以明显看出它是如何工作的 -一般来说,如果需要的话,总是通过向后移动一个位置来确保大块位于奇数位置(前面的小块的数量是偶数)。此外,大块左侧的小块需要包裹在另一个 div 中,以便它们出现在列而不是行中。

现在最后的问题是:

  • 如何概括该函数,以便我可以使用更多的图块尺寸,如 720x360 (3x2)、480x540 (2x3) 等?
  • 有没有办法简化功能?
  • 在检查实际位置时,我需要确保大图块算作小图块的倍数。因为在位置 12 上的图块(第三行中的最后一个图块)上使用 index() 现在将返回 7(位置 8),因为位置 5 和 9 上的图块被包装在一起在一列中,并且大图块也只是一个 div,但跨越 2x2 位置。有什么干净的方法来确保这一点吗?

非常感谢您的任何提示。请随意重用该代码,我认为它很有用。

约瑟夫

I'm doing an eshop with goods displayed as "tiles" in grid as usual. I just want to use various sizes of tiles and make sure (via jQuery) there are no free spaces.

In basic situation, I have a 960px wrapper and want to use 240x180px (class .grid_4) tiles and 480x360px (class .grid_8) tiles. See image (imagine no margins/paddings there):

alt text http://img580.imageshack.us/img580/2828/screenshot2010041508h52.png

Problems without jQuery:

  • when the CMS provides the big tile as 6th, there would be a free space under the 5th one
  • when the CMS provides the big tile as 7th, there would be a free space under 5th and 6th
  • when the CMS provides the big tile as 8th, it would shift to next line, leaving position no.8 free

My solution so far looks like this:

$(".grid_8").each(function(){
        //console.log("BIG on position "+($(this).index()+1)+" which is "+(($(this).index()+1)%2?"ODD":"EVEN"));

        switch (($(this).index()+1)%4) {

            case 1:
                // nothing needed
                //console.log("case 1");
                break;

            case 2:
                //need to shift one position and wrap into 240px div
                //console.log("case 2");
                $(this).insertAfter($(this).next()); //swaps this with next
                $(this).prevAll(":nth(0), :nth(1)").wrapAll("<div class=\"grid_4\" />");

                break;

            case 3:
                //need to shift two positions and wrap into 480px div
                //console.log("case 3");
                $(this).prevAll(":nth(0), :nth(1)").wrapAll("<div class=\"grid_4\" />"); //wraps previous two - forcing them into column 
                $(this).nextAll(":nth(0), :nth(1)").wrapAll("<div class=\"grid_4\" />"); //wraps next two - forcing them into column
                $(this).insertAfter($(this).next()); //moves behind the second column
                break;

            case 0:
                //need to shift one position
                //console.log("case 4");
                $(this).insertAfter($(this).next());
                //console.log("shifted to next line");
                break;

        }

    }); 

It should be obvious from the comments how it works - generally always makes sure that the big tile is on odd position (count of preceding small tiles is even) by shifting one position back if needed. Also small tiles to the left from the big one need to be wrapped in another div so that they appear in column rather than row.

Now finally the questions:

  • how to generalize the function so that I can use even more tile dimensions like 720x360 (3x2), 480x540 (2x3), etc.?
  • is there a way to simplify the function?
  • I need to make sure that big tile counts as a multiple of small tiles when checking the actual position. Because using index() on the tile on position 12 (last tile in 3rd row) would now return 7 (position 8) because tiles on positions 5 and 9 are wrapped together in one column and the big tile is also just a single div, but spans 2x2 positions. Any clean way to ensure this?

Thank you very much for any hints. Feel free to reuse the code, I think it can be useful.

Josef

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

难理解 2024-09-05 03:38:57

听起来你需要使用名为 masonry 的 jQuery 插件。

您可以在此处找到它

Sounds like you need to use the jQuery plugin called masonry.

You can find it here

埖埖迣鎅 2024-09-05 03:38:57

这对您来说足够简单吗?

$(".grid_8")
.each(function () {
switch (($(this)
    .index() + 1) % 4) {
    case 1:
        break;
    case 2:
        $(this)
            .insertAfter($(this)
            .next()), $(this)
            .prevAll(":nth(0), :nth(1)")
            .wrapAll('<div class="grid_4" />');
        break;
    case 3:
        $(this)
            .prevAll(":nth(0), :nth(1)")
            .wrapAll('<div class="grid_4" />'), $(this)
            .nextAll(":nth(0), :nth(1)")
            .wrapAll('<div class="grid_4" />'), $(this)
            .insertAfter($(this)
            .next());
        break;
    case 0:
        $(this)
            .insertAfter($(this)
            .next())
}
})

Is this simplified enough for you?

$(".grid_8")
.each(function () {
switch (($(this)
    .index() + 1) % 4) {
    case 1:
        break;
    case 2:
        $(this)
            .insertAfter($(this)
            .next()), $(this)
            .prevAll(":nth(0), :nth(1)")
            .wrapAll('<div class="grid_4" />');
        break;
    case 3:
        $(this)
            .prevAll(":nth(0), :nth(1)")
            .wrapAll('<div class="grid_4" />'), $(this)
            .nextAll(":nth(0), :nth(1)")
            .wrapAll('<div class="grid_4" />'), $(this)
            .insertAfter($(this)
            .next());
        break;
    case 0:
        $(this)
            .insertAfter($(this)
            .next())
}
})
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文