ブートストラップを使用していますが、ドロップダウンにアニメーションを追加したいと思います。それにアニメーションを追加し、それを離れるときに下にスライドして元に戻したいです。どうすればこれを行うことができますか?
私が試したこと:
次のようにJsドロップダウンファイルを変更します。
ブートストラップを使用していますが、ドロップダウンにアニメーションを追加したいと思います。それにアニメーションを追加し、それを離れるときに下にスライドして元に戻したいです。どうすればこれを行うことができますか?
私が試したこと:
次のようにJsドロップダウンファイルを変更します。
回答:
Bootstrap 3(BS3)に更新すると、必要な機能を結び付けるのに適したJavascriptイベントが多数公開されます。BS3では、このコードはすべてのドロップダウンメニューにあなたが探しているアニメーション効果を与えます:
  // Add slideDown animation to Bootstrap dropdown when expanding.
  $('.dropdown').on('show.bs.dropdown', function() {
    $(this).find('.dropdown-menu').first().stop(true, true).slideDown();
  });
  // Add slideUp animation to Bootstrap dropdown when collapsing.
  $('.dropdown').on('hide.bs.dropdown', function() {
    $(this).find('.dropdown-menu').first().stop(true, true).slideUp();
  });
BS3イベントについてはこちら、具体的にはドロップダウンイベントについてはこちらをご覧ください。
hidden.bs.dropdownイベントを処理する前に遷移が完了するのを待っていないように感じます。
                    また、この小さなコードをスタイルに追加することで、ドロップダウン効果にJavaScriptを使用することを避け、CSS3トランジションを使用することもできます。
.dropdown .dropdown-menu {
    -webkit-transition: all 0.3s;
    -moz-transition: all 0.3s;
    -ms-transition: all 0.3s;
    -o-transition: all 0.3s;
    transition: all 0.3s;
    max-height: 0;
    display: block;
    overflow: hidden;
    opacity: 0;
}
.dropdown.open .dropdown-menu { /* For Bootstrap 4, use .dropdown.show instead of .dropdown.open */
    max-height: 300px;
    opacity: 1;
}
この方法の唯一の問題は、max-heightを手動で指定する必要があることです。非常に大きな値を設定すると、アニメーションが非常に速くなります。
ドロップダウンのおおよその高さがわかっている場合は、チャームのように機能します。それ以外の場合でも、javascriptを使用して正確な最大高さの値を設定できます。
ここに小さな例があります:DEMO
!このソリューションにはパディングに関する小さなバグがあります。JacobStammのコメントとソリューションを確認してください。
pointer-events:none折りたたまれたバージョンに追加point-events: allして、メニューに追加することもできます.show
                    私はそのようなことをしていますが、クリックではなくホバーで..これは私が使用しているコードです。クリックで動作するように少し調整できるかもしれません
$('.navbar .dropdown').hover(function() {
  $(this).find('.dropdown-menu').first().stop(true, true).delay(250).slideDown();
}, function() {
  $(this).find('.dropdown-menu').first().stop(true, true).delay(100).slideUp()
});
<script>のタグが、何も起こらなかった
                    このスレッドをぶつけることができるかどうかはわかりませんが、開いているクラスの削除が速すぎると発生する視覚的なバグの簡単な修正を見つけました。基本的には、slideUpイベント内にOnComplete関数を追加し、すべてのアクティブなクラスと属性をリセットするだけです。このようになります:
結果は次のとおりです。Bootplyの例
Javascript / Jquery:
$(function(){
    // ADD SLIDEDOWN ANIMATION TO DROPDOWN //
    $('.dropdown').on('show.bs.dropdown', function(e){
        $(this).find('.dropdown-menu').first().stop(true, true).slideDown();
    });
    // ADD SLIDEUP ANIMATION TO DROPDOWN //
    $('.dropdown').on('hide.bs.dropdown', function(e){
        e.preventDefault();
        $(this).find('.dropdown-menu').first().stop(true, true).slideUp(400, function(){
            //On Complete, we reset all active dropdown classes and attributes
            //This fixes the visual bug associated with the open class being removed too fast
            $('.dropdown').removeClass('show');
            $('.dropdown-menu').removeClass('show');
            $('.dropdown').find('.dropdown-toggle').attr('aria-expanded','false');
        });
    });
});
スライド&フェード効果の解決策は次のとおりです。
   // Add slideup & fadein animation to dropdown
   $('.dropdown').on('show.bs.dropdown', function(e){
      var $dropdown = $(this).find('.dropdown-menu');
      var orig_margin_top = parseInt($dropdown.css('margin-top'));
      $dropdown.css({'margin-top': (orig_margin_top + 10) + 'px', opacity: 0}).animate({'margin-top': orig_margin_top + 'px', opacity: 1}, 300, function(){
         $(this).css({'margin-top':''});
      });
   });
   // Add slidedown & fadeout animation to dropdown
   $('.dropdown').on('hide.bs.dropdown', function(e){
      var $dropdown = $(this).find('.dropdown-menu');
      var orig_margin_top = parseInt($dropdown.css('margin-top'));
      $dropdown.css({'margin-top': orig_margin_top + 'px', opacity: 1, display: 'block'}).animate({'margin-top': (orig_margin_top + 10) + 'px', opacity: 0}, 300, function(){
         $(this).css({'margin-top':'', display:''});
      });
   });
