导航 dom 以调整自定义 jQuery 手风琴

Navigating dom to adjust custom jQuery 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
} 

但其中 none 有效。有什么建议吗??

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

解决方法:移动这段代码

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

到事件处理程序的末尾,就在您将 class .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

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

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

如果需要,请查看我的 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);
    }
  });
});