浏览dom以调整自定义jQuery手风琴

时间:2015-05-14 19:22:09

标签: jquery dom accordion

我有手风琴正在工作,当你走下手风琴时效果非常好,但是当你回来时它有点不好意思。

我想这样做,当您点击标头时,它将打开该标头内的内容并将页面顶部固定到标头顶部。我知道我需要在伪代码中做些什么,但我不确定该如何处理代码。

这是我的HTML:

<html>
<head>
    <meta>
    <title></title>
    <link rel="stylesheet" href="made-insider.css">
</head>
<body>
    <div class="accordion">
        <div id="one" class="masthead"></div>
        <div class="insider-info"></div>

        <div id="two" class="masthead"></div>
        <div class="insider-info"></div>

        <div id="three" class="masthead"></div>
        <div class="insider-info"></div>

        <div id="four" class="masthead"></div>
        <div class="insider-info"></div>
    </div>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script src="made-insider.js"></script>
</body>
</html>

这是我的jQuery:

$(function() {

  //Checking the position of panels
  var allPanels = $('.insider-info').hide();

  //working accordion code -- needs to be smoother
  $('.accordion > .masthead').click(function(event) {

    if ($(this).hasClass('active')) {
        $(this).removeClass('active')
            .next(allPanels).slideUp(400);
    } else {
      var topPos = $(this).position();
        $('.active').removeClass('active')
            .next(allPanels).slideUp(400);
      //if the previous accordion is open
        $('body').animate({ scrollTop: topPos.top - 200}, 600);
      //if the previous accordion is not open
        //$('body').animate({ scrollTop: topPos.top}, 600);
        $(this).addClass('active')
            .next(allPanels).slideDown(400);
    }
  });

});

我尝试过像

这样的事情
if ($(this).prev('.masthead').hasClass('.active')){
    behavior
}, 


if ($(this).prev().prev().hasClass('.active'){
    behavior
}

if ($(this).eq() < $('div.active').eq()){
    behavior
} 

但它们都不起作用。有什么建议??

2 个答案:

答案 0 :(得分:2)

问题是,在您从当前拥有的任何元素中删除类.active后,您需要知道.active索引的代码中的位置会运行。

解决方案:移动这段代码

$('.active').removeClass('active')
    .next(allPanels).slideUp(400);

到事件处理程序的末尾,就在您将类.active添加到新的活动元素之前。

然后你正在寻找的条件是

if ($('.active').length && $('.active').index() < $(this).index()) {
    // the previously active accordion is above the new one (we're moving down)
}

所以,总之,你的代码将如下所示:

$('.accordion > .masthead').click(function (event) {

    if ($(this).hasClass('active')) {
        $(this).removeClass('active')
            .next(allPanels).slideUp(400);
    } else {
        var topPos = $(this).position();

        // the previously active accordion is above the new one
        if ($('.active').length && $('.active').index() < $(this).index()) {
            $('body').animate({
                scrollTop: topPos.top - 200
            }, 600);
        } else { // the previously active accordion is below the new one, or there was no previous accordion
            $('body').animate({
                scrollTop: topPos.top
            }, 600);
        }

        $('.active').removeClass('active')
            .next(allPanels).slideUp(400);
        $(this).addClass('active')
            .next(allPanels).slideDown(400);
    }
});

JSFiddle Here

答案 1 :(得分:0)

我本周末花了一天时间来清理代码并改进它的功能。

此代码允许您创建一个固定在您单击的选项卡顶部的手风琴,并使其响应标头选项卡的大小和选项卡中的内容。关于如何使代码更清晰的任何建议都会很棒!

如果需要,请查看我的GitHub上的代码:https://github.com/realjoet/smooth-flexible-accordion

$(function () {
  //Checking the position of panels
  var allContentPanels = $('.content');
  var allMastheads = $('.masthead');
  var hideContentPanels = allContentPanels.hide();
  //If you want margin on your mastheads, enter it here just like CSS
  var mastheadMargin = "0";
  //Need to fill these in with negative values of the values you put in for mastheadMargin
  var marginTopFix = "0";
  var marginRightFix = "0";
  var marginBottomFix = "0";
  var marginLeftFix = "0";

  allMastheads.css("margin", mastheadMargin);

  //working accordion code
  $('.accordion > .masthead').click(function() {
    var el = $(this);
    var activeEl = $('.active');
    var contentHeight = $('.active').next().height();
    var topPos = $(this).position().top;

    function marginFix(el) {
      $(el).next().css({
        "position": "relative", 
        "top": marginTopFix, 
        "right": marginRightFix, 
        "bottom": marginBottomFix, 
        "left": marginLeftFix
      }).delay(10);
    }

    //Accordion function
    function accordionFunc(el, animationTime, animationTime2) {
      if (el.hasClass('active')) {
        el.removeClass('active')
          .next(allContentPanels).slideUp(animationTime);
        $('body').animate({scrollTop: topPos}, animationTime);
      } else {
        if (activeEl.length && activeEl.index() < el.index()) {
          $('body').animate({scrollTop: topPos - contentHeight}, animationTime2);
        } else { 
          $('body').animate({scrollTop: topPos}, animationTime2);
        }

        activeEl.removeClass('active')
          .next(allContentPanels).slideUp(animationTime);
        el.addClass('active')
          .next(allContentPanels).slideDown(animationTime);
      }
    }

    //Adjusts masthead margins
    if (el.hasClass('active')) {
      marginFix(el);
      $(allMastheads).css("margin", mastheadMargin);
    } else {
      marginFix(activeEl);
      $(allMastheads).css("margin", mastheadMargin);
      el.css("margin", "0");
      el.next().css("margin", mastheadMargin);
      if (el.next().css("top") == marginTopFix) {
        el.next().css("top", "0");
      }
    }

    //Creates content-responsive accordion
    if (contentHeight < 400) {
      accordionFunc(el, 600, 800);
    } else if (contentHeight < 800) {
      accordionFunc(el, 800, 1000);
    } else if (contentHeight < 1200) {
      accordionFunc(el, 1000, 1200);
    } else {
      accordionFunc(el, 1200, 1400);
    }
  });
});