-1

给定以下结构:

<ul>
    <li data-conference="Conference1" >Spain</li>
    <li data-conference="Conference1" >France</li>
    <li data-conference="Conference1" >Germany</li>
    <li data-conference="Conference1" >Italy</li>
    <li data-conference="Conference2" >Austria</li>
    <li data-conference="Conference2" >Poland</li>
    <li data-conference="Conference3" >Russia</li>
    <li data-conference="Conference3" >USA</li>
    <li data-conference="Conference3" >China</li>
</ul>

考虑到性能,将其重新排列成这样的最佳方法是什么(使用 jQuery):

<ul>
    <li>Spain</li>
    <li>France</li>
    <li>Germany</li>
    <li>Italy</li>
</ul>
<ul>
    <li>Austria</li>
    <li>Poland</li>
</ul>
<ul>
    <li>Russia</li>
    <li>USA</li>
    <li>China</li>
</ul>

谢谢!

4

6 回答 6

2

我认为整体问题(按属性分组元素)很好,您应该付出更多努力尝试自己解决。

无论如何,按属性对元素进行分组非常简单。您可以创建一个attribute value -> [element, ...]地图,这可以通过一个对象来完成:

var groups = {};

$('li[data-city]').each(function() {
    var attr = $(this).attr('data-city'),
        group = groups[attr];
    if(!group) {
        group = groups[attr] = [];
    }
    group.push(this);
});

现在你有了一个 DOM 元素列表的集合。您可以遍历集合并相应地创建 HTML 列表。

例如:

for(var group in groups) {
    var $list = $('<ul />');
    $list.append(groups[group]);
    // now append $list somewhere
}

查看Working with Objects [MDN]以获取有关如何处理对象的更多信息。

只要您有对元素的引用,例如作为NodeList. .each然后,您可以使用“正常”for循环来迭代该列表,而不是使用。

于 2012-05-06T12:45:41.773 回答
2

除非您在这些列表中有大量城市,否则我不会担心性能。我会考虑的唯一性能考虑是通过最小化对 DOM 的写入来避免重绘/重排。我认为在这个用例中代码的清晰性更为重要。

话虽这么说,我会用这样的东西来实现这个 - http://jsfiddle.net/XWufy/

于 2012-05-06T12:53:02.820 回答
1

干得好:

(function () {
    var $list = $( '#list' );
    var lists = {};
    var $newLists = $();

    $list.children().each( function () {
        var city = $( this ).data( 'city' );
        if ( !lists[ city ] ) lists[ city ] = [];
        lists[ city ].push( this );
    });

    $.each( lists, function ( city, items ) {
        var $newList = $( '<ul />' ).append( items );
        $newLists = $newLists.add( $newList );
    });

    $list.replaceWith( $newLists );            
}());

现场演示:http: //jsfiddle.net/rjt9W/6/

顺便说一句,代码假定列表的 ID 为"list". 替换此行中的选择器

var $list = $( ... );

以便它正确选择您的 UL 元素。

于 2012-05-06T13:08:47.190 回答
0

使用 data 属性作为对象属性对它们进行排序,然后循环它们以构造新的 html。这应该让你开始:

var list = {};
// for each item
list[item.data('city')] = item.text();

// for each property of list
var ul = $('<ul>');
// for each listItem in current list
var li = $('<li>').text(listItem);
ul.append(li);
于 2012-05-06T12:42:28.950 回答
0

试试这个:

var list = [];
var $div = $('#my_container_div');

$('li[data-city]').each(function() {
   var $this = $(this), data = $this.attr('data-city');
   list[ data ] = list[ data ] || [];
   list[ data ].push( $this.text() );
});

for(var data in list) {
   var $ul = $div.append('<ul/>');
   for(var li in list[data]) {
      $ul.append('<li>' + list[data][li] + '</li>');
   }
}
于 2012-05-06T12:57:16.537 回答
0

试试这个:

<ul id="first"></ul>// you can create the ul tags by using JavaScript

$("li").each(function(){
      data  = $(this).attr("data");
      if (data == "Conference1") {
         txt = $(this).text();
         $("<li>" + txt + "</li>").appendTo("ul#first");
      }
})
于 2012-05-06T12:58:25.277 回答