在slideToggle上动态更改div高度

时间:2014-03-08 16:21:15

标签: javascript jquery html css css3

enter image description here这很难解释,所以请耐心等待。

我的网页上有一栏分为2个小组/部分。当用户最小化面板时,我希望扩展辅助面板以占用剩余空间。

当面板1最小化时,列表隐藏,面板2标题将直接向上移动到面板1下方,列表将展开以填充下面的其余列空间。

当面板2最小化时,隐藏内的列表,面板2标题将直接进入页面底部,面板1列表将展开以适合列的其余部分

小提琴:http://jsfiddle.net/mL9RG/

我可以获取部分内的列表来滑动切换没问题。我还可以添加一个固定的CSS高度动画来实现我正在寻找的东西。我没有成功使用它来使其响应。

HTML

<div id="wrapper">
    <div id="section1">
        <h2 id="crossbar1">Section 1<span id="plus2">+/-</span></h2>
        <ul id="list1">
            <li>Stuff</li>
            <li>Stuff</li>
            <li>Stuff</li>
            <li>Stuff</li>
        </ul>
    </div>
    <div id="section2">
        <h2 id="crossbar2">Section 2 <span id="plus2">+/-</span></h2>
        <ul id="list2">
            <li>Stuff</li>
            <li>More Stuff</li>
            <li>Stuff</li>
        </ul>
    </div>
</div>

CSS

#wrapper { width: 200px; height: 400px; margin: 0 auto; background-color: #eaeaea; }
ul { margin: 0; padding: 0; list-style: none; display: block; }
h2 { margin: 0; padding: 5px 0; background-color: #d8d8d8; position: relative; }
h2 span { position: absolute; right: 10px; font-size: 15px; top: 10px; cursor: pointer }
#section1 { 
    height: 50%; width: 100%; background-color: blue;
    box-sizing: border-box;
}
#section2 {
    height: 50%; width: 100%; background-color: green;
}

jquery的

$('#crossbar1').click(function(){
   $('#list1').slideToggle(); 
});
$('#crossbar2').click(function(){
   $('#list2').slideToggle(); 
});

7 个答案:

答案 0 :(得分:2)

通用解决方案Fiddle

HTML

<div class="wrapper">
<div class="section expanded">
    <h2>Section 1<span class="toggle">+/-</span></h2>
    <ul class="list">
        <li>Stuff</li>
        <li>Stuff</li>
        <li>Stuff</li>
        <li>Stuff</li>
    </ul>
</div>
<div class="section expanded">
    <h2>Section 2<span class="toggle">+/-</span></h2>
    <ul class="list">
        <li>Stuff</li>
        <li>Stuff</li>
        <li>Stuff</li>
        <li>Stuff</li>
    </ul>
</div>
<div class="section expanded">
    <h2>Section 3<span class="toggle">+/-</span></h2>
    <ul class="list">
        <li>Stuff</li>
        <li>Stuff</li>
        <li>Stuff</li>
        <li>Stuff</li>
    </ul>
</div>

CSS

.wrapper {
    width: 200px; 
    height: 400px; 
    margin: 0 auto; 
    background-color: #eaeaea; 
    position: relative;
}


ul { 
    margin: 0; 
    padding: 0; 
    list-style: none; 
    display: block; 
}

h2 { 
    margin: 0; 
    padding: 0; 
    height:38px;
    line-height:38px; 
    background-color: #d8d8d8; 
    position: relative; 
}

h2 span { 
    position: absolute; 
    right: 10px; 
    font-size: 15px; 
    top: 0px; 
    cursor: pointer 
}

.section {
    position: relative;
    overflow:hidden;
}

脚本

function recalc(){
    var jq_parent = $(this).closest('.section');
    jq_parent.attr('class', 'section ' + (jq_parent.hasClass('expanded') ? 
                   'collapsed' : 'expanded'));
    var num = $('.expanded').length;
    if (num > 0) {
        var h = (400 - (38 * $('.collapsed').length) )/ num;
        $('.collapsed').animate({height:'38px'});
        $('.expanded').animate({height: h + 'px' });
    }
}
$('.toggle').click(recalc);
recalc();

答案 1 :(得分:1)

HTML

