¿Cómo puedo expandir y contraer un <div> usando javascript?

96

He creado una lista en mi sitio. Esta lista es creada por un bucle foreach que se construye con información de mi base de datos. Cada elemento es un contenedor con diferentes secciones, por lo que esta no es una lista como 1, 2, 3 ... etc. Estoy enumerando secciones repetidas con información. En cada sección, hay una subsección. La construcción general es la siguiente:

<div>
    <fieldset class="majorpoints" onclick="majorpointsexpand($(this).find('legend').innerHTML)">
    <legend class="majorpointslegend">Expand</legend>
    <div style="display:none" >
        <ul>
            <li></li>
            <li></li>
        </ul>
    </div>
</div>

Entonces, estoy tratando de llamar a una función con onclick = "majorpointsexpand ($ (this) .find ('legend'). InnerHTML)"

El div que estoy tratando de manipular es style = "display: none" por defecto, y quiero usar javascript para hacerlo visible al hacer clic.

El "$ (this) .find ('legend'). InnerHTML" está intentando pasar, en este caso, "Expandir" como un argumento en la función.

Aquí está el javascript:

function majorpointsexpand(expand)
    {
        if (expand == "Expand")
            {
                document.write.$(this).find('div').style = "display:inherit";
                document.write.$(this).find('legend').innerHTML = "Collapse";
            }
        else
            {
                document.write.$(this).find('div').style = "display:none";
                document.write.$(this).find('legend').innerHTML = "Expand";
            }
    }

Estoy casi 100% seguro de que mi problema es la sintaxis, y no tengo mucha idea de cómo funciona JavaScript.

Tengo jQuery vinculado al documento con:

<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>

En la <head></head>sección.

Ryan Mortensen
fuente
2
Creo que lo que estás tratando de lograr es un acordeón jqueryui.com/accordion
Marc
1
$ este soy yo tratando de decir "en relación con" el elemento HTML dentro del cual se activa la función.
Ryan Mortensen
1
@hungerpain: creo que el autor de la pregunta puede ser nuevo en jQuery y simplemente se olvidó del paréntesis $(this). Espero que esto ayude.
jmort253
2
Creo que primero deberías estudiar más sobre jQuery. Aparentemente, no sabe mucho sobre la diferencia entre jQuery y JavaScript
tom10271
1
@aokaddaoc tenías toda la razón;)
Ryan Mortensen

Respuestas:

183

Bien, tienes dos opciones aquí:

  1. Usa el acordeón de jQuery UI: es agradable, fácil y rápido. Ver más información aquí
  2. O, si aún desea hacer esto usted mismo, puede eliminar fieldset(no es semánticamente correcto usarlo para esto de todos modos) y crear una estructura usted mismo.

Así es como lo haces. Crea una estructura HTML como esta:

<div class="container">
    <div class="header"><span>Expand</span>

    </div>
    <div class="content">
        <ul>
            <li>This is just some random content.</li>
            <li>This is just some random content.</li>
            <li>This is just some random content.</li>
            <li>This is just some random content.</li>
        </ul>
    </div>
</div>

