Cambiando el orden de divs para posicionamiento con float

Tengo un montón de divs que el área flotará a la izquierda para que se sienten uno al lado del otro en filas que llenan una página. Quiero cambiar el orden en que están programáticamente y aún así hacer que floten.

Tengo una pieza de JS que escribí que toma el desplazamiento de cada cuadro, les da una posición fija (usando el desplazamiento para que permanezcan en su lugar) y luego los anima a uno de los otros desplazamientos. Mi problema es que ahora necesito volver a convertirlos del posicionamiento absoluto al posicionamiento flotante. Hacer esto obviamente los revierte a como eran originalmente.

Lo que necesito saber es si es posible establecer el índice de cada div, por lo que podría asociar un desplazamiento con un índice y actualizar cada desplazamiento e índice de div para que cuando floten permanezcan en su lugar. ¿Hay alguna manera de establecer el índice de elementos DOM usando jQuery?

preguntado el 04 de julio de 12 a las 10:07

3 Respuestas

No desea establecer su índice, per se; quiere cambiar literalmente su orden en su contenedor.

Esto es fácil (con el DOM o con jQuery): si desea mover un elemento frente a su hermano anterior, use insertBfore prev:

var elm = $("selector_for_the_element");
elm.insertBefore(elm.prev());

...o después de su próximo hermano, use insertAfter next:

var elm = $("selector_for_the_element");
elm.insertAfter(elm.next());

Presumiblemente, haría esto cuando termine de animar, volviendo los divs a flotar en lugar de posicionarse absolutamente.

Ejemplo vivo | fuente

HTML:

<div id="container"></div>

CSS:

#container div {
  float: left;
  width: 4em;
  border: 1px solid black;
  margin: 2px;
  padding: 2px;
}
.left, .right {
  cursor: pointer;
  font-weight: bold;
  font-size: 14pt;
  background-color: #eee;
  border: 1px solid #aaa;
}

JavaScript:

jQuery(function($) {

  var container = $("#container");
  var index;

  for (index = 0; index < 10; ++index) {
    $("<div>d" + index +" <span class='left'>&lt;</span> <span class='right'>&gt;</span></div>")
      .appendTo(container)
      .attr("id", "d" + index);
  }

  container.delegate(".left", "click", function() {
    var div = $(this).closest("div"),
        prev = div.prev();
    if (prev[0]) {
      div.insertBefore(prev);
    }
  });
  container.delegate(".right", "click", function() {
    var div = $(this).closest("div"),
        next = div.next();
    if (next[0]) {
      div.insertAfter(next);
    }
  });

});

Respondido 04 Jul 12, 10:07

@ T.JCrowder, ¿no necesitaría cambiar su posicionamiento de absoluto a estático? - Kevin Bowersox

@kmb385: Por supuesto, lo tomé como leído. Lo he hecho explícito ahora. - TJ Crowder

Eso se ve perfecto; Gracias. La única pregunta es algo que olvidé mencionar: los divs se animarán a posiciones aleatorias (aunque preestablecidas), por lo que no estoy seguro de cómo lograrlo con solo insertar antes e insertar después. ollie

@ollie: Puedes usar offset y width para averiguar cuál de los hermanos del elemento se superpone, lo que le indica dónde moverlo. Por ejemplo, si el left de tu elemento animado es 250, encuentra el hermano que tiene left <= 250 y (left + width) > 250. Entonces usa insertBefore para encajar el elemento animado en su lugar antes que ese hermano. - TJ Crowder

Lo siento, marqué esta pregunta como sin respuesta porque esta solución no funcionó para mí, ya que tengo miles de elementos y hace que el navegador se agote el tiempo de espera. ollie

Antes de comenzar su animación que reorganiza los divs, ¿podría almacenar sus posiciones e identificaciones originales en una matriz de objetos? Luego, ¿tiene una función que itera a través de los objetos en esa matriz llamando a una animación con sus posiciones originales como coordenadas?

Ejemplo de trabajo: http://jsfiddle.net/JpVS4/3/

HTML:

<div class="moving">Item 1</div>
<div class="moving">Item 2</div>
<div class="moving">Item 3</div>
<div id="move-back">Click to Move To Orignal Pos</div>

CSS:

.moving{
    width: 100px;
    float:left;
}


#move-back{
    position: absolute;
    top: 200px;
    border: 1px solid lightgray;
}

JavaScript:

var originalPos =[];

//Store Original

    $(".moving").each(function(){
        originalPos.push({"left":$(this).position().left,"top":$(this).position().top});
    });

    //rearrange
    $(".moving").each(function(i,e){
        $(this).css("position", "absolute");
        $(this).css("left",100 * ((3-i)-1));                
    });


    //move back to original - if needed you could also set top
    $("#move-back").click(function(){
        $(".moving").each(function(i,e){
            var position = originalPos[i];
            $(this).css("left",originalPos[i].left);                
        });
    });

Respondido 04 Jul 12, 11:07

Al final, modifiqué la solución a esta pregunta para satisfacer mis necesidades y funcionó muy bien:

Aleatorizar una secuencia de elementos div con jQuery

Muchas gracias a la ayuda de TJ Crowder

contestado el 23 de mayo de 17 a las 13:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.