Frage

Angenommen, ich habe die folgende HTML-Struktur:

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

Ist es möglich (und wie), einen neuen <li>3</li> für Elemente in der richtigen Reihenfolge einzufügen, ohne die Elemente zu trennen und neu zu greifen? Grund dafür ist, ich glaube, wenn Sie .detach () und .append () die Elemente, werden Sie einen Seiten-Reflow verursachen (was vermutlich sowieso passieren würde, wenn sich die Elemente bewegen). Aber aus irgendeinem Grund scheint es viel sauberer zu sein, es an der richtigen Stelle einzufügen, als anhängen / trennen / sortieren / anhängen.

Ich habe den n-ten untergeordneten Selektor in jQuery gesehen und arbeite auch mit dem underscore.js-Framework (das _.sortedIndex bereitstellt, das mir die korrekte Position des Elements angibt), aber ich kann es nicht herausfinden der richtige Weg, um es dort zu platzieren.

Hintergrund: Ich arbeite mit backbone.js und habe eine Sammlung von Elementen. Dann gehe ich davon aus, dass ich eine Ansicht der Sammlung benötige (oder eine Ansicht pro Element in der Sammlung?). Wenn ich der Sammlung ein Element hinzufüge, ist der Komparator so eingestellt, dass die Sammlung ordnungsgemäß sortiert ist, die Ansicht auf der Seite jedoch nicht sortiert ist.

Für diejenigen, die über Google hierher kommen, habe ich mir in backbone.js Folgendes ausgedacht:

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();

Führen Sie es hier aus: http://jsfiddle.net/dlamotte/L4j3b/

War es hilfreich?

Lösung

Sie können eine jQuery verwenden

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

Geigen-Seite: http://jsfiddle.net/Hrjks/

Besser noch:

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

Geige dafür: http://jsfiddle.net/Hrjks/1/

Andere Tipps

Ich hatte kürzlich das gleiche Problem und habe es mit der folgenden Funktion behoben.

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()); 
} );​

Grundsätzlich wird das gesamte Kind von parent abgerufen und anschließend ein filter erstellt.Wenn Sie nur die Werte vergleichen müssen, können Sie dies einfach tun, indem Sie den Rückruf vermeiden. In meinem Fall wurde er jedoch benötigt, da ich nach mehreren Kriterien sortiert habe.

Wenn Sie mit absteigender Reihenfolge sortieren möchten, ersetzen Sie einfach append durch prepend, before durch last und first für last und es sollte funktionieren.

Sie können gerne auf meinem Spielplatz spielen: http://jsfiddle.net/crodas/FMEkb/5/

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top