なぜこれが起こっているのかはわかっていると思いますが、それに取り組む最善の方法はわかりません。参照できるjsFiddleは次のとおりです。
jsFiddle でサブメニューを開いて閉じようとし (リンクの横にある [+] アイコンをクリック)、完全に閉じる前に再度開くと、スタックします。ここでメニューを開き、その子サブメニューの 1 つを開こうとすると、その親がそれに対応するように拡張されていないことがわかります。
この問題は、hide
手順中にjQuery
インラインの高さが要素に適用され、アニメーションが終了する前にそれを開こうとすると、要素の最終的な高さと見なされるために発生すると考えられます。
最初に各要素の高さを保存し、それを使用してアニメーション化することを検討しましたが、このアプローチの問題は、サブメニューが開いているかどうかに応じて、サブメニューの高さを持つメニューが常に変化し、この値が決して定数ではありません。
要素のインラインの高さを無視し、実際の高さを計算するようにjQueryに指示する方法はありますか?
使用した jQuery は次のとおりです。HTML と CSS については、かなり長いので jsFiddle を参照してください。
jQuery(document).ready(function($){
var legacyMode = $('html').hasClass('oldie');
var titles = {normal: "Show sub-topics", active: "Hide sub-topics"};
var sub_sections = $('ul#map li:has(ul.child)');
sub_sections.each(function() {
if (!$(this).find('li.active').length && !$(this).hasClass('active')) {
var toggle = $('<a class="toggle" href="#"></a>').attr('title', titles.normal).insertBefore($(this).children('ul.child'));
var child = $(this).children('ul.child').hide();
toggle.data('container', this);
}
});
$('a.toggle').click(function (event) {
event.preventDefault();
var target = $(this).siblings('ul.child');
if($(this).hasClass('active')) {
toggleDisplay(target, false);
$(this).removeClass('active').attr('title', titles.normal);
} else {
toggleDisplay(target, true);
$(this).addClass('active').attr('title', titles.active);
}
function toggleDisplay(target, on) {
var mode = (on) ? "show" : "hide";
if (!legacyMode) {
target.stop(true, false).animate({height: mode, opacity: mode}, 500);
} else {
// Omits opacity to avoid using proprietary filters in legacy browsers
target.stop(true, false).animate({height: mode}, 500);
}
}
});
});