以前とある案件でjQueryのバージョンを2.xにしたんですが、クリックで関数をそれぞれ実行するtoggle()が動かない! よくよく調べるとjQuery1.9以降では廃止された模様。。。常にアンテナは張っておかないとと自戒しつつ、この今は無きtoggle()を復活させたいと思います。
そもそもなぜ廃止されたのかというと、要素の表示/非表示を切り替える.toggle()メソッドと混同することと、モジュール性を高めるためという理由らしいです。
toggle関数を新たに作成する
調べてみると 廃止されたtoggle()の、クロージャーによる代替実装方法 | Qiitaという記事があり、コメント欄に良さげなコードがありました。
$.fn.clickToggle = function(a, b) {
return this.each(function() {
var clicked = false;
$(this).on('click', function() {
clicked = !clicked;
if (clicked) {
return a.apply(this, arguments);
}
return b.apply(this, arguments);
});
});
};
コードの内容はわからない点が多いので後述しますが、早速実行してみます。
関数を実行する
用意したコードはクリックするたびに画像を切り替えるものです。廃止されたtoggle()と書き方は同じです。
$( '.btn_menu' ).clickToggle(
function() {
$( 'img', this ).attr( 'src', 'image1.png' );
},
function() {
$( 'img', this ).attr( 'src', 'image2.png' );
}
);
jQuery Migrate Pluginでtoggle()を使用できるようにする
記事を書くのに調べた中で知ったのですが、jQuery Migrateというプラグインがあり、これを読み込むことで廃止されたAPIを復元できるようになります。読み込むJQuery本体のバージョンは当然ながら、廃止されたバージョン、1.9以降になります。
<script src="js/jquery-1.9.0.min.js"></script>
<script src="js/jquery-migrate-1.4.1.js"></script>
おまけ - コードを読み解いてみる
今回のコードですが、力量不足で何をしているのか読み解けない箇所もあったので、いろいろ調べつつ拙いながらも処理内容のコメントをいれました。
//関数clickToggleの追加を宣言
$.fn.clickToggle = function(a, b) {
//関数clickToggleがあれば繰り返し処理
return this.each(function() {
//変数clickedを設定
var clicked = false;
//clickされた時の処理
$(this).on('click', function() {
//クリックされたら、!clicked、つまりclickedの値はブール値なのでtrueになる
clicked = !clicked;
//clickedの値がtrueなら、つまりクリックされた状態なら、
if (clicked) {
//引数a(ここでは関数)を実行し処理を返す
return a.apply(this, arguments);
}
//さらにクリックされたら、引数b(ここでは関数)を実行し処理を返す
return b.apply(this, arguments);
});
});
};
よく解らなかったのがこの箇所、
return a.apply(this, arguments);
大雑把な説明ですが、apply()は別の関数からオブジェクトを参照して実行するメソッドで、この場合 aが実行される関数、thisは関数aの値、argumentsは実行される関数のすべての引数を取得する特殊な変数で、配列のようなオブジェクトです。
先ほどの画像切り替えのスクリプトを例にとると、clickToggle内の function(){・・・} を実行しているのはわかりました。ただ、どうしてこのような書き方をするのかなど、まだ理解不足なのでさらに精進!です。