Как я могу развернуть и свернуть <div> с помощью javascript?

96

Я создал список на своем сайте. Этот список создается с помощью цикла foreach, который строится на основе информации из моей базы данных. Каждый элемент представляет собой контейнер с разными разделами, поэтому это не список типа 1, 2, 3 ... и т. Д. Я перечисляю повторяющиеся разделы с информацией. В каждом разделе есть подраздел. Общая сборка выглядит следующим образом:

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

Итак, я пытаюсь вызвать функцию с onclick = "majorpointsexpand ($ (this) .find ('legend'). InnerHTML)"

Div, которым я пытаюсь управлять, по умолчанию - style = "display: none", и я хочу использовать javascript, чтобы сделать его видимым при нажатии.

«$ (This) .find ('legend'). InnerHTML» пытается передать, в данном случае, «Expand» в качестве аргумента функции.

Вот 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";
            }
    }

Я почти на 100% уверен, что моя проблема в синтаксисе, и я не очень понимаю, как работает javascript.

У меня есть jQuery, связанный с документом:

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

В <head></head>разделе.

Райан Мортенсен
источник
2
Я думаю, что вы пытаетесь достичь аккордеона jqueryui.com/accordion
Marc
1
$ это я пытаюсь сказать "по отношению" к HTML-элементу, внутри которого запускается функция.
Райан Мортенсен
1
@hungerpain - я думаю, что задающий вопрос может быть новичком в jQuery и просто забыл круглые скобки $(this). Надеюсь это поможет.
jmort253 04
2
Я думаю, вам следует сначала больше узнать о jQuery. Похоже, вы мало что знаете о разнице между jQuery и JavaScript
tom10271 01
1
@aokaddaoc, вы были абсолютно правы;)
Райан Мортенсен

Ответы:

184

Итак, у вас есть два варианта:

  1. Используйте аккордеон jQuery UI - это красиво, легко и быстро. См. Дополнительную информацию здесь
  2. Или, если вы все еще хотите сделать это самостоятельно, вы можете удалить fieldset(в любом случае использовать его для этого семантически не правильно) и создать структуру самостоятельно.

Вот как это сделать. Создайте такую ​​структуру HTML:

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

С помощью этого CSS: (Это нужно, чтобы скрыть .contentсодержимое при загрузке страницы.

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

Затем с помощью jQuery напишите clickсобытие для заголовка.

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

});

Вот демонстрация: http://jsfiddle.net/hungerpain/eK8X5/7/

кришвадер
источник
9
+1, так как это решило бы проблему, если бы на странице было более одного элемента DIV. Другими словами, поскольку вы ориентируетесь на контент в заголовке, по которому щелкнули мышью, это хорошо масштабируется.
jmort253 04
2
Набор полей не является обязательным. Я избавлюсь от этого и использую рамку. Это отлично, потому что он выбирает div для расширения относительно заголовка, который я щелкнул, что важно из-за того, что у меня может быть несколько разное количество перечисленных элементов в зависимости от настроек пользователя и других факторов.
Райан Мортенсен
1
@Unipartisandev, посмотрите на это: jsfiddle.net/hungerpain/476Nq полноценный пример :)
krishwader 05
Я очень ценю помощь. Будут и другие части сайта, в которых, несомненно, потребуется использовать аккордеон, даже если эта конкретная вещь представляет собой скорее пример отображения «все или ничего». У меня все еще проблемы. Мой jQuery устарел и не загружается. Это исправлено, но у меня все еще не работает. Я уже добрый час с этим напортачил, посплю на нем. Может завтра меня ударит.
Райан Мортенсен
Замечательно, спасибо. Сэкономлено много времени!
Василий Муса
21

как насчет:

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>

Скрипка

Таким образом, вы привязываете событие click к .majorpointsклассу, и вам не нужно каждый раз писать его в HTML.

raam86
источник
Привет, raam86, я бы пошел дальше и сделал бы .find в div, используя класс вместо идентификатора. Если у запрашивающего есть несколько таких наборов полей на странице, он захочет настроить таргетинг на хайдер, связанный с конкретным выбранным набором полей. Надеюсь это поможет! :) Например, вы можете использовать .closest, чтобы получить ссылку на родительский div, а затем использовать .find, чтобы вместо этого найти div с class = "hider".
jmort253 04
1
Я знаю, что сейчас 3 часа ночи;), но я только что заметил, что вы все еще используете id в своем jsFiddle. Это может привести к неопределенному поведению, поскольку спецификация W3C говорит, что каждый идентификатор должен быть уникальным. Если вы измените hider на класс, это будет более защищено от ошибок или странного, необъяснимого поведения в других браузерах. Надеюсь это поможет!
jmort253 04
на самом деле это должно быть $ ('. majorpointslegend'). click (function () {$ (this) .parent (). find ('. hider'). toggle ();}); ИЛИ иначе, когда щелкнули в любом месте набора полей, он рухнет.
Awatatah
7

