将列表格式化为列的理想方法是啥,它们在垂直方向上保持字母顺序?

Posted

技术标签:

【中文标题】将列表格式化为列的理想方法是啥,它们在垂直方向上保持字母顺序?【英文标题】:What would be the ideal way to format a list into columns, where they remain alphabetical vertically?将列表格式化为列的理想方法是什么,它们在垂直方向上保持字母顺序? 【发布时间】:2016-09-09 23:40:22 【问题描述】:

假设有一个美国州列表,如下所示:

<ul>
    <li>Alabama</li>
    <li>Alaska</li>
    <li>Arizona</li>
    <li>Arkansas</li>
    <li>California</li>
    <li>Colorado</li>
    <li>Connecticut</li>
    <li>Delaware</li>
    <!-- and so on with all 50 -->
</ul>

只用 CSS 就可以很容易地将它们格式化为四列:

li float:left; width:25%;
li:nth-of-type(4n+5) clear:left;

这会创建四列,并确保第 5 项始终清除前面的元素。

但是,这将导致第一列以阿拉巴马州开头,第二个阿拉斯加州,第三个亚利桑那州和第四个阿肯色州。

相反,我试图找出使所有四列包含相对相等数量的状态的最佳方法(50 / 4 = 12.5,因此第 1 - 3 列将包含 13 个列表项,最后一列将包含剩余的11 个项目),同时第一列应包含 FIRST 13 个州(即阿拉巴马州 - 伊利诺伊州),第二列包含第 14 - 27 个州(印第安纳州 - 蒙大拿州),依此类推。

为此倾向于 jQuery,到目前为止,我已经做到了:

var list_items_count = $('li').length, // get the total number of list items
    even_list_math   = list_items_count / 4, // divide that by 4 columns
    even_list_amount = Math.ceil(even_list_math), // round the number up
    column_1_start   = 0, // it doesn't = 1 because 0 = 1
    column_2_start   = even_list_amount, // 1st item in column 2
    column_3_start   = even_list_amount * 2, // 1st item in column 3
    column_4_start   = even_list_amount * 3; // 1st item in column 4

    $('li').each(function(index, val) 
        if (index == column_1_start) 
            $(this).before('<li><ul>');
         else if (index == column_2_start || index == column_3_start || index == column_4_start) 
            $(this).before('</ul></li><li><ul>');
         else if (index == list_items_count) 
            $(this).after('</ul></li>');
        
    );

但是当我这样做时,jQuery 想要关闭我的元素。

所以而不是:

<ul>
    <li><ul> <!-- this should be created in the first $(this).before() statement -->
        <li>Alabama</li>
...
</ul>

jQuery 会自动关闭这些元素:

<ul>
    <li><ul></ul><li> <!-- the closing UL and LI tags shouldn't be here -->
        <li>Alabama</li>
...
</ul>

我可以阻止它这样做吗?还是我的 jQuery 有什么问题需要修复或优化?

编辑:虽然此示例显示了 50 个状态,但我正在使用的内容是动态的。所以它可能是一份包含 1000 种蔬菜、3 个国家、28 种挽留男人的方法等的清单。因此所有这些......

我也在尝试使用.wrap(),但还没有运气。

var li_elems = $('li'),
    li_arr = $.makeArray( li_elems );
    while(li_arr.length) 
        li_arr.splice(0,even_list_amount);
    
    $.each(li_arr, function(index, val) 
        $(this).wrap('<ul class="test"></ul>');
    );

【问题讨论】:

您不能将li 分成四个div,因为状态的数量是有限且已知的吗? @Marxtai,对不起,澄清了初始列表是动态的。它并不总是州或数字 50。 @Nathan jsfiddle.net/pcwbahyj 【参考方案1】:

您可以使用slicewrapAll 的组合。 Demo.

解决方案很简单。

$(function() 
    var items = $('#list > li'),
    count = items.length,
    columns = 4,
    perColumn = Math.ceil(count/columns);

  for(var i = 0; i < columns; i++) 
    items
      .slice(i*perColumn, (i+1)*perColumn) //group
      .wrapAll('<li class="column"><ul class="inner"/></li>') //wrap
  
)

或者,如果您不关心旧浏览器,您可以使用CSS3 multiple-columns layout。 Demo.

ul 
  column-count: 4; //important part
  margin: 0;
  padding: 0;

【讨论】:

完美的 jQuery 答案,感谢您提醒我有关 CSS3 列的信息!这可能是更简单的方法。 :)

以上是关于将列表格式化为列的理想方法是啥,它们在垂直方向上保持字母顺序?的主要内容,如果未能解决你的问题,请参考以下文章

存储 R 生成的大型结果的理想格式是啥?

MySQL需要帮助将垂直数据重新格式化为水平

word文档里面的文字垂直方向上如何居中?

如何将列表标签中的数字(通过 Combat)格式化为幂符号?

将动态范围的数据格式化为文本

matlab中plot(2,2)是啥意思