Con este CSS: (Esto es para ocultar las .contentcosas cuando se carga la página.

.container .content {
    display: none;
    padding : 5px;
}

Luego, usando jQuery, escriba un clickevento para el encabezado.

$(".header").click(function () {

    $header = $(this);
    //getting the next element
    $content = $header.next();
    //open up the content needed - toggle the slide- if visible, slide up, if not slidedown.
    $content.slideToggle(500, function () {
        //execute this after slideToggle is done
        //change text of header based on visibility of content div
        $header.text(function () {
            //change text based on condition
            return $content.is(":visible") ? "Collapse" : "Expand";
        });
    });

});

Aquí hay una demostración: http://jsfiddle.net/hungerpain/eK8X5/7/

Krishwader
fuente
9
+1 ya que esto resolvería el problema si hubiera más de un elemento DIV en la página. En otras palabras, dado que está apuntando al contenido dentro del encabezado en el que se hizo clic, esto se escala bien.
jmort253
2
El campo no es imperativo. Me deshaceré de él y solo usaré un borde. Esto es excelente porque selecciona el div para expandir en relación con el encabezado en el que hice clic, lo cual es importante debido al hecho de que puedo tener varios números diferentes de elementos en la lista según la configuración del usuario y otros factores.
Ryan Mortensen
1
@Unipartisandev mira esto: jsfiddle.net/hungerpain/476Nq ejemplo completo :)
krishwader
Realmente aprecio la ayuda. Habrá otras partes del sitio que sin duda necesitarán usar un acordeón, aunque esta cosa en particular es más un ejemplo de visualización de todo o nada. Sigo teniendo problemas. Mi jQuery estaba desactualizado y no se cargaba. Eso está arreglado, pero todavía no lo hago funcionar. Lo he estado jugando durante una buena hora, dormiré sobre él. Quizás mañana me golpee.
Ryan Mortensen
Maravilloso, gracias. ¡Ahorró mucho tiempo!
Basil Musa
21

qué tal si:

jQuery:

$('.majorpoints').click(function(){
    $(this).find('.hider').toggle();
});

HTML

<div>
  <fieldset class="majorpoints">
    <legend class="majorpointslegend">Expand</legend>
    <div class="hider" style="display:none" >
        <ul>
            <li>cccc</li>
            <li></li>
        </ul>
    </div>
</div>

Violín

De esta manera, vincula el evento de clic a la .majorpointsclase y no tiene que escribirlo en HTML cada vez.

raam86
fuente
Hola raam86, iría un paso más allá y haría un .find en el div usando una clase en lugar de una identificación. Si el autor de la pregunta tiene varios de estos conjuntos de campos en la página, querrá apuntar al ocultador para el relacionado con el conjunto de campos específico en el que se hizo clic. ¡Espero que esto ayude! :) Por ejemplo, podría usar .closest para obtener una referencia al div padre, luego usar .find para ubicar el div con un class = "hider" en su lugar.
jmort253
1
Sé que son las 3 am;), pero acabo de notar que todavía estás usando id's en tu jsFiddle. Esto podría resultar en un comportamiento indefinido ya que la especificación W3C dice que cada identificación debe ser única. Si cambia el ocultador a una clase, entonces esto sería más inmune a errores o comportamientos extraños e inexplicables en otros navegadores. ¡Espero que esto ayude!
jmort253
en realidad debería ser $ ('. majorpointslegend'). click (function () {$ (this) .parent (). find ('. hider'). toggle ();}); O bien, cuando se haga clic en cualquier lugar del conjunto de campos, se colapsará.
Awatatah
7

Entonces, en primer lugar, su Javascript ni siquiera usa jQuery. Hay un par de maneras de hacer esto. Por ejemplo:

Primera forma, usando jQuery toggle método :

<div class="expandContent">
        <a href="#">Click Here to Display More Content</a>
 </div>
<div class="showMe" style="display:none">
        This content was hidden, but now shows up
</div>

<script>  
    $('.expandContent').click(function(){
        $('.showMe').toggle();
    });
</script>

jsFiddle: http://jsfiddle.net/pM3DF/

Otra forma es simplemente usar el showmétodo jQuery :

<div class="expandContent">
        <a href="#">Click Here to Display More Content</a>
 </div>
<div class="showMe" style="display:none">
        This content was hidden, but now shows up
</div>

<script>
    $('.expandContent').click(function(){
        $('.showMe').show();
    });
</script>

jsFiddle: http://jsfiddle.net/Q2wfM/

Sin embargo, una tercera forma es utilizar el slideTogglemétodo de jQuery que permite algunos efectos. Como el $('#showMe').slideToggle('slow');que mostrará lentamente el div oculto.

