11

序文

次の 2 つの要件を満たすナビゲーション メニューを備えたレスポンシブ Web サイトを作成しようとしています。

  1. ナビゲーションは、水平に配置された通常のブラウザ ウィンドウで完全に表示されます。
  2. ナビゲーションは、モバイル デバイスと小さな画面用の切り替え可能な垂直メニューになり、「開いた」状態と「閉じた」状態の間でアニメーション化されます。

モバイル デバイス (特に iOS) でのパフォーマンスを向上させたいと考えています。つまり、アニメーションでは、GPU で高速化された translate3d 変換CSS トランジションを使用する必要があります。

私の問題

これを設定するのは簡単で、ほとんどの場合うまく機能します。と を使用z-index: 1して、デフォルトの閉じた状態でtransform: translate3d(0,-100%,0)ヘッダーの背後にあるメニューを非表示にしてから、メニューを開いた状態にアニメーション化しました。z-index: 2transform: translate3d(0,0,0)

しかし、問題が 1 つあります。Chrome ブラウザ ウィンドウのサイズを変更してモバイル メディア クエリが起動すると、メニューが開いた状態から閉じた状態にアニメーション化されます。

ブラウザー ウィンドウのサイズを 600px 未満に変更して、実際の問題を確認します。

なぜこれが起こっているのかはわかっていると思います。モバイル メディア クエリが起動すると、ブラウザはそれ.navが現在アクティブではないことを認識し、デフォルトの閉じた状態にアニメートします。display:noneさまざまなメディア クエリの状態に対してとを試してみましdisplay:blockたが、アニメーションが完全に壊れているようです。

ブラウザ ウィンドウのサイズが変更されたときに、ナビゲーション メニューの「閉じる」アニメーションが起動しないようにするにはどうすればよいですか?

4

3 に答える 3

1

GionaJanusz Kacalakからの回答 (および Justin Bull のコメント) を組み合わせることで、コードをさらに最適化して、ナビゲーション バーが開いた状態から閉じた状態にアニメーション化されないようにすることができます (最初だけでなく、Giona のコードが行うことです)。 .

function toggle() {
  var navbar = $(".nav");
  if (navbar.hasClass("active")) {
    // Closing the nav bar.
    navbar.removeClass("active");
    // Listening for a transition.
    // Use `.one` here because we only want this to be called once.
    navbar.one(whichTransitionEvent(), function() {
      // Remove animation property after the nav bar is closed.
      navbar.removeClass("activated");
    });
  } else {
    // Opening the nav bar.
    navbar.addClass("activated").addClass("active");
  }
}

// Ref: https://davidwalsh.name/css-animation-callback
function whichTransitionEvent() {
  var t;
  var el = document.createElement('fakeelement');
  var transitions = {
    'transition': 'transitionend',
    'OTransition': 'oTransitionEnd',
    'MozTransition': 'transitionend',
    'WebkitTransition': 'webkitTransitionEnd'
  };

  for (t in transitions) {
    if (el.style[t] !== undefined) {
      return transitions[t];
    }
  }
}
body { margin: 0; }
.toggle { display: none; }
.nav { list-style-type: none; margin: 0; padding: 0; }
.nav li { float: left; margin: 0; padding: 20px; background: #fdd; }
.nav li:nth-child(2n) { background: #dfd; }

@media only screen and (max-width: 599px)
{
    .toggle {
        display: block;
        position: relative;
        z-index: 2;
        padding: 20px;
        background: #eee;
    }
    .nav li {
        display: block;
        float: none;
    }
    .nav {
        display: block;
        position: relative;
        z-index: 1;
        transform: translate3d(0,-100%,0);
		-webkit-transform: translate3d(0,-100%,0);
    }
    .nav.active {
        transform: translate3d(0,0,0);
		-webkit-transform: translate3d(0,0,0);
    }
    .nav.activated {
        transition: transform 400ms linear;
		-webkit-transition: -webkit-transform 400ms linear;
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<a href="#" class="toggle" onclick="javascript:toggle();return false;">Toggle menu</a>
<ul class="nav">
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
    <li>Four</li>
    <li>Five</li>
</ul>

于 2018-12-31T01:38:26.710 に答える