Pregunta

Digamos que tengo la siguiente estructura html:

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

¿Es posible (y cómo) insertar un nuevo elemento <li>3</li> en el orden correcto sin separar los elementos y recurrir? La razón es que creo que si .detach () y .append () los elementos, provocará un reflujo de página (que supongo que sucedería de todos modos si los elementos se mueven). Pero por alguna razón, parece mucho más limpio insertarlo en el lugar correcto en lugar de agregar / separar / ordenar / agregar.

He visto el selector nth-child en jQuery y también estoy trabajando con el framework underscore.js (que proporciona _.sortedIndex que me dice la posición correcta del elemento), pero parece que no puedo entender la forma correcta de ponerlo allí.

Algunos antecedentes: Estoy trabajando con backbone.js y tengo una colección de elementos. Entonces supongo que necesito una Vista de la colección (¿o una vista por elemento de la colección?). Cuando agrego un elemento a la colección, tengo el comparador configurado para que la colección esté ordenada correctamente, pero la Vista en la página no está ordenada.

Para aquellos que llegan aquí a través de Google, esto es lo que finalmente se me ocurrió en 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();

Ejecútelo aquí: http://jsfiddle.net/dlamotte/L4j3b/

¿Fue útil?

Solución

puedes usar un jQuery

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

página de violín: http://jsfiddle.net/Hrjks/

Mejor aún:

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

violín para esto: http://jsfiddle.net/Hrjks/1/

Otros consejos

Tuve el mismo problema recientemente y lo solucioné con la siguiente función.

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

Básicamente se trata de obtener todos los elementos secundarios de parent, y luego hacer un filter.Si solo necesita comparar sus valores, puede hacerlo de manera simple evitando la devolución de llamada, pero en mi caso fue necesario ya que estaba ordenando según varios criterios.

Si desea ordenar con un orden descendente, simplemente reemplace append por prepend, before por last y first por last y debería estar funcionando.

Siéntete libre de jugar en mi patio de recreo: http://jsfiddle.net/crodas/FMEkb/5/

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top