ダミー

【jQuery】slideToggle を使ったドロワーメニューが WordPressで不具合に

2019年6月12日

サイトの制作では毎回ナビゲーションをどうしようか悩みますね。よく使われるナビゲーションの一つが、ハンバーガークリックで上から降りて来るドロワーメニュー。jQueryのslideToggleを使い、ハンバーガークリックで上から降りてきて、×クリックで上に戻るタイプです。マークアップ時は正常に動いていたのに、Wordpress適用したら、なぜか動きがおかしくなりました。原因は何でしょうか?

正常なドロワーメニュー

今回作るドロワーメニューとはどんなものかまずは
正常なドロワーメニュー
をご覧ください。

実装はhead内に次の2行を書くだけのシンプルな構成です。
1行目でjQueryを呼び、2行目で独自jsファイルcommon.jsを読み込んでいます。

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="js/common.js"></script>

common.jsの内容もとてもシンプル。

$(function(){
  $('.menu-trigger').on('click',function(){
    $(this).toggleClass('active');
    $('.g-nav').slideToggle();
  });
  $('.g-nav a').on('click',function(){
    $('.menu-trigger').toggleClass('active');
    $('.g-nav').slideToggle();
  });
});

こんなシンプルなドロワーメニュー、「他に移植して動かなくなるかも」なんて心配は皆無ですね!

不具合のドロワーメニュー

ところが、Wordpressで構築したページで妙なことになりました。
どうなったかは以下をご覧ください。

不具合を再現したドロワーメニューはこちら
(このサンプルページはWordpressで作ったページではありません。Wordpressで起こった不具合を、静的htmlに手入力し再現したものです)

ここで確認です。
・テーマのテンプレートheader.phpの内で、ちゃんと上の2行は読み込んでいる。
・js、css、htmlはいずれも正常に動いているものと同じである。
何が違うのか、不具合の理由がまったく分からない・・・

一瞬降りてくるけどすぐに戻ってしまうドロワーメニュー、ということはToggleが2回実行されている?
いやそんなはずはない、と思いつつWordpressによって書き出されたソースを1行ずつ見ていくと・・・

重複読み込み箇所がありました!

なんと

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="js/common.js"></script>

を2回読み込んでいたのです!

何故2回読み込んでいるのかわかりませんでしたが、とにかく1セットを削除してみたい。それで自分で書いたheader.phpからこの2行を削除してみると、正常に動くようになりました。

重複読み込みが不具合の原因?

ここで単純に「2回読み込んでいるのが悪いのね」と考え、試しに静的htmlの<head>内にあえて

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="js/common.js"></script>

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="js/common.js"></script>

と書いてみました。

すると、どうでしょう?
ドロワーメニュー正常に動くのです!

つまり、jqueryやjavascriptの重複読み込みが、今回の不具合の原因ではありませんでした。
もちろん重複は無駄なので1回ずつ読み込むように修正しましょう。

何故重複読み込みしていたのか?

ほどなくして、その理由がわかりました。
このWordpressテーマのfunctions.phpは他サイトからコピーして編集したものでした。もちろん1行ずつ要/不要を確認したのですが、見落としがありました。そう、functions.phpでもjqueryとcommon.jsを書き出していたのです。単純なミスでした。

さて、ここまでわかったこと
・jqueryとjsを重複読み込みしていた
・重複の原因はheader.phpとfunctions.phpにそれぞれ書いていたから
・しかし、重複読み込みだけなら不具合は起きない

つまり
おかしな動作のドロワーメニュー
の原因は他にあるのです。

不具合のほんとうの原因

もう一度Wordpressが書き出したソースに怪しい箇所が無いか1行目から見ていくと、なんだか怪しそうな1行をみつけました。

<link rel='dns-prefetch' href='//ajax.googleapis.com' />

これは怪しい!怪しすぎる…

さっそく静的htmlにこの1行をコピーしてみます。

<link rel='dns-prefetch' href='//ajax.googleapis.com' />
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="js/common.js"></script>

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="js/common.js"></script>

うわっ出た!不具合

まとめ

以下の5行がすべて揃ったときに不具合が起こります。
検証はしていませんがtoggle,fadeToggleメソッドでも同条件で不具合が起こるかもしれません。

<link rel='dns-prefetch' href='//ajax.googleapis.com' />
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="js/common.js"></script>

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="js/common.js"></script>

以下は問題ありません。

<link rel='dns-prefetch' href='//ajax.googleapis.com' />
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="js/common.js"></script>

以下はドロワーメニューは正常に動きますが、重複しているので1回読み込みに修正しましょう。

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="js/common.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="js/common.js"></script>

因みに<link rel=’dns-prefetch’ href=’//ajax.googleapis.com’ />というのはWordpressまたはプラグインが書き出しているようです。Wordpressのバージョンによっても異なるようです。機会があれば<link rel=’dns-prefetch’ href=’//ajax.googleapis.com’ />について書いてみたいと思います。