$(this).css({'margin-top':''});@Vedmantが必要なのかよくわかりません
                    2018ブートストラップ4を更新
Boostrap 4では、.openクラスはに置き換えられました.show。追加のJSやjQueryを必要とせずに、CSSトランジションのみを使用してこれを実装したかったのです...
.show > .dropdown-menu {
  max-height: 900px;
  visibility: visible;
}
.dropdown-menu {
  display: block;
  max-height: 0;
  visibility: hidden;
  transition: all 0.5s ease-in-out;
  overflow: hidden;
}
デモ:https://www.codeply.com/go/3i8LzYVfMF
注:max-heightドロップダウンコンテンツに対応するのに十分な任意の大きな値に設定できます。
margin-top。
                    クリックすると、以下のコードを使用して実行できます
$('.dropdown-toggle').click(function() {
  $(this).next('.dropdown-menu').slideToggle(500);
});
上記のコードを使用していますが、slideToggleによって遅延効果を変更しました。
アニメーションでホバー時にドロップダウンをスライドします。
$('.navbar .dropdown').hover(function() {
    $(this).find('.dropdown-menu').first().stop(true, true).slideToggle(400);
    }, function() {
    $(this).find('.dropdown-menu').first().stop(true, true).slideToggle(400)
    });
拡張された答えは、私の最初の答えだったので、以前に十分な詳細がなかった場合は言い訳になります。
Bootstrap 3.xの場合、私は個人的にCSSアニメーションを好み、animate.cssとBootstrapドロップダウンJavascriptフックを使用しています。かなり柔軟なアプローチを採用した後は、正確な効果が得られない可能性があります。
ステップ1: headタグを使用してanimate.cssをページに追加します。
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.4.0/animate.min.css">
ステップ2:トリガーで標準のブートストラップHTMLを使用します。
<div class="dropdown">
  <button type="button" data-toggle="dropdown">Dropdown trigger</button>
  <ul class="dropdown-menu">
    ...
  </ul>