<div class="wrapper">
  <div class="wrapper-item">
    Section 1
    <div class="type"></div>
  </div>
  <div class="data">
      <ul id="list1">
          <li>Stuff</li>
          <li>Stuff</li>
          <li>Stuff</li>
          <li>Stuff</li>
      </ul>
  </div>
   <div class="wrapper-item">
    Section 2
     <div class="type"></div>
  </div>
  <div class="data">
      <ul id="list1">
          <li>Stuff</li>
          <li>Stuff</li>
          <li>Stuff</li>
          <li>Stuff</li>
      </ul>
  </div>

CSS

body
{
font-family: Arial, Helvetica, sans-serif;
}
.wrapper
{
  width:100%;
  max-height:300px;
  margin:20px auto;
}
.wrapper-item {
font-size: 1em;
margin: 0 10px 0 10px;
padding: 10px;
height: 20px;
background: #f2f2f2;
border-bottom:1px solid #ccc;
color: #000;
cursor:pointer;
}

.wrapper-item.open
{
background:#14ad40;
border-bottom:0px;
color:#fff;
}
.wrapper-item.open .type {
float: right;
background: url('http://vivekarora.com/images/minus.png') center no-repeat;
padding: 10px;
}

.wrapper-item .type {
float: right;
background: url('http://vivekarora.com/images/plus.png') center no-repeat;
padding: 10px;
}

div.data {
background: #fff;
margin: 0 10px 0 10px;
padding: 10px;
border:1px solid #ccc;
font-size: .8em;
line-height: 140%;
display:none;
}

JS

$(function($) {
  var allWrappers = $('.wrapper div.data');
  var allWrapperItems = $('.wrapper .wrapper-item');
  $('.wrapper > .wrapper-item').click(function() {
    if($(this).hasClass('open'))
    {
      $(this).removeClass('open');
      $(this).next().slideUp("slow");
    }
    else
    {
    allWrappers.slideUp("slow");
    allWrapperItems.removeClass('open');
    $(this).addClass('open');
    $(this).next().slideDown("slow");
    return false;
    }
  });
});

DEMO

答案 2 :(得分:0)

尝试这种方法来实现你想要的目标。

我使用了class而不是id。它会使代码很短。

<强> HTML

<div id="wrapper">
    <div class="section">
        <h2 class="crossbar">Section 1<span id="plus2">+/-</span></h2>
        <ul id="list1">
            <li>Stuff</li>
            <li>Stuff</li>
            <li>Stuff</li>
            <li>Stuff</li>
        </ul>
    </div>
    <div class="section">
        <h2 class="crossbar">Section 2 <span id="plus2">+/-</span></h2>
        <ul id="list2">
            <li>Stuff</li>
            <li>More Stuff</li>
            <li>Stuff</li>
        </ul>
    </div>
</div>

<强> CSS

