Jak mogę rozwinąć i zwinąć <div> za pomocą JavaScript?

96

Utworzyłem listę w mojej witrynie. Ta lista jest tworzona przez pętlę foreach, która tworzy informacje z mojej bazy danych. Każda pozycja jest kontenerem z różnymi sekcjami, więc nie jest to lista typu 1, 2, 3 ... itd. Wymieniam powtarzające się sekcje z informacjami. W każdej sekcji znajduje się podrozdział. Ogólna konstrukcja jest następująca:

<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>

Więc próbuję wywołać funkcję z onclick = "majorpointsexpand ($ (this) .find ('legenda'). InnerHTML)"

Element div, którym próbuję manipulować, ma domyślnie style = "display: none" i chcę użyć javascript, aby był widoczny po kliknięciu.

„$ (This) .find ('legend'). InnerHTML” próbuje przekazać, w tym przypadku, „Expand” jako argument funkcji.

Oto 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";
            }
    }

Jestem prawie w 100% pewien, że moim problemem jest składnia i nie mam pojęcia, jak działa javascript.

Mam łącze jQuery do dokumentu z:

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

W <head></head>sekcji.

Ryan Mortensen
źródło
2
Myślę, że to, co próbujesz osiągnąć, to akordeon jqueryui.com/accordion
Marc
1
$ to ja próbuję powiedzieć „w odniesieniu do” elementu HTML, w którym wyzwalana jest funkcja.
Ryan Mortensen
1
@hungerpain - Myślę, że osoba pytająca może być nowa w jQuery i po prostu zapomniała o nawiasach $(this). Mam nadzieję że to pomoże.
jmort253
2
Myślę, że najpierw powinieneś dowiedzieć się więcej o jQuery. Najwyraźniej niewiele wiesz o różnicy między jQuery i JavaScript
tom10271
1
@aokaddaoc miałeś absolutną rację;)
Ryan Mortensen

Odpowiedzi:

184

OK, więc masz dwie opcje:

  1. Użyj akordeonu jQuery UI - jest przyjemny, łatwy i szybki. Zobacz więcej informacji tutaj
  2. Lub, jeśli nadal chcesz to zrobić samodzielnie, możesz usunąć fieldset(i tak nie jest semantycznie właściwe używanie go do tego) i samodzielnie stworzyć strukturę.

Oto jak to robisz. Utwórz strukturę HTML w następujący sposób:

<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>

Z tym CSS: (ma to na celu ukrycie zawartości .contentpodczas ładowania strony.

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

Następnie, używając jQuery, napisz clickzdarzenie dla nagłówka.

$(".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";
        });
    });

});

Oto demo: http://jsfiddle.net/hungerpain/eK8X5/7/

krishwader
źródło
9
+1, ponieważ rozwiązałoby to problem, gdyby na stronie był więcej niż jeden element DIV. Innymi słowy, ponieważ kierujesz reklamy na zawartość klikniętego nagłówka, to dobrze się skaluje.
jmort253
2
Zestaw pól nie jest konieczny. Pozbędę się go i po prostu użyję ramki. Jest to doskonałe, ponieważ wybiera div do rozwinięcia w stosunku do klikniętego nagłówka, co jest ważne, ponieważ mogę mieć kilka różnych numerów pozycji na liście w zależności od ustawień użytkownika i innych czynników.
Ryan Mortensen,
1
@Unipartisandev spójrz na to: jsfiddle.net/hungerpain/476Nq pełny przykład :)
krishwader
Naprawdę doceniam pomoc. Będą inne części witryny, które bez wątpienia będą wymagały użycia akordeonu, nawet jeśli ta konkretna rzecz jest bardziej przykładem pokazującym wszystko albo nic. Wciąż mam problemy. Mój jQuery był przestarzały i nie ładuje się. To naprawione, ale nadal nie działa. Bawię się tym już dobrą godzinę, prześpię się na tym. Może jutro mnie to uderzy.
Ryan Mortensen,
Cudownie, dzięki. Zaoszczędzono mnóstwo czasu!
Basil Musa
21

Co powiesz na:

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>

Skrzypce

W ten sposób wiążesz zdarzenie click z .majorpointsklasą i nie musisz za każdym razem zapisywać go w kodzie HTML.

raam86
źródło
Cześć raam86, pójdę o krok dalej i zrobię .find w div przy użyciu klasy zamiast id. Jeśli pytający ma kilka takich zestawów pól na stronie, będzie chciał wycelować w element ukrywający powiązany z określonym zestawem pól, który kliknął. Mam nadzieję że to pomoże! :) Na przykład możesz użyć .closest, aby uzyskać odniesienie do nadrzędnego elementu div, a następnie użyć .find, aby znaleźć element div z klasą = "hider".
jmort253
1
Wiem, że jest 3 nad ranem;), ale właśnie zauważyłem, że nadal używasz identyfikatorów w swoim jsFiddle. Może to spowodować niezdefiniowane zachowanie, ponieważ specyfikacja W3C mówi, że każdy identyfikator powinien być unikalny. Jeśli zmienisz ukrywający się na klasę, będzie to bardziej odporne na błędy lub dziwne, niewyjaśnione zachowanie w innych przeglądarkach. Mam nadzieję że to pomoże!
jmort253
właściwie to powinno być $ ('. majorpointslegend'). click (function () {$ (this) .parent (). find ('. hider'). toggle ();}); LUB w przeciwnym razie, gdy zostanie kliknięte dowolne miejsce w zestawie pól, zostanie zwinięte.
Awatatah,
7