</div>
ステップ3:次に、2つのカスタムデータ属性をdropdrop-menu要素に追加します。inアニメーションの場合はdata-dropdown-in、outアニメーションの場合はdata-dropdown-out。これらは、fadeInやfadeOutなどのanimate.cssエフェクトにすることができます。
<ul class="dropdown-menu" data-dropdown-in="fadeIn" data-dropdown-out="fadeOut">
......
</ul>
ステップ4:次に、次のJavascriptを追加して、data-dropdown-in / outデータ属性を読み取り、Bootstrap Javascript APIフック/イベント(http://getbootstrap.com/javascript/#dropdowns-events)に反応します。
var dropdownSelectors = $('.dropdown, .dropup');
// Custom function to read dropdown data
// =========================
function dropdownEffectData(target) {
  // @todo - page level global?
  var effectInDefault = null,
      effectOutDefault = null;
  var dropdown = $(target),
      dropdownMenu = $('.dropdown-menu', target);
  var parentUl = dropdown.parents('ul.nav'); 
  // If parent is ul.nav allow global effect settings
  if (parentUl.size() > 0) {
    effectInDefault = parentUl.data('dropdown-in') || null;
    effectOutDefault = parentUl.data('dropdown-out') || null;
  }
  return {
    target:       target,
    dropdown:     dropdown,
    dropdownMenu: dropdownMenu,
    effectIn:     dropdownMenu.data('dropdown-in') || effectInDefault,
    effectOut:    dropdownMenu.data('dropdown-out') || effectOutDefault,  
  };
}
// Custom function to start effect (in or out)
// =========================
function dropdownEffectStart(data, effectToStart) {
  if (effectToStart) {
    data.dropdown.addClass('dropdown-animating');
    data.dropdownMenu.addClass('animated');
    data.dropdownMenu.addClass(effectToStart);    
  }
}
// Custom function to read when animation is over
// =========================
function dropdownEffectEnd(data, callbackFunc) {
  var animationEnd = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend';
  data.dropdown.one(animationEnd, function() {
    data.dropdown.removeClass('dropdown-animating');
    data.dropdownMenu.removeClass('animated');
    data.dropdownMenu.removeClass(data.effectIn);
    data.dropdownMenu.removeClass(data.effectOut);
    // Custom callback option, used to remove open class in out effect
    if(typeof callbackFunc == 'function'){
      callbackFunc();
    }
  });
}
// Bootstrap API hooks
// =========================
dropdownSelectors.on({
  "show.bs.dropdown": function () {
    // On show, start in effect
    var dropdown = dropdownEffectData(this);
    dropdownEffectStart(dropdown, dropdown.effectIn);
  },
  "shown.bs.dropdown": function () {
    // On shown, remove in effect once complete
    var dropdown = dropdownEffectData(this);
    if (dropdown.effectIn && dropdown.effectOut) {
      dropdownEffectEnd(dropdown, function() {}); 
    }
  },  
  "hide.bs.dropdown":  function(e) {
    // On hide, start out effect
    var dropdown = dropdownEffectData(this);
    if (dropdown.effectOut) {
      e.preventDefault();   
      dropdownEffectStart(dropdown, dropdown.effectOut);   
      dropdownEffectEnd(dropdown, function() {
        dropdown.dropdown.removeClass('open');
      }); 
    }    
  }, 
});
ステップ5(オプション):アニメーションを高速化または変更する場合は、次のようにCSSを使用して行うことができます。
.dropdown-menu.animated {
  /* Speed up animations */
  -webkit-animation-duration: 0.55s;
  animation-duration: 0.55s;
  -webkit-animation-timing-function: ease;
  animation-timing-function: ease;
}
興味のある人がいれば、より詳細な記事を書き、ダウンロードしてください:記事:http://bootbites.com/tutorials/bootstrap-dropdown-effects-animatecss
それがお役に立てば幸いです。この2回目の記事には、トムに必要な詳細レベルが含まれています。
$('.navbar .dropdown').hover(function() {
    $(this).find('.dropdown-menu').first().stop(true, true).slideDown();
}, function() {
    $(this).find('.dropdown-menu').first().stop(true, true).slideUp();
});
このコードは、ホバー時にドロップダウンを表示する場合に機能します。
私は変更.slideToggleに.slideDown&.slideUp、および削除(400)のタイミングを
これは、jQueryうまく機能するを使用した簡単な解決策です。
$('.dropdown-toggle').click(function () {
    $(this).next('.dropdown-menu').slideToggle(300);
});
$('.dropdown-toggle').focusout(function () {
    $(this).next('.dropdown-menu').slideUp(300);
})
スライドアニメーションの切り替えはクリックすると発生し、フォーカスを失うと常に上にスライドします。
300値を任意の値に変更します。数値が小さいほど、アニメーションが速くなります。
編集:
このソリューションは、デスクトップビューでのみ機能します。モバイルでうまく表示するには、さらに変更が必要です。
dropdown-toggle)、再び消えます。つまり、サブメニュー項目を選択できません
                    BOOTSTRAP3リファレンス
私はこのスレッドの解決策にとらわれ続け、それは毎回私を詰め込むので追加されました。
基本的に、BSドロップダウンはすぐに削除します .open親からクラスをため、上にスライドしても機能しません。
slideDown();の他のソリューションと同じビットを使用します。
// ADD SLIDEUP ANIMATION TO DROPDOWN //
$('.dropdown').on('hide.bs.dropdown', function(e){
  e.preventDefault();
  $(this).find('.dropdown-menu').first().stop(true, true).slideUp(300, function(){
    $(this).parent().removeClass('open');
  });
});
Bootstrap 3の場合、上記の回答のこのバリエーションにより、モバイルslideUp()アニメーションがスムーズになります。Bootstrapは.openトグルの親からクラスをすぐに削除するため、上記の回答はアニメーションが途切れます。このコードは、slideUp()アニメーションが終了するまでクラスを復元します。
// Add animations to topnav dropdowns
// based on https://stackoverflow.com/a/19339162
// and https://stackoverflow.com/a/52231970
$('.dropdown')
  .on('show.bs.dropdown', function() {
    $(this).find('.dropdown-menu').first().stop(true, true).slideDown(300);
  })
  .on('hide.bs.dropdown', function() {
    $(this).find('.dropdown-menu').first().stop(true, false).slideUp(300, function() {
      $(this).parent().removeClass('open');
    });
  })
  .on('hidden.bs.dropdown', function() {
    $(this).addClass('open');
  });
