WordPressでjQueryを使うときに、問題なく動作させる為の基礎知識やTipsと、動かない場合の対処例

Ads
jQuery

WordPressを使っていてjQueryの導入で結構つまづいてしまう、という意見をちらほら見かけるので、無理やり入れずに、しっかりした形で導入すれば今後も動かない、などの混乱を生じにくくなると思って記事にします。

WordPressもjQueryも情報量が豊富で、割と手軽に利用出来るようになっていますが、Web制作者さんでは無い方だとどうしてもつまづいてしまう事が多いかと思いますので、WordPressでjQueryを使うときの基本的な注意点などをご紹介します。

というわけで、今日は少しビギナーさん向けの内容になります。お困りの方は参考にして見てください。

WordPressとjQuery


さて、WordPressでjQueryを使う前に、仕組みをさらっとおさらいします。

WordPress内のjQueryはどうやって読み込まれるの?

WordPressで、jQuery本体はどうやって読み込まれるのか、という話になるんですが、これはheader.php内に必ず書いてください!とよく言われている

<?php wp_head(); ?>

を書くことで呼び出されます。wp_head()はこうしたライブラリの出力や、プラグインにも関わるコードなので必ず含めるようにしてください。これを書いておかないと問題が発生しますので必ず書いてくださいね。

なぜWordPressでjQueryが動かないの?

jQueryはJavascriptのライブラリの一つですが、同じようなライブラリは他にも存在します。特定のWordPressプラグイン利用など、環境によっては2つ以上のライブラリが同一サイトで共存する事になります。例えばprototype.jsというライブラリがあるんですが、

prototype.jsとは

WordPressのプラグインによっては、このprototype.jsを使用したものも存在していて、有効化することでテーマ内に呼び出されます。

この2つのライブラリは共通して$を関数に使っています。詳細は省きますが、この$が原因で衝突・・コンフリクトというんですが、これを起こすことで上手く動作しない事が大半だったりします。

コンフリクトを回避する

そういうわけで、コンフリクトを回避して同一サイトで共存してあげるにはjQuery側で$を使わないようにすればいいわけです。

一つの回避法として以下のような方法がよく紹介されています。

var j = jQuery.noConflict();

こんなコードを書く前に記述し、

$(“foo”).addClass(“bar”);

j(“foo”).addClass(“bar”);

に書き換えれば大抵動作させる事が出来るようになります。$をjに置き換えるんですが、結構古い方法で、管理性、実用性に欠けます。

[note]実際、コンフリクトはmootoolsなど他の要因も影響します。詳しく知りたい方は以下をご覧下さい。

jQueryをmootoolsなどの他のライブラリと干渉しないようにする方法まとめ
【2016/06/12 updata】
リンク先が変わってしまったため削除処置を行いました。
お問い合せいただきました方、有難うございました![/note]
通常はカプセル化が一番合理的ですかね。

(function($){
  // foo
})(jQuery);

或いは以下のように書きます。

jQuery(document).ready(function($){
  // foo
});

ただ、あくまで複数のライブラリを共存させる場合の話なので、jQueryしか使わないならこんな面倒な事をする必要は無いですが、WordPressに限ってはこのコンフリクト回避が逆に混乱を生じさせる要因にもなっています。

WordPress本体に最初から含まれているjQueryは・・・


さて、WordPressに最初から含まれているjQueryだと何でうまくいかないのか、っていう理由なんですが、WordPress本体に含まれているjQueryは最初からjQuery.noConflict();が含まれてしまっているので、普通にjQueryを導入しても動かない事もあります。

以下は当ブログのWordPressに含まれているjQueryです。コードの最下部をご覧下さい。長いコードの一番下にnoConflict();が入っているのが確認できます。

jQuery.js – kachibito.net

WordPressに内包されているjQuery本体には全て追記されています。これは通常のjQuery本体には含まれていません。

以下はjQuery公式サイトで配布されている本体です。最下部を見てもnoConflict()は記述が無いと思います。

jQuery.js

なぜわざわざnoConflict();を含めているの?

なぜWordPressはjQuery本体にわざわざjQuery.noConflict();を入れるかというと、WordPressに内包されているjQuery本体はテーマだけでなく、管理画面内でも利用するし、プラグインデベロッパーもjQuery以外のライブラリを使いたい事もあるので、最初からnoConflict();を含めているのはそういう配慮なわけですが、こういった特徴を知らないまま、配布されているjQueryプラグインを自力でWordPressテーマに導入した際に

