Cómo alternar elementos dentro y fuera de DOM utilizando el método jQuery detach ()?

Tengo un grupo de divs dispuestos en una grilla.

enter image description here

Para darle un estilo a cada div, los estoy seleccionando con la nth-child() .

 div.tile:nth-child(4n-7) .text { background-color: yellow; } 

Un usuario puede ocultar divs haciendo clic en un botón (que activa una función jQuery que agrega una regla display: none al atributo de class en el div seleccionado).

jQuery

 $('.hide-divs').click(function () { $('.dolphin').toggleClass('hidden'); }) 

CSS

 .hidden { display: none; } 

Aquí está el problema:

Aunque display: none elimina el div de la pantalla, no elimina el div del DOM, por lo que el selector nth-child aún lo cuenta cuando aplica estilos, lo que a su vez altera el diseño visual de la grilla.

enter image description here

El diseño anterior está roto porque solo la primera columna debe ser amarilla.

Así que mi primer pensamiento fue utilizar el método jQuery remove() , que toma elementos (y sus descendientes) del DOM.

Resulta que, sin embargo, una vez que se aplica remove() no se pueden recuperar esos divs. Se fueron. Entonces la función de alternancia se rompe.

Después de un poco de investigación, descubrí el método jQuery detach() , que hace lo mismo que .remove() , excepto que almacena los datos de los elementos eliminados para su uso posterior.

Desde el sitio web de jQuery :

El método .detach() es el mismo que .remove() , excepto que .detach() mantiene todos los datos jQuery asociados con los elementos eliminados. Este método es útil cuando los elementos eliminados deben reinsertarse en el DOM en un momento posterior.

Todo se ve bien para que detach() funcione con el interruptor de palanca, excepto que mis esfuerzos para implementarlo no están funcionando.

He usado el ejemplo en el sitio web de jQuery como guía, pero no funciona en la cuadrícula. También leí varias publicaciones relacionadas en este sitio, pero fue en vano. Debo estar perdiendo algo.

Cualquier comentario sería muy apreciado.

http://jsfiddle.net/tfyfpbb2/

 $('.hide-divs').click(function() { $('.dolphin').toggleClass('hidden'); }) 
 .row { display: flex; flex-wrap: wrap; width: 500px; padding: 0; margin: 0; } .text { height: 50px; width: 100px; margin: 10px; padding-top: 15px; background: tomato; color: #fff; text-align: center; font-size: 2em; } .tile:nth-child(4n-7) .text { border: 2px solid #ccc; background-color: yellow; color: #000; } button { padding: 10px; background-color: lightblue; position: relative; left: 200px; } .hidden { display: none; } 
  
01
02
03
04
05
06
07
08
09
10
11
12

Sugiero seguir usando separar. Puedes hacerlo con este código:

 var divs; $('.hide-divs').on('click', function () { if(divs) { $(divs).appendTo('.row'); divs = null; } else { divs = $('.dolphin').parent().detach(); } }); 

Luego, para garantizar que se usa el mismo orden, se me ocurrió este pequeño código:

 $('.tile').each(function(i){ $(this).data('initial-index', i); }); ... $(divs).each(function(){ var oldIndex = $(this).data('initial-index'); $('.tile').eq(oldIndex).before(this); }); 

Ponlo todo junto y obtenemos este código:

 var divs; $('.tile').each(function(i){ $(this).data('initial-index', i); }); $('.hide-divs').on('click', function () { if(divs) { $(divs).appendTo('.row').each(function(){ var oldIndex = $(this).data('initial-index'); $('.tile').eq(oldIndex).before(this); }); divs = null; } else { divs = $('.dolphin').parent().detach(); } }); 

Demostración en jsfiddle: http://jsfiddle.net/tqbzff2v/2/

Todos estaban cerca, pero aquí está exactamente lo que estás buscando con tu marcado HTML actual: http://jsfiddle.net/vs5o5nLb/2/

El truco es establecerse con anticipación con lo que necesita para alternar, luego mantener esa información para insertar y separar.

 var $els = $( '.tile' ); var stack = []; var isShown = true; $els.each(function() { var $this = $( this ); if ( $this.find('.dolphin').length ) { stack.push({ $el : $this, index : $els.index( this ) }); } }); $('.hide-divs').click(function () { if ( isShown ) { $.each(stack, function() { this.$el.detach(); }); isShown = false; } else { $.each(stack, function() { $('.tile').eq( this.index ).before( this.$el ); }); isShown = true; } }); 

Espero que ayude.

He usado remove () con alternar para eliminar y eliminar elementos. ejemplo: cada vez que el mouse pase el mouse y verifique si el texto está impreso en la lista desordenada y luego los elementos se eliminan en el siguiente clic. Jquery

  $('h1').hover(function(){ //alert('test toggle'); remove_el(); for(var i=0;i<5;i++){ $('ul').append('
  • '+'END_check else'+i+'
  • ').toggle(); } } ); function remove_el(){ $('li').remove(); };

    No estoy muy seguro de si esto es lo que le gustaría hacer – http://jsfiddle.net/tfyfpbb2/1/

    Si es así, solo necesita agregar tres filas de clases en lugar de una. De esta forma, cada fila tiene su propio “espacio” y no se perderá el estilo de la siguiente fila.

     
    01
    02
    03
    04

    ¡Espero que ayude! Avíseme si eso no es lo que quería y puedo editar mi respuesta.