将列表格式化为列的理想方式是什么,它们在垂直方向上保持字母顺序?
What would be the ideal way to format a list into columns, where they remain alphabetical vertically?
假设有一个 U.S 的列表。状态,像这样:
<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 项),同时,第一列应包含前 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>');
});
您可以使用 slice
and wrapAll
. 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;
}
假设有一个 U.S 的列表。状态,像这样:
<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 项),同时,第一列应包含前 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>');
});
您可以使用 slice
and wrapAll
. 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;
}