「動かない!」

ってなっちゃうわけですね。

WordPress公式サイトでもjQueryの使用に関して言及してあります。ですので基本的にWordPressでjQueryを使いたいなら$() の代わりに jQuery() を使えと、こういうわけですが、これじゃいちいち変更したりカプセル化しなきゃいけないのでやはり合理性に欠けます。

なので、自分のテーマでjQuery以外のライブラリを使う予定が無いのであれば、WordPress内にあるnoConflict();付きのjQuery本体ではなく、GoogleなどにホスティングされているjQuery本体を使ったほうがトラブルが少ないし、jQueryプラグインの導入も楽になるかも知れません。

やってしまいがちなWPでjQueryを使う際の失敗例


ここでよく聞く失敗例を挙げてみます。失敗って程でもないんですけど、思い当たる節がある方は問題解決に繋がるかもしれません。

jQuery本体を2回読み込んでいる


僕も昔はやっちゃってましたけど、WordPress本体からjQueryが読み込まれるのに、それとは別にheader.phpに直接jQuery本体のパスを書いてしまうので結果的に重複してしまいます。

<?php wp_head(); ?>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.6/jquery.min.js"></script>
<script type="text/javascript" src="<?php bloginfo('template_url'); ?>/js/lightbox.js"></script>

こんな感じにしちゃうと本体が2回読み込まれてしまいます。以下のような感じに。

<script type='text/javascript' src='http://example.com/wp-includes/js/l10n.js?ver=20101110'></script>
<script type='text/javascript' src='http://example.com/wp-includes/js/jquery/jquery.js?ver=1.7.1'></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.6/jquery.min.js"></script>
<script type="text/javascript" src="http://example.com/wp-content/themes/my-theme/js/lightbox.js"></script>

1.7の後に1.3.6を読み込んでいる状態です。

この場合、新旧2つのjQuery本体を読み込んでいるので、jQueryプラグインがうまく動かない、という問題が生じる恐れがあります。

配布されている古いjQueryプラグインのサンプルコードなんかは、当然古いままなんですが、そのままコピペして動かそうとすると「WordPressで動かない!」とかなっちゃうので注意が必要です。

何より軽量とは言えないjQuery本体を無駄に2回もロードしてしまうと、表示スピード遅延など、Webサイトのパフォーマンスを損ねてしまいます。

動かないから取り敢えずwp_head()より上に書いてみる

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.6/jquery.min.js"></script>
<script type="text/javascript" src="<?php bloginfo('template_url'); ?>/js/lightbox.js"></script>
<?php wp_head(); ?>

さっきの書き方だと動かないからwp_head()より上に書いてみた、みたいな。これも良く見かけますが、やはりわざわざ重いjQuery本体を重複して読み込んでいます。ページのロード時間にも当然影響を与えてしまいますね。

ただ、これならまぁ動く事もあります・・・が、今後の運営に問題が無いとも言えません。

WordPressに内包されるjQueryの使用をやめて最新にしたら動かなくなった


今まで使用していたjQueryのコードやプラグインが、最新のjQueryに対応していないと動きません。

例えば、jQuery1.4で下記コードは実行されますが、それ以降では実行できません。

$("foo").stop().animate({"background-position" : "10% 0" });

animateメソッドにbackground-positionは対応しなくなりました、というか単なるバグで動いてただけで、今はバグが解消されて動かなくなりました。

jQueryもまだ開発中で、こうした問題もありますので、基本的には常に新しいバージョンに対応する為にもプラグインのみに頼らない姿勢も大事です。

何度か書いてますので勉強してみてはいかがでしょう。

  1. 「ノンプログラマーのためのjQuery入門」のスライドが凄く分かりやすいですね
  2. jQuery事始め・コピペに頼らず、基礎知識を理解して実際に動かしてみる
  3. jQuery事始めvol.2・画像にマウスオーバーして動作するアニメーションエフェクトを作ってみる
  4. jQuery事始めvol.3・プラグインに頼らず自分でクリックで切り替わるタブメニューを作ってみる

