【スポンサーリンク】

[JavaScript]下にスクロールするとヘッダーメニューを半透明にするようにした

[JavaScript]下にスクロールするとヘッダーメニューを半透明にするようにした
  • Xのタイムラインを見ていたら、画面のメニューバーの透過度が上下のスクロールに応じて変化していることに気づきました。
  • 少し下にスクロールすると半透明になり、少し上にスクロールすると元に戻っています。
  • 自分のサイトのヘッダーメニュー(mobile-header-menu-buttons)でも、このような処理をするように、JavaScriptを作りたいと思います。
[JavaScript]下にスクロールするとヘッダーメニューを半透明にするようにした

画面内の情報の表示範囲が増えるからです。

\記事が役に立ったらシェアしてね/
【スポンサーリンク】

1. javascript.jsとstyle.css

機能

ユーザーがページを下にスクロールするとヘッダーメニューが半透明になり、上にスクロールするか、ヘッダーメニューをタッチすると、ヘッダーメニューが完全に不透明になります。

javascript.jsとstyle.css

テーマのjavascript.jsに以下のコードを追加しました。
これで、全ページでスクリプトが動作します。

/** 下にスクロールするとヘッダーメニューを半透明にするようにした 2024-05-12 */
let lastScrollPosition = 0;

const headerMenu = document.querySelector('.mobile-header-menu-buttons');

window.addEventListener('scroll', function() {
  const scrollPosition = window.pageYOffset;

  if (scrollPosition > lastScrollPosition) {
    // 下にスクロールした場合
    headerMenu.style.opacity = '0.5';
  } else {
    // 上にスクロールした場合
    headerMenu.style.opacity = '1';
  }

  lastScrollPosition = scrollPosition;
});

headerMenu.addEventListener('touchstart', function() {
  headerMenu.style.opacity = '1';
});

また、style.cssに追加します。

.mobile-header-menu-buttons {
  transition: opacity 0.3s ease;
}
javascript.jsとstyle.css

2. スクリプトの説明

このスクリプトでは、スクロールとタッチイベントに応じて、ヘッダーメニューの透明度を変更する機能を実装しています。

まず、変数を準備します。

  • lastScrollPosition変数を宣言し、初期値を0に設定します。この変数は、前回のスクロール位置を保持するために使用されます。
  • 次に、.mobile-header-menu-buttonsクラスを持つ要素を選択し、headerMenu変数に代入します。

そして、ウィンドウのスクロールイベントにリスナーを追加します。
スクロールが発生すると、以下の処理が行われます。

  1. 現在のスクロール位置をscrollPosition変数に取得します。
  2. scrollPositionlastScrollPositionより大きい場合、下にスクロールしたと判断されます。この場合、headerMenuの不透明度を0.5に設定し、半透明にします。
  3. それ以外の場合、上にスクロールしたと判断されます。この場合、headerMenuの不透明度を1に設定し、完全に不透明にします。
  4. 現在のスクロール位置をlastScrollPositionに保存します。次のスクロールイベントで比較するために使用されます。

最後に、headerMenuにタッチイベントのリスナーを追加します。
headerMenuがタッチされると、すぐに完全に不透明に戻ります。

CSSでは、opacity(透過度)のプロパティが変更された場合、0.3秒かけてスムーズに変化するように「transition: opacity 0.3s ease;」を追加しています。

3. 【追記】透明度の調整とクリック操作への対応(2024-05-17)

当初、ヘッダー要素を半透明にしていましたが、見えにくいことに気づきました。
そこで、半透明ではなく完全に透明に変更しました。

また、パソコンでは、クリックに反応しないという問題がありました。
そのため、タッチ操作とクリック操作の両方に対応できるように、handleEvent関数を用意しました。

let lastScrollPosition = 0;

const headerMenu = document.querySelector('.mobile-header-menu-buttons');

window.addEventListener('scroll', function() {
  const scrollPosition = window.pageYOffset;

  if (scrollPosition > lastScrollPosition) {
    // 下にスクロールした場合
    headerMenu.style.opacity = '0';
  } else {
    // 上にスクロールした場合
    headerMenu.style.opacity = '1';
  }

  lastScrollPosition = scrollPosition;
});


function handleEvent(event) {
    if (event.type === 'touchstart') {
        event.preventDefault();
    }
    headerMenu.style.opacity = '1';
}

headerMenu.addEventListener('touchstart', handleEvent);
headerMenu.addEventListener('click', handleEvent);

ただし、タッチデバイスでは、タッチ時にタッチスタートイベントとクリックイベントの両方が発火してしまうと思って、preventDefault()を使ってタッチイベントのデフォルトの動作をキャンセルし、タッチ時には1回だけ処理が実行されるようにしました。

3-1. 【追記】スクロール量が20px以上の場合にのみ透過度を変更(2024-05-18)

しかし、確認してみたらメニューがタッチ操作に反応しなくなってしまいました。
そこで、preventDefault()は削除しました。

また、scrollThresholdを指定して、スクロール閾値を超えたときに透明化処理を戻すことにしました。

/** 下にスクロールするとヘッダーメニューを半透明にするようにした 2024-05-12 
 * 2024-05-17: メニューをクリックしたときの反応
 * 2024-05-18: スクロール量が20px以上の場合にのみ透過度を変更
*/
let lastScrollPosition = 0;

const headerMenu = document.querySelector('.mobile-header-menu-buttons');

window.addEventListener('scroll', function() {
  const scrollPosition = window.pageYOffset;
  const scrollThreshold = 20; // スクロールしきい値(px)を設定
  
  if (scrollPosition > lastScrollPosition + scrollThreshold) {
    // 下にスクロールした場合
    headerMenu.style.opacity = '0';
    lastScrollPosition = scrollPosition;
  }
  if (scrollPosition < lastScrollPosition - scrollThreshold) {
    // 上にスクロールした場合
    headerMenu.style.opacity = '1';
    lastScrollPosition = scrollPosition;
  } 


});


function handleEvent(event) {
    headerMenu.style.opacity = '1';
}

headerMenu.addEventListener('touchstart', handleEvent);
headerMenu.addEventListener('click', handleEvent);

QRコードを読み込むと、関連記事を確認できます。

[JavaScript]下にスクロールするとヘッダーメニューを半透明にするようにした
【スポンサーリンク】
タイトルとURLをコピーしました