主な違い:
hide.bs.dropdown、イベントハンドラ私が使用しています.stop()(のデフォルト値をfalse(2番目の引数のために)jumpToEnd)hidden.bs.dropdownイベントハンドラは、復元し.open、ドロップダウントグルの親にクラスを、そしてそれはかなりすぐにクラスが最初に除去された後にこれを行います。その間、slideUp()アニメーションはまだ実行されており、上記の回答と同様に、「the-animation-is-completed」コールバックが最終的に削除されます。.openクラスを親から。執筆時点で、元の回答は8歳になりました。それでも、元の質問に対する適切な解決策はまだないように感じます。
それ以来、ブートストラップは大きく進歩し、現在は4.5.2になっています。ます。この回答は、まさにこのバージョンに対応しています。
他のすべての回答の問題は、show.bs.dropdown/にフックしている間hide.bs.dropdown、フォローアップイベントshown.bs.dropdown/hidden.bs.dropdownが早すぎる(アニメーションがまだ進行中)か、抑制されているためにまったく起動しない(e.preventDefault())ということです。
Bootstrapsクラスのshow()との実装にはいくつかの類似点があるため、元の動作を模倣するときにそれらをグループ化し、QoLヘルパー関数をとに少し追加しました。Bootstrapと同じ方法で/イベントを作成します。このイベントは、アニメーションが完了した後に発生します-予想どおりです。hide()DropdowntoggleDropdownWithAnimation()showDropdownWithAnimation()hideDropdownWithAnimation()
toggleDropdownWithAnimation()shown.bs.dropdownhidden.bs.dropdown
/**
 * Toggle visibility of a dropdown with slideDown / slideUp animation.
 * @param {JQuery} $containerElement The outer dropdown container. This is the element with the .dropdown class.
 * @param {boolean} show Show (true) or hide (false) the dropdown menu.
 * @param {number} duration Duration of the animation in milliseconds
 */
function toggleDropdownWithAnimation($containerElement, show, duration = 300): void {
    // get the element that triggered the initial event
    const $toggleElement = $containerElement.find('.dropdown-toggle');
    // get the associated menu
    const $dropdownMenu = $containerElement.find('.dropdown-menu');
    // build jquery event for when the element has been completely shown
    const eventArgs = {relatedTarget: $toggleElement};
    const eventType = show ? 'shown' : 'hidden';
    const eventName = `${eventType}.bs.dropdown`;
    const jQueryEvent = $.Event(eventName, eventArgs);
    if (show) {
        // mimic bootstraps element manipulation
        $containerElement.addClass('show');
        $dropdownMenu.addClass('show');
        $toggleElement.attr('aria-expanded', 'true');
        // put focus on initial trigger element
        $toggleElement.trigger('focus');
        // start intended animation
        $dropdownMenu
            .stop() // stop any ongoing animation
            .hide() // hide element to fix initial state of element for slide down animation
            .slideDown(duration, () => {
            // fire 'shown' event
            $($toggleElement).trigger(jQueryEvent);
        });
    }
    else {
        // mimic bootstraps element manipulation
        $containerElement.removeClass('show');
        $dropdownMenu.removeClass('show');
        $toggleElement.attr('aria-expanded', 'false');
        // start intended animation
        $dropdownMenu
            .stop() // stop any ongoing animation
            .show() // show element to fix initial state of element for slide up animation
            .slideUp(duration, () => {
            // fire 'hidden' event
            $($toggleElement).trigger(jQueryEvent);
        });
    }
}
/**
 * Show a dropdown with slideDown animation.
 * @param {JQuery} $containerElement The outer dropdown container. This is the element with the .dropdown class.
 * @param {number} duration Duration of the animation in milliseconds
 */
function showDropdownWithAnimation($containerElement, duration = 300) {
    toggleDropdownWithAnimation($containerElement, true, duration);
}
/**
 * Hide a dropdown with a slideUp animation.
 * @param {JQuery} $containerElement The outer dropdown container. This is the element with the .dropdown class.
 * @param {number} duration Duration of the animation in milliseconds
 */
function hideDropdownWithAnimation($containerElement, duration = 300) {
    toggleDropdownWithAnimation($containerElement, false, duration);
}
アニメーションでドロップダウンを表示/非表示にするための適切なコールバックを作成したので、実際にこれらを正しいイベントにバインドしましょう。
他の回答でよく見られる間違いは、イベントリスナーを要素に直接バインドすることです。これは、イベントリスナーの登録時に存在するDOM要素に対しては正常に機能しますが、後で追加される要素にはバインドされません。
そのため、一般的にdocument:に直接バインドする方が良いでしょう。
$(function () {
    /* Hook into the show event of a bootstrap dropdown */
    $(document).on('show.bs.dropdown', '.dropdown', function (e) {
        // prevent bootstrap from executing their event listener
        e.preventDefault();
        
        showDropdownWithAnimation($(this));
    });
    /* Hook into the hide event of a bootstrap dropdown */
    $(document).on('hide.bs.dropdown', '.dropdown', function (e) {
        // prevent bootstrap from executing their event listener
        e.preventDefault();
          
        hideDropdownWithAnimation($(this));
    });
});