jQuery根据数据属性包装元素的最佳方法是什么?

时间:2012-05-06 12:34:07

标签: javascript jquery performance algorithm

鉴于以下结构:

<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>

谢谢!

6 个答案:

答案 0 :(得分: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]以获取有关如何处理对象的更多信息。

在没有jQuery的情况下执行此操作也很简单,只要您有对元素的引用,例如NodeList。您可以使用“普通”.each循环来迭代该列表,而不是使用for

答案 1 :(得分:2)

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

话虽如此,我会用这样的方式实现这一点 - http://jsfiddle.net/XWufy/

答案 2 :(得分: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元素。

答案 3 :(得分: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);

答案 4 :(得分: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>');
   }
}

答案 5 :(得分: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");
      }
})