Michael Hawkins
fuente
Suponga que tiene más de uno de estos elementos showMe en la página. Recuerde, está usando un bucle for para construir una lista de estos, por lo que la orientación class = "showMe" solo afectaría la primera instancia de ese elemento. Mi sugerencia es hacer referencia al elemento showMe en relación con el que se hizo clic. Entonces esta sería una buena solución. ¡Espero que esto ayude! :)
jmort253
Correcto, pero está usando el bucle para construir la lista en una serie de <li>elementos, no divs. De cualquier manera, podría usar el ID del elemento y luego ocultarlo.
Michael Hawkins
Estás pensando en las subsecciones y olvidas que habrá más de estas. Cada sección se rellena con elementos li en una subsección . "Esta lista se crea mediante un bucle foreach que se crea con información de mi base de datos. Cada elemento es un contenedor con diferentes secciones, por lo que esta no es una lista como 1, 2, 3 ... etc. Estoy enumerando secciones repetidas con información . En cada sección, hay una subsección ". en resumen, simplemente le mostró una sola sección, aunque habrá más.
jmort253
6

Es posible que desee echar un vistazo a este método simple de Javascript que se invoca al hacer clic en un enlace para hacer que un panel / div se expanda o colapse.

<script language="javascript"> 
function toggle(elementId) {
    var ele = document.getElementById(elementId);
    if(ele.style.display == "block") {
            ele.style.display = "none";
    }
    else {
        ele.style.display = "block";
    }
} 
</script>

Puede pasar la ID div y alternará entre mostrar 'ninguno' o 'bloquear'.

Fuente original en snip2code : cómo contraer un div en html

Mike Scattoni
fuente
6

Muchos problemas aqui

Configuré un violín que funciona para ti: http://jsfiddle.net/w9kSU/

$('.majorpointslegend').click(function(){
    if($(this).text()=='Expand'){
        $('#mylist').show();
        $(this).text('Colapse');
    }else{
        $('#mylist').hide();
        $(this).text('Expand');
    }
});
David Lin
fuente
3

prueba jquery,

  <div>
        <a href="#" class="majorpoints" onclick="majorpointsexpand(" + $('.majorpointslegend').html() + ")"/>
        <legend class="majorpointslegend">Expand</legend>
        <div id="data" style="display:none" >
            <ul>
                <li></li>
                <li></li>
            </ul>
        </div>
    </div>


function majorpointsexpand(expand)
    {
        if (expand == "Expand")
            {
                $('#data').css("display","inherit");
                $(".majorpointslegend").html("Collapse");
            }
        else
            {
                $('#data').css("display","none");
                $(".majorpointslegend").html("Expand");
            }
    }
nmanandhan
fuente
3

Aquí está mi ejemplo de animación de una lista de personal con una descripción ampliada.