#wrapper { width: 200px; height: 400px; margin: 0 auto; background-color: #eaeaea; }
ul { margin: 0; padding: 0; list-style: none; display: block; }
h2 { margin: 0; padding: 5px 0; background-color: #d8d8d8; position: relative; }
h2 span { position: absolute; right: 10px; font-size: 15px; top: 10px; cursor: pointer }
.section{ 
   width: 100%; 
    box-sizing: border-box;
}
#list1{ height: 150px; background-color: blue;}
#list2{ height: 150px; background-color: green;}

<强>脚本

$('h2.crossbar').on('click', function(){
    $(this).next('ul').slideToggle();
}); 

Fiddle Demo

答案 3 :(得分:0)

听起来你正在描述Bootstrap崩溃插件实现的行为,这是正确的吗?请在此处查看示例:http://getbootstrap.com/javascript/#collapse

答案 4 :(得分:0)

我建议您使用jQuery的.toggleClass()函数。

如果再增加两个课程:

.open {
    height: 50%;    
}

.fullOpen {
    height: 100%;   
}

然后,您可以按如下方式控制内容框的状态:

$('#crossbar1').click(function(){
   $("#one").toggleClass('open', 100);
   $('#bodyOne').slideToggle(100); 
   $("#two").toggleClass('fullOpen', 100);   
});

$('#crossbar2').click(function(){
   $("#two").toggleClass('open', 100);
   $('#bodyTwo').slideToggle(100); 
   $("#one").toggleClass('fullOpen', 100);    
});

这完美无缺,完全按照你的暗示行事。

DEMO

您还可以通过明确跟踪框的状态来实现它:

DEMO 2

希望这会帮助你!

答案 5 :(得分:0)

您想使用flexboxes

我假设您使用div#section来创建效果,并且您不需要它们,这样可以为DOM提供更清晰的标记和更少的节点:

<div id="wrapper">
    <h2 id="crossbar1">Section 1<span id="plus1">+/-</span></h2>
    <ul id="list1">
        <li>Stuff</li>
        <li>Stuff</li>
        <li>Stuff</li>
        <li>Stuff</li>
    </ul>
    <h2 id="crossbar2">Section 2 <span id="plus2">+/-</span></h2>
    <ul id="list2">
        <li>Stuff</li>
        <li>More Stuff</li>
        <li>Stuff</li>
    </ul>
</div>

现在我们将#wrapper设置为flexbox(通过display: flex),并说我们希望以列方式使用它(flex-direction: column),这意味着内容将垂直展开。另外,我们将列表中的flex-grow设置为1,以便在必要时增加:

#wrapper { display: flex; flex-flow: column nowrap; 
           width: 200px; height: 400px; margin: 0 auto; background-color: #eaeaea; }
#wrapper > ul { flex-grow:1; margin: 0; padding: 0; list-style: none; }

/* your old rules */
h2 { margin: 0; padding: 5px 0; background-color: #d8d8d8; position: relative; }
h2 span { position: absolute; right: 10px; font-size: 15px; top: 10px; cursor: pointer }

#list1{background-color: blue}
#list2{background-color: green}

对于相互行为,我选择了一种易于扩展到更多部分的方法:

var addToToggleGroup = (function(){
    var toggleState = []; // holds the state of the elements in the group

    var toggle = function(i, target) {
        toggleState[i] = !toggleState[i];

        // prevent that we toggle this element if it is the last

        if(toggleState.every(function(el){ return !el;})){
            toggleState[i] = !toggleState[i];
            return;
        } else {
            $(target).slideToggle();
        }
    }

    return function (el, target){
        var i = toggleState.length;
        toggleState.push(true);
        $(el).on("click", function(){
            toggle(i, target);
        })
    }
})();

// add the elements to the toggle group. We can use jQuery selectors here
addToToggleGroup("#crossbar1","#list1");
addToToggleGroup("#crossbar2","#list2");

那就是它(fiddle)。

参考

答案 6 :(得分:0)

通过设置动画高度来查看我的解决方案。 行为应与您的图像类似。

已修改css:

#wrapper { 
    width: 200px; height: 400px; margin: 0 auto; background-color: #eaeaea; 
    position: relative;
}
ul { margin: 0; padding: 0; list-style: none; display: block; }
h2 { margin: 0; padding: 5px 0; background-color: #d8d8d8; position: relative; }
h2 span { position: absolute; right: 10px; font-size: 15px; top: 10px; cursor: pointer }

#section1, #section2{
    box-sizing: border-box;
    width: 100%;
    height: 50%;
}

#section1 { 
    background-color: blue;
}
#section2 {
    background-color: green;
} 

修改后的js

$('#crossbar1').click(function(){
    if($('#list1').is(':hidden')){
        if($('#list2').is(':hidden')){
            $( "#section1" ).animate({height: "362px"});
            $( "#section2" ).animate({height: "37px"});
        }else{   
            $( "#section1" ).animate({height: "50%"}); 
            $( "#section2" ).animate({height: "50%"});    
        } 
    }else{   
        if($('#list1').is(':hidden')){
            $( "#section1" ).animate({height: "362px"});
        }else{   
            $( "#section1" ).animate({height: "37px"}); 
            $( "#section2" ).animate({height: "362px"});     
        }  
    }
    $('#list1').slideToggle(); 
});
$('#crossbar2').click(function(){
    if($('#list2').is(':hidden')){  
        if($('#list1').is(':hidden')){
            $( "#section2" ).animate({height: "362px"});
        }else{   
            $( "#section2" ).animate({height: "50%"});
            $( "#section1" ).animate({height: "50%"});     
        } 
    }else{   
        if($('#list1').is(':hidden')){
            $( "#section2" ).animate({height: "362px"});
        }else{   
            $( "#section2" ).animate({height: "37px"}); 
            $( "#section1" ).animate({height: "362px"});     
        }  
    }
    $('#list2').slideToggle(); 
});

查看jsFiddle 上的演示。 希望这就是你要找的东西。

编辑:关闭section2和打开和关闭section1的小错误修正。 (更新了jsFiddle-Demo)