WebデザインWordPress

jQuery window.scrollTop() がWordPressで正常に動かない時の対処法

Webデザイン

10年以上稼働中のWordpressで作成したサイトの「ページトップへ戻る」ボタンが正常に動かなくなっていたので原因を調べたのですが、原因と対処法の備忘録です。

原因:Akamaiのせいでした

最初に今回の原因を述べますと、Akamaiのせいでした。

Akamaiとは…
サーバーやネットワークなどインターネットを根幹で支える世界的企業。大容量のコンテンツをインターネット上で大量配信するためのネットワーク(CDN)やセキュリティに関する事業が主軸。

header.phpの記述を確認していましたら、記述した覚えのない以下の記述がありました。

<script src="https://basefile.akamaized.net/copen/5a83fd2862d15/slidebars_v1.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://basefile.akamaized.net/copen/5a83fd372d9e9/slidebars_v1.css">
<script type="text/javascript" src="https://basefile.akamaized.net/stockh0lm/5ab536bcb23cf/Velocity.js"></script>
<script type="text/javascript" src="https://basefile.akamaized.net/stockh0lm/5ab7bdde91e65/jquery.inview.min.js"></script>

こちらで読み込んでいるCSSに window.scrollTop() が効かなくなってしまう原因とされている以下の記述がありました。

  • body に overflow:hidden を指定している
  • html や body に width・height:100% を指定している

そもそも記述した覚えがない…ので上記のAkamaiの記述をまるっと削除したところ、window.scrollTop() が正常に値を取得できるようになり問題解決しました。

問題の解決はしましたが、そもそも10年以上前のjQueryコードのままでしたので、jQueryのバージョンなどなど最新バージョンに差し替えてしまおうということで以下の対策をしました。

jQueryのバージョンを変更

はじめは、jQuery-1.8.3を利用していました。
が、色々な部分でバグが起きていたのでちょうどよい機会だなと思い、2023年9月時点で最新版のjQuery-3.7.0を適応させてみました。

jQuery
jQuery: The Write Less, Do More, JavaScript Library

以下はCDNを使う方法です。以下のようにhead内に記述します。

 <head>
  <title>ページのタイトル</title>
  <meta charset="UTF-8">
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
 </head>
Download jQuery | jQuery
jQuery: The Write Less, Do More, JavaScript Library

Google CDN、Microsoft CDNなどなど…4種類ほどございますが、一番有名どころのGoogle CDNを利用しています。

jQueryコードを改修

jQueryを最新バージョンに変更しましたので、コードも改修しました。
修正前のコードと修正後のコードを以下に載せておきます。

▽ビフォー

$(function() {
    var topBtn = $('#back-top');
    topBtn.hide();
    //スクロールが100に達したらボタン表示
    $(window).scroll(function() {
        if ($(this).scrollTop() > 100) {
            topBtn.fadeIn();
        } else {
            topBtn.fadeOut();
        }
    });
    //スクロールしてトップ
    topBtn.click(function() {
        $('body,html').animate({
            scrollTop: 0,
        }, 500);
        return false;
    });
});

▽アフター

jQuery(function($) {
    const topBtn = $('#back-top');
    topBtn.hide();
    //スクロールが100に達したらボタン表示
    $(window).on('scroll', function() {
        if ($(this).scrollTop() > 100) {
            topBtn.fadeIn();
        } else {
            topBtn.fadeOut();
        }
    });
    //スクロールしてトップ
    topBtn.on('click', function() {
        $('body,html').animate({ scrollTop: 0 }, 500);
        return false;
    });
});

変更した箇所は2箇所です。

  • var → const
  • click() → on('click', function())

まず1つ目の変更点。
変数を指定するための var は、同じ変数名が複数あってもエラーにならなかったり、ブロックスコープに対応できないなど、バグが発生しやすい仕様となっていたため非推奨となっていました。

そのため、 再代入できるが、再宣言はできない let 、または再代入も再宣言もできない const で定義しなおします。再代入の必要がない場合は、極力 const を使うと間違いなさそうなので const を使っています。

まだ使ってる?今は非推奨となったJavaScriptの書き方
いつも何気なく使っていたコードをふと調べ直してみると、知らないうちに「Deprecated(非推奨)」と書かれている…なんてこともありますよね。今回はJavaScriptを書いていて出くわした非推奨となったものをいくつか