<html>
  <head>
    <style>
      .staff {            margin:10px 0;}
      .staff-block{       float: left; width:48%; padding-left: 10px; padding-bottom: 10px;}
      .staff-title{       font-family: Verdana, Tahoma, Arial, Serif; background-color: #1162c5; color: white; padding:4px; border: solid 1px #2e3d7a; border-top-left-radius:3px; border-top-right-radius: 6px; font-weight: bold;}
      .staff-name {       font-family: Myriad Web Pro; font-size: 11pt; line-height:30px; padding: 0 10px;}
      .staff-name:hover { background-color: silver !important; cursor: pointer;}
      .staff-section {    display:inline-block; padding-left: 10px;}
      .staff-desc {       font-family: Myriad Web Pro; height: 0px; padding: 3px; overflow:hidden; background-color:#def; display: block; border: solid 1px silver;}
      .staff-desc p {     text-align: justify; margin-top: 5px;}
      .staff-desc img {   margin: 5px 10px 5px 5px; float:left; height: 185px; }
    </style>
  </head>
<body>
<!-- START STAFF SECTION -->
<div class="staff">
  <div class="staff-block">
    <div  class="staff-title">Staff</div>
    <div class="staff-section">
        <div class="staff-name">Maria Beavis</div>
        <div class="staff-desc">
          <p><img src="http://www.craigmarlatt.com/canada/images/security&defence/coulombe.jpg" />Maria earned a Bachelor of Commerce degree from McGill University in 2006 with concentrations in Finance and International Business. She has completed her wealth Management Essentials course with the Canadian Securities Institute and has worked in the industry since 2007.</p>
        </div>
        <div class="staff-name">Diana Smitt</div>
        <div class="staff-desc">
          <p><img src="http://www.craigmarlatt.com/canada/images/security&defence/coulombe.jpg" />Diana joined the Diana Smitt Group to help contribute to its ongoing commitment to provide superior investement advice and exceptional service. She has a Bachelor of Commerce degree from the John Molson School of Business with a major in Finance and has been continuing her education by completing courses.</p>
        </div>
        <div class="staff-name">Mike Ford</div>
        <div class="staff-desc">
          <p><img src="http://www.craigmarlatt.com/canada/images/security&defence/coulombe.jpg" />Mike: A graduate of École des hautes études commerciales (HEC Montreal), Guillaume holds the Chartered Investment Management designation (CIM). After having been active in the financial services industry for 4 years at a leading competitor he joined the Mike Ford Group.</p>
        </div>
    </div>
  </div>

  <div class="staff-block">
    <div  class="staff-title">Technical Advisors</div>
    <div class="staff-section">
        <div class="staff-name">TA Elvira Bett</div>
        <div class="staff-desc">
          <p><img src="http://www.craigmarlatt.com/canada/images/security&defence/coulombe.jpg" />Elvira has completed her wealth Management Essentials course with the Canadian Securities Institute and has worked in the industry since 2007. Laura works directly with Caroline Hild, aiding in revising client portfolios, maintaining investment objectives, and executing client trades.</p>
        </div>
        <div class="staff-name">TA Sonya Rosman</div>
        <div class="staff-desc">
          <p><img src="http://www.craigmarlatt.com/canada/images/security&defence/coulombe.jpg" />Sonya has a Bachelor of Commerce degree from the John Molson School of Business with a major in Finance and has been continuing her education by completing courses through the Canadian Securities Institute. She recently completed her Wealth Management Essentials course and became an Investment Associate.</p>
        </div>
        <div class="staff-name">TA Tim Herson</div>
        <div class="staff-desc">
          <p><img src="http://www.craigmarlatt.com/canada/images/security&defence/coulombe.jpg" />Tim joined his father&#8217;s group in order to continue advising affluent families in Quebec. He is currently President of the Mike Ford Professionals Association and a member of various other organisations.</p>
        </div>
    </div>
  </div>
</div>
<!-- STOP STAFF SECTION -->

<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

<script language="javascript"><!--
//<![CDATA[
$('.staff-name').hover(function() {
    $(this).toggleClass('hover');
});
var lastItem;
    $('.staff-name').click(function(currentItem) {
        var currentItem = $(this);
      if ($(this).next().height() == 0) {
          $(lastItem).css({'font-weight':'normal'});
          $(lastItem).next().animate({height: '0px'},400,'swing');
          $(this).css({'font-weight':'bold'});
          $(this).next().animate({height: '300px',opacity: 1},400,'swing');
      } else {
          $(this).css({'font-weight':'normal'});
          $(this).next().animate({height: '0px',opacity: 1},400,'swing');
      }
      lastItem = $(this);
    });
//]]>
--></script>

</body></html>

Violín

Intacto
fuente
3

Eche un vistazo a la función toggle() jQuery :

http://api.jquery.com/toggle/

Además, la función innerHTML jQuery es .html().

es esto amor
fuente
1
Hola, bienvenido a Stack Overflow. Debería mostrar un ejemplo para que su respuesta sea más completa. Si el enlace se rompiera, su respuesta aún sería útil para futuros visitantes. ¡Buena suerte! :)
jmort253
¿Podría editar para agregar un ejemplo o agregar esto como un comentario? Gracias.
JGallardo
2

Como tiene jQuery en la página, puede eliminar ese onclickatributo y la majorpointsexpandfunción. Agregue la siguiente secuencia de comandos al final de su página o, preferiblemente, a un archivo .js externo:

$(function(){

  $('.majorpointslegend').click(function(){
    $(this).next().toggle().text( $(this).is(':visible')?'Collapse':'Expand' );
  });

});

Esta solución debería funcionar con su HTML tal como está, pero en realidad no es una respuesta muy sólida. Si cambia su fieldsetdiseño, podría romperlo. Le sugiero que ponga un classatributo en ese div oculto, como class="majorpointsdetail"y use este código en su lugar:

$(function(){

  $('.majorpoints').on('click', '.majorpointslegend', function(event){
    $(event.currentTarget).find('.majorpointsdetail').toggle();
    $(this).text( $(this).is(':visible')?'Collapse':'Expand' );
  });

});

Obs: no hay una </fieldset>etiqueta de cierre en su pregunta, así que supongo que el div oculto está dentro del conjunto de campos.

sergiopereira
fuente
Estás en lo correcto. Hay un conjunto de campos de cierre, pero me lo perdí en mi pregunta. Viene inmediatamente después del cierre interior </div> y antes del cierre exterior </div>
Ryan Mortensen
1

Si usó el rol de datos colapsable, por ejemplo

    <div id="selector" data-role="collapsible" data-collapsed="true">
    html......
    </div>

luego cerrará el div expandido

    $("#selector").collapsible().collapsible("collapse");   
Atif Hussain
fuente
1

Consulte la biblioteca Readmore.js de Jed Foster .

Su uso es tan simple como:

$(document).ready(function() {
  $('article').readmore({collapsedHeight: 100});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<script src="https://fastcdn.org/Readmore.js/2.1.0/readmore.min.js" type="text/javascript"></script>

<article>
  <p>From this distant vantage point, the Earth might not seem of any particular interest. But for us, it's different. Consider again that dot. That's here. That's home. That's us. On it everyone you love, everyone you know, everyone you ever heard of, every human being who ever was, lived out their lives. The aggregate of our joy and suffering, thousands of confident religions, ideologies, and economic doctrines, every hunter and forager, every hero and coward, every creator and destroyer of civilization, every king and peasant, every young couple in love, every mother and father, hopeful child, inventor and explorer, every teacher of morals, every corrupt politician, every "superstar," every "supreme leader," every saint and sinner in the history of our species lived there – on a mote of dust suspended in a sunbeam.</p>

  <p>Space, the final frontier. These are the voyages of the starship Enterprise. Its five year mission: to explore strange new worlds, to seek out new life and new civilizations, to boldly go where no man has gone before!</p>

  <p>Here's how it is: Earth got used up, so we terraformed a whole new galaxy of Earths, some rich and flush with the new technologies, some not so much. Central Planets, them was formed the Alliance, waged war to bring everyone under their rule; a few idiots tried to fight it, among them myself. I'm Malcolm Reynolds, captain of Serenity. Got a good crew: fighters, pilot, mechanic. We even picked up a preacher, and a bona fide companion. There's a doctor, too, took his genius sister out of some Alliance camp, so they're keeping a low profile. You got a job, we can do it, don't much care what it is.</p>

  <p>Space, the final frontier. These are the voyages of the starship Enterprise. Its five year mission: to explore strange new worlds, to seek out new life and new civilizations, to boldly go where no man has gone before!</p>
</article>

Estas son las opciones disponibles para configurar su widget:

{
  speed: 100,
  collapsedHeight: 200,
  heightMargin: 16,
  moreLink: '<a href="#">Read More</a>',
  lessLink: '<a href="#">Close</a>',
  embedCSS: true,
  blockCSS: 'display: block; width: 100%;',
  startOpen: false,

  // callbacks
  blockProcessed: function() {},
  beforeToggle: function() {},
  afterToggle: function() {}
},

El uso puede usarlo como:

$('article').readmore({
  collapsedHeight: 100,
  moreLink: '<a href="#" class="you-can-also-add-classes-here">Continue reading...</a>',
});

Espero que ayude.

Heitor Althmann
fuente