web-dev-qa-db-ja.com

jQuery-要素をアンカーリンクで上部ではなく画面の中央にスクロールします

アンカーリンクを介してさまざまなセクション要素にスムーズにスクロールする固定位置ナビゲーションバーを備えた1ページのサイトを構築しています。要素へのスクロールのデフォルトの動作は、ブラウザウィンドウの上部に配置することです。代わりに、要素を画面の中央に揃えたいです。

ナビゲーションにこのマークアップを使用します。

<nav class="main-nav">
  <a href="#top">Top</a>
  <a href="#section-1">Section 1</a>
  <a href="#section-2">Section 2</a>
  <a href="#section-3">Section 3</a>
  <a href="#section-4">Section 4</a>
  <a href="#section-5">Section 5</a>
</nav>

kswedbergのjQuery Smooth Scrollプラグイン を使用してスクロールをスムーズにします。私はこれを次のように開始します:

$('.main-nav a').smoothScroll({
  offset: 0,
  speed: 700
});

オフセットを((window).height / 2) - (element height / 2)に設定して、垂直方向の中央に配置したいのですが、適切に実行する方法を見つけるのに助けが必要です。

私はそれが必要です:

  • ウィンドウの高さを取得し、それを2で割る
  • 要素の高さを取得し、それを2で割る
  • 前者を後者から引きます
  • 可能であれば、要素がウィンドウよりも高い場合、デフォルトで上部に揃えます

アンカーリンクが多数あるため、リンクをクリックしたアンカーリンクの要素の高さを確認するか、すべてのアンカーリンクに対してsmoothScrollを開始する必要があると思います。

誰もこれを行う方法を知っていますか?

33
Nils Kaspersson

APIは、要素にバインドされていない smoothScroll を実行する方法を提供します。アンカータグのonclickイベント内でこのメソッドを実行すると、ターゲットにアクセスできるようになります。次に、目的の位置に到達するために必要なものを計算できます。 offsetは相対オフセットではなく絶対オフセットになったため、スクロールする正確な位置を取得する必要があります。

$('.main-nav a').on('click', function(e) { 
  var el = $( e.target.getAttribute('href') );
  var elOffset = el.offset().top;
  var elHeight = el.height();
  var windowHeight = $(window).height();
  var offset;

  if (elHeight < windowHeight) {
    offset = elOffset - ((windowHeight / 2) - (elHeight / 2));
  }
  else {
    offset = elOffset;
  }

  $.smoothScroll({ speed: 700 }, offset);
  return false;
});
33
Steven Lambert

ScrollTo()を使用してプレーンなJQueryでそれを行う方法を次に示します。

 $('.main-nav a').on('click', function(e) { 
  var el = $( e.target.getAttribute('href') );
  var elOffset = el.offset().top;
  var elHeight = el.height();
  var windowHeight = $(window).height();
  var offset;

  if (elHeight < windowHeight) {
    offset = elOffset - ((windowHeight / 2) - (elHeight / 2));
  }
  else {
    offset = elOffset;
  }
  var speed = 700;
  $('html, body').animate({scrollTop:offset}, speed);
});

これはstrakerのコードとこの質問からのコードの組み合わせです。 jQuery scrollTo-ウィンドウの垂直方向の中央Div

33
Santiago Angel

ここでそれを行う確実な方法

var $window = $(window),
    $element = $('.my-element'),
    elementTop = $element.offset().top,
    elementHeight = $element.height(),
    viewportHeight = $window.height(),
    scrollIt = elementTop - ((viewportHeight - elementHeight) / 2);

    $window.scrollTop(scrollIt);
1
ameer nagvenkar

私が最終的に使用したソリューションは次のとおりです。クリックしたときに中央に配置する必要のあるすべての要素を保持するスクロール可能な親コンテナがある場合は、非常に便利です。

コードスニペットを実行して、動作を確認してください。

$('#main-nav a').on('click', function(e) { 
  var el = $(this), parentEl = $('#main-nav');
  
  var elOffset = el.offset().top + parentEl.scrollTop();
  var elHeight = el.height();
  var parentHeight = parentEl.height();
  
  var offset = elOffset - ((parentHeight - elHeight) / 2);
 
  parentEl.animate({scrollTop:offset}, 700);
});
#main-nav {
  height: 200px;
  width: 200px;
  outline: 1px solid red;
  overflow: hidden;
}

#main-nav a {
  height: 50px;
  background: blue;
  display: block;
  margin-bottom: 5px;
  color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav id="main-nav">
  <a href="#top">Top</a>
  <a href="#section-1">Section 1</a>
  <a href="#section-2">Section 2</a>
  <a href="#section-3">Section 3</a>
  <a href="#section-4">Section 4</a>
  <a href="#section-5">Section 5</a>
  <a href="#section-6">Section 6</a>
  <a href="#section-7">Section 7</a>
  <a href="#section-8">Section 8</a>
  <a href="#section-9">Section 9</a>
  <a href="#section-10">Section 10</a>
</nav>
0
Andy