そして2つ目の変更点。
jQuery1.7以降に追加された "on" は、さまざまなイベントへの汎用性や複数のイベントを設定できるため非常に便利です。

jQuery 便利なonを使おう(on click) - Qiita
対象者click()とon('click', function())の違いが分からない人。click()しか使ったことのない人。何も考えずにon('click', function())を使っ…

WordPressでjQueryを使う場合は正しい書き方に修正する

jQueryは通常「$」をつけてコードを書きますが、WordPressではデフォルトで読み込まれるjQueryは、コンフリクト(衝突)を避けるための「jQuery.noConflict()」という関数の実行により、jQueryで使う「$」は通常、使えなくなっています。
そのため、「jQuery」の記述を使わなくてはなりません。

ただ「$」で書く部分を「jQuery」にすべて書き換えるのは少々面倒なので、通常は次で紹介するような書き方でスコープを作り、その中で「$」を使って書くことが一般的となっています。

▼WordPressでjQueryを読み込む方法

jQuery(function($) {
  // ここにスクリプトの処理を記述
});

▼以下のサイト様が大変詳しく記載されております。

WordPressでjQueryの正しい使い方・書き方
WordPressでjQueryを使いたい方向け。本記事では、WordPressでjQueryのスクリプトを正しく書く方法を解説します。WordPressのjQueryでは「$」をそのまま使うと正常に動かないので注意が必要です。

scrollTop() メソッドの対象要素を見直す

jQueryでスクロール位置を取得するには、「scrollTop()」メソッドを使用します。
「scrollTop()」メソッドの記述方法は以下の通り。

対象要素.scrollTop();

ブラウザ全体のスクロール位置を取得するには対象要素に window を指定します。

$(window).scrollTop();

上記のように scrollTop() メソッドの対象要素が window ではなく body にしている場合に Chrome と IE と Firefox では、値を取得できないバグがあるようです。

ブラウザ判別して scrollTop を使用するタグを切り替える方法もあるようです。

ただし、webkit系 の chrome では、バージョン61以降は html 要素で取得できますが、古いバージョンでは body 要素を使う必要があるのでブラウザ判定ができなくなります…。

// safariやバージョン61より前のchrome
document.body.scrollTop 

// firefoxやバージョン61以降のchrome,ie,edgeなど
document.documentElement.scrollTop 

この問題点のより良い解決方法として scrollingElement プロパティを使う方法があります。scrollingElement プロパティを使えば body 要素と html 要素を分ける処理が不要になります。スクロール要素がない場合には null となるようです。

// documentのスクロール要素取得
const scrollElement = document.scrollingElement;
// スクロール位置の取得 
const scrollTopValue = scrollElement.scrollTop; 

だがしかし…。上記の scrollingElement プロパティは IE では使えないようです…(泣)
以下のサイト様がとても詳しく説明して下さっていました。

JavaScriptで簡単にスクロール位置を取得する|canonono.com
webサイト作成時にスクロール位置の取得することが多いので、今後のために方法をまとめました。結論を先に書くとdocume

まとめ

「ページトップへ戻る」というプログラムだけでも、動かなくなる原因や対処方法がたくさんあって、どこを直したらいいのか分からなくなってしまいますね…(泣)
色々な原因が複合的に絡んでいる場合もあるので、こちらの備忘録が少しでもお役に立てましたら嬉しいです。

以下、今回のエラーについて参考にさせて頂いた記事になります。
本当にみなさんの記事にいつも助けられています。ありがとうございます。

window の scroll イベントがうまく取れない | zu-min.com
JavaScript でスクロールイベントをトリガーにする処理を書いたのですが、うまく動かなかったので調査しま
【CSS+JS】現在のスクロール量を確実に取得する(プロパティ対応状況まとめ)
はじめに JavaScriptで現在のスクロール量を取得するためのプロパティはたくさんあります。種類がありすぎるため、かえってどれを使えばいいのかいまいちわからないという人も多いかと思います。 本記事では、各プロパティのブラウザ対応状況まと...

comment

タイトルとURLをコピーしました