最初から何しても動かない


利用しているWordPressプラグインのスクリプトと干渉してるかもしれません。WordPressプラグインを有効化/無効化して動作を確認してください。或いは、実はjQuery以外のライブラリも読み込まれていた、という場合です。ソースを確認して、protetype.jsやmootools.jsが無いかを確認してください。

それでも動かないようでしたら、WordPress以外で同じ記述をして動作テストを行います。それでも動かなければWordPressではなく、記述に問題があるといえます。URLのパスに誤りがあるとか。

根本的に間違ってるケースも多いです

この場合はWordPress関係ないんですけど、良くあるビギナーさんの混乱の元となってる話。大抵はコピペが原因の事もあるようです。

2つのjQueryプラグインを使ったときに、片方だけ動作しなくなってしまった、なんて事ありませんかね。これは、セレクタの重複が問題だったりします。

例えば、クリックして何かアクションを起こすjQueryプラグインを使用していたとします。トップに戻る、とタブで切り替わるやつとかね。

この場合は以下の理由が考えられます。トップに戻る、のイベントトリガーが

//href="#~"をクリックしたら上に戻る
$('a[href*=#]').click(function(){
// トップに戻る為のコード
)};

で、タブも

//href="#~"をクリックしたらタブが切り替わる
$('a[href*=#]').click(function(){
// タブの切り替えコード
)};

