2015-05-14 4 views
3

У меня работает аккордеон, и он работает очень хорошо, когда вы спускаетесь по аккордеон, но по мере того, как вы возвращаетесь, это своего рода глупость.Навигация, чтобы настроить пользовательский jQuery аккордеон

Я хочу сделать это так, когда вы нажмете на мачту, он откроет содержимое внутри этого мачты и привяжет верхнюю часть страницы к вершине мачты. Я знаю, что мне нужно делать в псевдокоде, но я не уверен, что на самом деле делать с кодом.

Вот мой 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

Проблема в том, что место в вашем коде, где вам нужно знать индекс .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

+0

ДА !! Большое спасибо за вашу помощь, это именно то, что я пытался сделать! – realjoet

+0

Могу ли я спросить, что именно это делает? Супер счастлив, что это работает, просто любопытно, что он делает в этом случае, чтобы я мог учиться! – realjoet

+0

Извините, я должен был бы высказать здесь замечание. Это просто проверка наличия активного элемента. Если в настоящее время нет открытой панели, мы не хотим вычитать 200 из topPos, так как 200 предназначен для учета высоты открытой панели над новой. – bowheart

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); 
    } 
    }); 
}); 
Смежные вопросы