Po pierwsze, Twój Javascript nawet nie używa jQuery. Można to zrobić na kilka sposobów. Na przykład:

Pierwszy sposób, używając togglemetody 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').toggle();
    });
</script>

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

Innym sposobem jest po prostu użycie showmetody 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/

Jeszcze trzecim sposobem jest użycie slideTogglemetody jQuery, która pozwala na pewne efekty. Na przykład $('#showMe').slideToggle('slow');który będzie powoli wyświetlał ukryty element div.

Michael Hawkins
źródło
Załóżmy, że ma więcej niż jeden z tych elementów showMe na stronie? Pamiętaj, że używa pętli for do zbudowania ich listy, więc kierowanie na class = "showMe" wpłynie tylko na pierwsze wystąpienie tego elementu. Proponuję odwołać się do elementu showMe w odniesieniu do tego, który został kliknięty. Wtedy byłoby to dobre rozwiązanie. Mam nadzieję że to pomoże! :)
jmort253
Zgadza się, ale używa pętli do tworzenia listy w postaci serii <li>elementów, a nie elementów div. Tak czy inaczej, mógł po prostu użyć identyfikatora elementu, aby go ukryć.
Michael Hawkins,
Myślisz o podrozdziałach i zapominasz, że będzie ich więcej. Każda sekcja jest wypełniona elementami li w podsekcji . "Ta lista jest tworzona przez pętlę foreach, która tworzy informacje z mojej bazy danych. Każdy element jest kontenerem z różnymi sekcjami, więc nie jest to lista taka jak 1, 2, 3 ... itd. Wymieniam powtarzające się sekcje z informacjami . W każdej sekcji znajduje się podsekcja ”. krótko mówiąc, po prostu pokazał ci tylko jedną sekcję, chociaż będzie ich więcej.
jmort253
6

Możesz rzucić okiem na tę prostą metodę JavaScript, która ma być wywoływana po kliknięciu linku, aby rozwinąć lub zwinąć panel / element div.

<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>

Możesz przekazać identyfikator DIV i będzie on przełączał się między wyświetlaniem „brak” lub „blok”.

Oryginalne źródło na snip2code - Jak zwinąć div w html

Mike Scattoni
źródło
6

Wiele problemów tutaj

Skonfigurowałem skrzypce, które Ci odpowiadają: http://jsfiddle.net/w9kSU/

$('.majorpointslegend').click(function(){
    if($(this).text()=='Expand'){
        $('#mylist').show();
        $(this).text('Colapse');
    }else{
        $('#mylist').hide();
        $(this).text('Expand');
    }
});
David Lin
źródło
3

wypróbuj 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
źródło
3

Tutaj jest mój przykład animacji lista pracowników z rozszerzeniem opisu.

<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>

Skrzypce

Intacto
źródło
3

Spójrz na funkcję toggle() jQuery :

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

Również funkcja innerHTML jQuery jest .html().

czy to miłość
źródło
1
Witaj, witaj w Stack Overflow! Powinieneś pokazać przykład, aby twoja odpowiedź była bardziej kompletna. Gdyby łącze się zepsuło, odpowiedź nadal byłaby przydatna dla przyszłych odwiedzających. Powodzenia! :)
jmort253
Czy możesz edytować, aby dodać przykład lub dodać to jako komentarz. Dzięki.
JGallardo
2

Ponieważ na stronie znajduje się jQuery, możesz usunąć ten onclickatrybut i majorpointsexpandfunkcję. Dodaj następujący skrypt na dole strony lub, najlepiej, do zewnętrznego pliku .js:

$(function(){

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

});

To rozwiązanie powinno działać z Twoim HTML bez zmian, ale tak naprawdę nie jest to bardzo solidna odpowiedź. Jeśli zmienisz fieldsetukład, może to go zepsuć. Sugerowałbym umieszczenie classatrybutu w tym ukrytym div, na przykład class="majorpointsdetail"i użycie tego kodu:

$(function(){

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

});

Obs: </fieldset>w pytaniu nie ma zamykającego tagu, więc zakładam, że ukryty element div znajduje się wewnątrz zestawu pól.

sergiopereira
źródło
Masz rację. Jest zestaw pól zamykających, ale przegapiłem go w moim pytaniu. Następuje natychmiast po zamykającym wewnętrznym </div> i przed zamykającym zewnętrznym </div>
Ryan Mortensen
1

Jeśli użyłeś zwijanej roli danych, np

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

wtedy zamknie rozwinięty div

    $("#selector").collapsible().collapsible("collapse");   
Atif Hussain
źródło
1

Sprawdź bibliotekę Jeda Fostera Readmore.js .

Jego użycie jest tak proste, jak:

$(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>

Oto dostępne opcje konfiguracji widżetu:

{
  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() {}
},

Użyj można go używać jak:

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

Mam nadzieję, że to pomoże.

Heitor Althmann
źródło