2011-03-22 69 views
2

比方说,我有以下HTML结构:jQuery按正确顺序插入元素vs detach()。sort()?

<ul> 
    <li>1</li> 
    <li>2</li> 
    <li>4</li> 
</ul> 

是否有可能(以及如何)以正确的顺序插入一个新的元素<li>3</li>没有分离的元素和诉诸?原因是,我相信如果你.detach()和.append()元素,你会导致页面重排(如果元素四处移动,我认为会发生)。但出于某种原因,将它插入正确的位置vs append/detach/sort/append似乎更清晰。

我见过jQuery中的第n个子选择器,我也正在使用underscore.js框架(它提供了_.sortedIndex,它告诉我元素的正确位置),但我似乎无法形象用正确的方式把它放在那里。

一些背景: 我正在与backbone.js工作,我有一个项目的集合。那么我假设我需要一个集合的视图(或集合中的每个项目的视图?)。当我将一个元素添加到集合中时,我设置了比较器,以便集合正确排序,但页面上的View未排序。

对于那些到达这里通过谷歌,这是我最终想出了在Backbone.js的:

Item = Backbone.Model.extend({}); 

ItemList = Backbone.Collection.extend({ 
    model: Item, 

    comparator: function(item) { 
     return item.get('id'); 
    } 
}); 

ItemView = Backbone.View.extend({ 
    tagName: 'li', 
    className: 'item', 

    initialize: function() { 
     _.bindAll(this, 'render'); 
     this.model.bind('change', this.render); 
     this.model.view = this; 
    }, 

    render: function() { 
     $(this.el).text(this.model.get('name')); 
     return this; 
    } 
}); 

App = Backbone.View.extend({ 
    el: $('#mylist'), 

    initialize: function() { 
     _.bindAll(this, 'add_one', 'add_all', 'render'); 

     this.items = new ItemList(); 
     this.items.bind('add', this.add_one); 
     this.items.bind('refresh', this.add_all); 
     this.items.bind('all', this.render); 

     this.items.add(new Item({id: 2, name: 'two'})); 
     this.items.add(new Item({id: 5, name: 'five'})); 
     this.items.add(new Item({id: 1, name: 'one'})); 
     this.items.add(new Item({id: 4, name: 'four'})); 
     this.items.add(new Item({id: 3, name: 'three'}));   
     this.items.add(new Item({id: 6, name: 'six'})); 
     this.items.add(new Item({id: 5.5, name: 'five.five'})); 
    }, 

    add_one: function(item) { 
     var view = new ItemView({model: item}); 
     var visible = this.$(view.tagName+'.'+view.className); 
     var newel = view.render().el; 
     var idx = this.items.indexOf(item); 
     if (visible.length == idx) { 
      $(this.el).append(newel); 
     } 
     else { 
      visible.eq(idx).before(newel); 
     } 
    }, 

    add_all: function() { 
     this.items.each(this.add_one); 
    } 
}); 

app = new App(); 

运行在这里:http://jsfiddle.net/dlamotte/L4j3b/

回答

0

你可以使用一个jQuery

$('li').eq(1).after('<li>3</li>'); 

小提琴页:http://jsfiddle.net/Hrjks/

更好:

var myindex = 3; 
var insertPoint = myindex -2; 
$('li').eq(insertPoint).after('<li>' + myindex +'</li>'); 

捣鼓这个:http://jsfiddle.net/Hrjks/1/

+0

可能需要一些错误检查索引界限。 – 2011-03-22 16:09:40

0

最近我有同样的问题,我固定用下面的函数。

function sortInsert(parent, element, fnc) { 
    var stack = parent.children().filter(function() { 
     return fnc($(this), element) > 0; 
    });  
    if (stack.length == 0) { 
     parent.append(element); 
    } else { 
     stack.first().before(element); 
    } 
} 

sortInsert($('ul'), $('<li>1</li>'), function(e, a) { 
    return parseInt(e.html()) - parseInt(a.html()); 
});​ 

它基本上得到的parent所有的孩子,然后做一个filter。如果你只需要比较它的值,你可以简单地通过避免回调来实现,但在我的情况下,它是需要的,因为我按照几个标准进行排序。

如果你想用一个降序排序只需更换append通过prependbefore通过lastfirstlast,它应该是工作。

随意在我的游乐场玩:http://jsfiddle.net/crodas/FMEkb/5/