JS / CSS手风琴滑动过渡问题

时间:2015-01-14 17:03:49

标签: javascript jquery css accordion

我正在尝试为滑块/滑动HTML块做JS模块。 JS模块正在计算块max-height

问题是,CSS过渡仅适用于向下滑动。 我找不到合适的解决方案。

这是jsFiddle

var Accordion = {
  'vars': {
    'attrItem': 'data-accordion-item',
    'attrToggle': 'data-accordion-toggle',
    'classOpened': '_active',
    'classPrepare': '_preparing',
    'timer': null
  },

  'accObject': {},

  'accData': function(accID, key, value) {
    var module = this;
    if (typeof value != 'undefined') {
      if (typeof module.accObject[accID] == 'undefined') {
        module.accObject[accID] = {};
      }
      module.accObject[accID][key] = value;
    } else {
      return module.accObject[accID][key];
    }
  },

  'init': function() {
    var module = this;

    // Loop accToggles
    $('*[' + module.vars.attrToggle + ']').each(function() {
      var accToggle = $(this);
      var accID = accToggle.attr(module.vars.attrToggle);
      // Store data of ID
      module.accData(accID, 'accID', accID);
      // Store data of toggle
      if (!module.accData(accID, 'accToggle')) {
        module.accData(accID, 'accToggle', accToggle);
      } else {
        module.accData(accID, 'accToggle', module.accData(accID, 'accToggle').add(accToggle));
      }
      // Attach click to accToggle
      accToggle.click(function(e) {
        e.preventDefault();
        // Toggle between open/close state
        module.accData(accID, 'accOpened') ? module.toggle(accID, false) : module.toggle(accID, true);
      });
    });

    // Loop accItems
    $('*[' + module.vars.attrItem + ']').each(function() {
      var accItem = $(this);
      var accID = accItem.attr(module.vars.attrItem);
      var accOpened = accItem.hasClass(module.vars.classOpened) ? true : false;
      // Store data of ID
      module.accData(accID, 'accID', accID);
      // Store data of item
      if (!module.accData(accID, 'accItem')) {
        module.accData(accID, 'accItem', accItem);
      } else {
        module.accData(accID, 'accItem', module.accData(accID, 'accItem').add(accItem));
      }
      // Store data of state
      if (!module.accData(accID, 'accOpened')) module.accData(accID, 'accOpened', accOpened);
      // Check to open or close accItem
      accOpened ? module.toggle(accID, true) : module.toggle(accID, false);
    });
  },

  'getSize': function(accItem) {
    var module = this;
    accItem.addClass(module.vars.classPrepare);
    var height = accItem.outerHeight();
    accItem.removeClass(module.vars.classPrepare);
    return height;
  },

  'toggle': function(accID, open, skipAnimation) {
    var module = this;
    var accItems = module.accData(accID, 'accItem');
    var accToggles = module.accData(accID, 'accToggle');
    var accOpened = module.accData(accID, 'accOpened');
    var action;

    // Check for action open/close and set vars
    if (open) {
      module.accData(accID, 'accOpened', true);
      action = 'addClass';
    } else {
      module.accData(accID, 'accOpened', false);
      action = 'removeClass';
    }


    // Loop items
    if (accItems) {
      accItems.each(function() {
        var accItem = $(this);
        accItem[action](module.vars.classOpened);
        // Timer fights against no animation
        if (module.timer) clearTimeout(module.timer);
        module.timer = setTimeout(function() {
          accItem.css('max-height', open ? module.getSize(accItem) : 0);
        }, 10);
      });
    }

    // Loop toggles
    if (accToggles) {
      accToggles.each(function() {
        var accToggle = $(this);
        accToggle[action](module.vars.classOpened);
      });
    }
  }
}


$(document).ready(function() {
  Accordion.init();
});
.f-control {
  background: #ddd;
}

*[data-accordion-item] {
  max-height: 0;
  padding-bottom: 6px;
  overflow: hidden;
  opacity: 0;
  -webkit-transition-property: max-height, opacity;
  transition-property: max-height, opacity;
  -webkit-transition-duration: 300ms;
  transition-duration: 300ms;
  margin-left: -20px;
  margin-right: -20px;
  padding-left: 20px;
  padding-right: 20px;
}
*[data-accordion-item]._active {
  opacity: 1;
}
*[data-accordion-item]._preparing {
  max-height: initial !important;
  -webkit-transition: none;
  transition: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<div class="f-row">
  <a href="#" class="side-title" data-accordion-toggle="1">
    <span>Show/hide</span>
  </a>
  <div class="f-control" data-accordion-item="1">
    <h1>Test1</h1>
    <h2>Test2</h2>
  </div>
</div>

1 个答案:

答案 0 :(得分:1)

JQuery有一种简单的方法可以使用slideToggle来显示/隐藏元素来生成这种功能。你甚至可以设定速度:)

$('#showHide').click(function(){
$('div').slideToggle("fast");  
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<button id="showHide">hideshow</button>
<div>
  this <br/>
  and this
  </div>