2010-05-31 21 views
13

Estoy usando JavaScript clásico para secuencias de comandos DOM, tengo un conjunto de DIV en un contenedor DIV. El evento click del niño DIV, quiero que el DIV niño que ha causado evento que se swaped con el DIV por encima de ella .. mi código va aquí ..Cómo intercambiar elementos HTML en javascript?

<div id="container"> 
     <div onclick="swapDiv(event);">1</div> 
     <div onclick="swapDiv(event);">2</div> 
     <div onclick="swapDiv(event);">3</div> 
</div> 

si DIV 2 ha hecho click en lo que debería ser swap con DIV 1

+1

Y si se hace clic en div 1? –

+0

si div es 1, entonces no se intercambian ... –

+0

¿se intercambian solo los contenidos o los elementos completos? – karim79

Respuesta

12

Este código hará lo que quiera (si desea cambiar el elemento seleccionado con el primer elemento hijo). En caso de que quieras algo más, debes ser más preciso.

<script type="text/javascript"> 

function swapDiv(event,elem){ 
    elem.parentNode.insertBefore(elem,elem.parentNode.firstChild); 
} 

</script> 


<div id="container"> 
     <div onclick="swapDiv(event,this);">1</div> 
     <div onclick="swapDiv(event,this);">2</div> 
     <div onclick="swapDiv(event,this);">3</div> 
</div> 
+0

Sí, eso es casi lo mismo que pensé, pero no lo hace siempre quiero ponerlo primero, quiere ponerlo encima del div antes que él. Entonces el 'previousSibling'.Es un buen comienzo para él aunque. – CharlesLeaf

+0

en este código, cuando hace clic en DIV 3, el DIV 3 intercambia con DIV 1 en lugar de DIV 2 .. –

+0

sí! con previousSibling, funciona ... –

2

A partir de los sonidos de la misma que, básicamente, sólo quieren intercambiar el div con el div ante sí, ergo con el previousSibling. Podrías mirar haciendo un insertBefore pero en vez de crear un nuevo elemento usa el existente. No estoy seguro de qué pasa con los eventos adjuntos, si se copiarán correctamente.

+1

'previousSibling' generalmente será un nodo de texto en blanco (excepto en IE). – bobince

+1

cierto, pero entonces simplemente pruebe el nodeType, y si es 3 obtenga 'previousSibling' (si está disponible) hasta que encuentre uno de nodeType 1. Eso no es demasiado difícil. – CharlesLeaf

15

La propiedad parentNode de un elemento le proporciona su nodo primario. Los elementos tienen una función insertBefore que inserta un elemento antes de otro elemento de referencia (moviéndolo si ya está en otra parte del árbol). Y los nodos tienen un previousSibling que le proporciona el nodo hermano anterior (que puede o no ser un elemento). Por lo tanto:

function swapDiv(elm) { 
    var previous = findPrevious(elm); 
    if (previous) { 
     elm.parentNode.insertBefore(elm, previous); 
    } 
} 

... donde findPrevious se parece a esto:

function findPrevious(elm) { 
    do { 
     elm = elm.previousSibling; 
    } while (elm && elm.nodeType != 1); 
    return elm; 
} 

... onclick donde sus atributos deben ser:

onclick="swapDiv(this);" 

... aunque es posible que desee mire en su lugar el enganche al evento DOM2 (addEventListener, o attachEvent en IE).

Ligeramente OT, pero puedo recomiendo el uso de cualquiera de las varias bibliotecas disponibles que hacen la vida más fácil, como Prototype, jQuery, Closure o any of several others. De hecho, hubo un error en una versión anterior de esto porque había sido que desde que había tratado el DOM directamente. :-)

+0

Esto es más o menos lo que ya se ha respondido, pero te estoy votando porque das una buena respuesta completa. – CharlesLeaf

+0

sí! totalmente a prueba de balas ... –

+0

Justo lo que estaba buscando – jing3142

2

En principio, solo insertBefore ha hecho clic en su elemento antes que su elemento anterior. Sin embargo, la presencia de nodos de texto en espacios en blanco lo hace más molesto de lo que debería ser en las secuencias de comandos tradicionales. El Element Traversal API hará que esto sea más fácil, pero hasta que no es más ampliamente apoyada en los navegadores, funciones de ayuda son necesarios, por ejemplo .:

<div id="container"> 
    <div>1</div> 
    <div>2</div> 
    <div>3</div> 
</div> 

<script type="text/javascript"> 
    // Bind event to each line div 
    // 
    var div= firstElementChild(document.getElementById('container')); 
    while (div!==null) { 
     div.onclick= swapWithPreviousElement; 
     div= nextElementSibling(div); 
    } 

    // Move element before its previous element sibling 
    // 
    function swapWithPreviousElement() { 
     var previous= previousElementSibling(this); 
     if (previous!==null) 
      this.parentNode.insertBefore(this, previous); 
    } 


    // We've used some Element Traversal API methods but some 
    // browsers don't support them yet. Provide wrapper functions 
    // for compatibility. 
    // 
    function previousElementSibling(element) { 
     if ('previousElementSibling' in element) 
      return element.previousElementSibling; 
     do 
      element= element.previousSibling; 
     while (element!==null && element.nodeType!==1); 
     return element; 
    } 
    function nextElementSibling(element) { 
     if ('nextElementSibling' in element) 
      return element.nextElementSibling; 
     do 
      element= element.nextSibling; 
     while (element!==null && element.nodeType!==1); 
     return element; 
    } 
    function firstElementChild(element) { 
     if ('firstElementChild' in element) 
      return element.firstElementChild; 
     var child= element.firstChild; 
     while (child!==null && child.nodeType!==1) 
      child= child.nextSibling; 
     return child; 
    } 
</script> 
0

Intercambiar los nodos, no hermanos, los hermanos no adjecent, no hay nodos temporales, sin clonación, no jquery ... IE9 +

function swapNodes(n1, n2) { 

    var p1 = n1.parentNode; 
    var p2 = n2.parentNode; 
    var i1, i2; 

    if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return; 

    for (var i = 0; i < p1.children.length; i++) { 
     if (p1.children[i].isEqualNode(n1)) { 
      i1 = i; 
     } 
    } 
    for (var i = 0; i < p2.children.length; i++) { 
     if (p2.children[i].isEqualNode(n2)) { 
      i2 = i; 
     } 
    } 

    if (p1.isEqualNode(p2) && i1 < i2) { 
     i2++; 
    } 
    p1.insertBefore(n2, p1.children[i1]); 
    p2.insertBefore(n1, p2.children[i2]); 
} 
Cuestiones relacionadas