の場合、大抵は片方しか動いてくれません。これはクリックイベントを起こさせるトリガーとなるセレクタの指定が両方ともa[href*=#]で、同じになっているので両方に動作させてしまっている状態です。

こうやって書くと難しく聞こえますが、cssでも同様で、

a{color:#eee;}と書いて、下の方にもa{color:#000;}

と書いてしまったらa{color:#000;}しか適応されませんよね?jQueryでも理屈は同じことです。

なので適切なセレクタを書くようにします。

//親要素がid="gotop"内にあるhref="#~"をクリックしたら上に戻る
$('#gotop a[href*=#]').click(function(){
// トップに戻る為のコード
)};
//親要素がid="tabs"内にあるhref="#~"をクリックしたらタブが切り替わる
$('#tabs a[href*=#]').click(function(){
// タブの切り替えコード
)};

「コピペしたのに動かない」というのは不自然ではなく割と自然です。親要素を指定するクセをつける様にするといいですね。

というか、jQuery本体の古いバーションは極力使わないで下さい

セキュリティ上、出来る限り新しいバージョンのjQueryを使うようにしてください。

WordPress × jQueryのベストプラクティス


ちょっと大げさですけど、動作しないで困っている方は多分他のライブラリと共存させる、とかあまりしないと思うんですよね。素敵なプラグインがあったから使ってみたい、とかそんな理由じゃないかなと。

なので、最もトラブルになり難いのはjQuery以外のライブラリを使わない、という場合はWordPress本体のjQueryを使用しないようにする事です。

お使いのテーマファイルのheader.phpのwp_head()よりも上に以下を書きます。

<?php
wp_deregister_script('jquery');
wp_enqueue_script('jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js', array(), '1.7.1');
?>

最初の行は、WordPressに内包されている、jQuery.noConflict();付きのjQuery本体を読み込ませない、という記述で、2行目で任意のjsファイルを読み込みます。この読み込むファイルを、Googleにホスティングされている最新のjQueryに置き換えます。

これで、<head>内に

http://kachibito.net/wp-includes/js/jquery/jquery.js?ver=1.7.1

は読み込まれなくなり、代わりに

http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js?ver=1.7

に変わってくれますので、$(“foo”).addClass(“bar”);といった普通の記述でjQueryを動かすことが出来ます。

テーマに任意のjsファイルを読み込む

素敵なjQueryプラグインを見付けたのでテーマで使いたい、というときは以下を書いてあげるようにします。

wp_enqueue_script('example',get_bloginfo('template_url') . '/js/example.js', array('jquery'), '1.0');

これで以下のように出力されます。

<script type='text/javascript' src='http://example.com/wp-content/themes/your-theme/js/example.js?ver=1.0'></script>

ただ、複数のjQueryプラグインを1つのファイルにしてコンパイルしたい、とかページによって条件分岐させてる、などなど、いろいろ工夫したい方は特に拘らなくてもベタ書きでいいかなって思います。そういう方はコンフリクト回避も容易に出来るでしょうし。管理しやすい方で良さそうですね。

functions.phpで一括管理

利用しているテーマにheader.phpが複数ある場合は、functions.phpで一括管理したほうが楽ですが、管理画面内もリセットしないように気をつける必要があります。

function load_cdn() {
	if ( !is_admin() ) {
	wp_deregister_script('jquery');
	wp_enqueue_script('jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js', array(), '1.7.1');
	}
}
add_action('init', 'load_cdn');

!is_admin()で、管理画面以外に適応させるように配慮します。この件は以前書いています。

WordPressでjQuery本体をCDN等に置き換える際は管理画面に読み込ませないようにする

[note]管理画面ではプラグイン開発者が上手く作ってくれていますのでWordPressのjQueryを使用してください。[/note]

現状すでにjQuery.noConflict();に合わせてあるけどjQueryはGoogleのを使いたい

今現在、問題なく動作している方の大半はjQuery.noConflict()に対応済みかと思います。中身を見ると

jQuery("foo").addClass("bar");

となっていると思います。

もし、GoogleのjQuery本体を使って動作しなくなったら、jQuery.noConflict();を含めます。

<script type="text/javascript">
        jQuery.noConflict();

        jQuery(function() {
            jQuery("foo").addClass("bar");
        });
    </script>

おまけ:wp_enqueue_scriptが便利

wp_enqueue_scriptは指定したライブラリの重複を防げる便利な関数ですので、WordPressでJavascriptを使う場合はよく覚えておくと良いと思います。特にjQueryは重いので、GoogleのCDNを使うと、環境によってはちょっと高速化に繋がりますよ。wp_enqueue_scriptの使い方は

wp_enqueue_script('ハンドル名', 'スクリプトのパス' , array(), 'バージョン');

といった具合です。この関数で登録したスクリプトで、ハンドル名が同じものについて各々のバージョンをチェックし、その中で最新のバージョンのスクリプトを使用しますので重複問題を起こしにくいです。

ハンドル名は様々で、jquery-effects-fadeとかjquery-ui-accordionとかいろいろです。バージョンはオプションで、無くても構いませんが、このようにクエリ文字を含めておくと、キャッシュを防げますので入れておくと良さそうです。

これだけでなく、自作のスクリプトや、管理画面で使われているjsをテーマで使う事が出来るので無駄を省けます。管理画面で使われているものとして、例えば画像の切り抜きやLightbox、スライドパネルなどから、使われてないけど内包されているjQueryUIなどもハンドルとパスの指定で手軽に呼び出せます。

[note]詳しくはwp-includes/js/内を、ハンドル名はwp-includes/script-loader.phpか、またはCODEXのハンドル名一覧をご確認下さい。[/note]

まとめ

ではまとめ。

  • 使うWPテーマでjQuery以外を使わないときは、WordPress本体のjQueryは使わない
  • wp_head()は必ずheader.phpに書く
  • functions.phpで指定する場合は管理画面に適応させないようにする
  • テーマファイルへのjQueryプラグインのファイルのURLはwp_head()以下に書く
  • jQuery本体がアップデートしたら最新版に置き換える
  • 上記が分からない場合はjQueryプラグイン等をカプセル化する※コードを(function($){}(jQuery))で囲う
  • それでもダメならソースを確認して、jsを読み込んでいるWPプラグインを停止して動作を確認する
  • それでも動作しない場合はWordPress以外で動作するか等を確認する。動作しなければWPは無関係

と、こんな感じでしょうか。長々と書いてきましたが、こういったライブラリは動かすことよりも問題を生じさせないことのほうが難しいのです。

趣味ではなく、クライアントワークとしてWordPressでjQueryを使用するのであればトラブルを避けるためにこうした知識が必要になってくるかと思います。

WordPressもjQueryも気軽に使える事は使えるんですが、ある程度基礎的な知識が無いと困って誰かに頼らざるを得なくなります。そうなると聞くほうも聞かれるほうも大変ですからね。使うなら基礎くらいは頭に入れておくと、聞き方も的確になるし、聞かれたほうは教えやすくなりますのでみんな幸せになれそうですね。

長くなりましたけど問題点ありましたら突っ込みお願いします。

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