jQuery以正确的顺序插入元素vs detach()。sort()?

时间:2011-03-22 15:59:08

标签: javascript jquery backbone.js underscore.js

假设我有以下html结构:

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

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

我在jQuery中看到了nth-child选择器,我也在使用underscore.js框架(它提供_.sortedIndex告诉我元素的正确位置),但我不能似乎找到了把它放在那里的正确方法。

一些背景: 我正在使用backbone.js,我收集了一些项目。然后我假设我需要一个集合的视图(或集合中的每个项目的视图?)。当我向集合中添加一个元素时,我将比较器设置为正确排序集合,但页面上的视图未排序。

对于那些通过谷歌来到这里的人来说,这是我最终在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/

2 个答案:

答案 0 :(得分: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/

答案 1 :(得分: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替换为prepend,将before替换为last,将first替换为last,它应该工作。

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