Итак, во-первых, ваш Javascript даже не использует jQuery. Это можно сделать двумя способами. Например:

Первый способ - с помощью toggleметода 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/

Другой способ - просто использовать showметод 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/

Тем не менее, третий способ - использовать slideToggleметод jQuery, который позволяет получить некоторые эффекты. Например, $('#showMe').slideToggle('slow');который будет медленно отображать скрытый div.

Майкл Хокинс
источник
Предположим, у него на странице больше одного из этих элементов showMe? Помните, что он использует цикл for для создания их списка, поэтому таргетинг class = "showMe" повлияет только на первый экземпляр этого элемента. Я предлагаю ссылаться на элемент showMe по отношению к тому, по которому щелкнули. Тогда это было бы хорошим решением. Надеюсь это поможет! :)
jmort253 04
Верно, но он использует цикл для построения списка из серии <li>элементов, а не из div. В любом случае, он мог просто использовать идентификатор элемента, чтобы скрыть его.
Майкл Хокинс
Вы думаете о подразделах и забываете, что их будет больше. Каждый раздел заполняется li элементами в подразделе . "Этот список создается с помощью цикла foreach, который строится на основе информации из моей базы данных. Каждый элемент представляет собой контейнер с разными разделами, поэтому это не список типа 1, 2, 3 ... и т. Д. Я перечисляю повторяющиеся разделы с информацией . В каждом разделе есть подраздел ". Короче говоря, он просто показал вам только один раздел, хотя их будет больше.
jmort253 04
6

Возможно, вы захотите взглянуть на этот простой метод Javascript, который будет вызываться при нажатии на ссылку, чтобы развернуть или свернуть панель / 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>

Вы можете передать идентификатор div, и он будет переключаться между отображением «нет» или «блокировать».

Исходный код на snip2code - как свернуть div в html

Майк Скаттони
источник
6

Здесь много проблем

Я настроил скрипку, которая вам подходит: http://jsfiddle.net/w9kSU/

$('.majorpointslegend').click(function(){
    if($(this).text()=='Expand'){
        $('#mylist').show();
        $(this).text('Colapse');
    }else{
        $('#mylist').hide();
        $(this).text('Expand');
    }
});
Дэвид Лин
источник
3

попробуйте 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");
            }
    }
нманандхан
источник
3

Вот мой пример анимации штатного расписания с расширенным описанием.

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

Скрипка

Intacto
источник
3

Взгляните на функцию toggle() jQuery :

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

Также есть функция innerHTML jQuery.html() .

Это любовь
источник
1
Привет, добро пожаловать в Stack Overflow! Вы должны показать пример, чтобы ваш ответ был более полным. Если бы ссылка оборвалась, ваш ответ все равно был бы полезен для будущих посетителей. Удачи! :)
jmort253 04
Не могли бы вы отредактировать, чтобы добавить пример, или добавить это как комментарий. Спасибо.
JGallardo,
2

Поскольку у вас есть jQuery на странице, вы можете удалить этот onclickатрибут и majorpointsexpandфункцию. Добавьте следующий скрипт внизу вашей страницы или, желательно, во внешний файл .js:

$(function(){

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

});

Это решение должно работать с вашим HTML как есть, но на самом деле это не очень надежный ответ. Если вы измените fieldsetмакет, он может сломаться. Я бы посоветовал вам поместить classатрибут в этот скрытый div, например, class="majorpointsdetail"и вместо этого использовать этот код:

$(function(){

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

});

Obs: </fieldset>в вашем вопросе нет закрывающего тега, поэтому я предполагаю, что скрытый div находится внутри набора полей.

Сергиоперейра
источник
Вы правы. Есть закрывающий набор полей, но я пропустил его в своем вопросе. Он идет сразу после закрывающего внутреннего </div> и перед закрывающим внешним </div>
Райан Мортенсен
1

Если вы использовали сворачиваемую роль данных, например

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

тогда он закроет расширенный div

    $("#selector").collapsible().collapsible("collapse");   
Атиф Хуссейн
источник
1

Ознакомьтесь с библиотекой Readmore.js Джеда Фостера .

Его использование очень простое:

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

Вот доступные варианты настройки вашего виджета:

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

Использование может использовать его как:

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

Я надеюсь, что это помогает.

Хайтор Альтманн
источник