複数バージョンのjQueryを使う時の注意点
- カテゴリ:
- JavaScript
- コメント数:
- Comments: 0
◆ trigger はイベント設定したのと違う方のjQueryから実行しても登録した関数は実行されない
noConflict()
jQueryはnoConflict()を使うことで複数バージョンを1ページで使えます好きなバージョンの違う複数人で開発するとき向け?
それとも過去に古いバージョンで作ったページに機能追加したいときに 新しいバージョン使いたいけど前に前に書いたところで問題おきるかもしれないから新しく作るところでだけ新しいバージョンを使うため?
どっちでもいいですけど jQueryにはそんな機能があります
jQueryのコードはこんなのです
var
// Map over jQuery in case of overwrite
_jQuery = window.jQuery,
// Map over the $ in case of overwrite
_$ = window.$;
jQuery.noConflict = function( deep ) {
if ( window.$ === jQuery ) {
window.$ = _$;
}
if ( deep && window.jQuery === jQuery ) {
window.jQuery = _jQuery;
}
return jQuery;
};
if ( typeof noGlobal === strundefined ) {
window.jQuery = window.$ = jQuery;
}
jQueryが読み込まれる時に window.$ と window.jQuery を _$ と _jQuery にバックアップを取って window.$ と window.jQuery に読み込んだバージョンのjQueryを設置しています
jQuery.noConflict() が実行されると window.$ がnoConflict() を実行したjQueryと同じなら window.$ を _$ の値(通常は1つ前に読み込んだjQuery)に戻します
noConflict() の引数がtrueなら window.jQuery も同じように _jQuery の値に戻します
noConflict() が呼ばれた バージョンのjQueryはなかったことにされます
しかし noConflict() の返り値にjQueryが返ってくるので 受け取って好きな変数名にセットしたり クロージャの引数として限られて範囲でのみ使うということができます
_$ などにバックアップしてるので noConflict() なくても前のバージョン直接持ってこれるのかと思うかもですが このバックアップ処理書かれている場所がグローバルスコープじゃないので _$ は通常アクセスすることができなく noConflict() でのみ復元できます
基本的な使い方
<script src="jquery-1.11.3.js"></script>
<script>
var jq1113 = $.noConflict(true)
</script>
<script src="jquery-2.1.4.js"></script>
<script>
var jq214 = $.noConflict(true)
</script>
<script>
$ // undefined
jQuery // undefined
jq1113().jquery // 1.11.3
jq214().jquery // 2.1.4
</script>
両方にnoConflict(true)をすると$とjQueryはundefinedになります<script src="jquery-1.11.3.js"></script>
<script>
var jq1113 = $.noConflict(true)
</script>
<script src="jquery-2.1.4.js"></script>
<script>
$().jquery // 2.1.4
jQuery().jquery // 2.1.4
jq1113().jquery // 1.11.3
</script>
1つ目の読み込み後にnoConflict(true)をすると$とjQueryは2つ目になります
<script src="jquery-1.11.3.js"></script>
<script src="jquery-2.1.4.js"></script>
<script>
var jq214 = $.noConflict(true)
</script>
<script>
$().jquery // 1.11.3
jQuery().jquery // 1.11.3
jq214().jquery // 2.1.4
</script>
2つ目の読み込み後にnoConflict(true)をすると$とjQueryは1つ目になります
バックアップは _ がついたものに一段階だけですが jQueryの読み込みごとに別スコープに保存されるので3つ以上のjQueryを読み込んでも大丈夫です
window.$ が noConflict() を実行したjQueryと一緒の場合のみ復元しますが 基本 window.$ へ上書きしていくので noConflict() を実行する順番を考える必要はなく $.noConflict(true) だけを繰り返していけば新しい順に取得できるようになっています
ここはすごく考えられてるな~と感心しました
DOM操作部分とかはあまり私の好みじゃないのでそこまですごいとも思いませんでしたがこういうところではすごいと思わざるを得ないですね
応用的な使い方
<script src="jquery-1.11.3.js"></script>
<script src="jquery-2.1.4.js"></script>
<script>
!function($){
// この中では $ でjQuery2.1.4が使える
}($.noConflict(true))
</script>
クロージャの中では引数で $ を指定のバージョンにしています
jQueryの読み込みから noConflict() を引数にしたクロージャの間にコードが全く無ければ2つ目のjQueryはクロージャ内でしか使うことが出来ません
noConflict() の中身を知らずにサンプルだけ見るとnoConflict() を書いてる場所が説明しているページによって違ってどれが正しいのかわからなかったですが コードを見てみるとシンプルでわかりやすかったです
複数バージョンで注意すること
noConflict() 自体の説明が長くなりましたが注意点です当たり前といえば当たり前ですが jQuery内にデータを保存するものは別のjQueryとは共有されません
例えば イベントリスナを付けるのはどっちでつけたものもイベントが起きた時には動きますが trigger で実行させる場合には リスナをつけたjQueryでしか実行させることができません
クロージャで場所限定で別バージョン使うときなどはイベントをつけたjQueryを取得するのが難しいので注意が必要です
まぁtriggerなんて滅多に使わないと思いますけど
私の場合は 引数がeventになる関数は ほぼ何もせず関数1つ呼ぶようにすることが多いので特にtrigger の必要が無いです
というのも イベントリスナに設定された関数は 引数がevent で this がイベントが起きた要素になっていて特殊なので直接その関数を呼べなくて不便です
そのための trigger なのかもしれませんが リスナが複数あるといらないのまで実行されることがあります
なのでイベントリスナに設定される関数で実行する内容を直接関数を呼び出して実行できるように メインとなる部分を別関数にして イベントリスナの関数ではそれに引数を合わせて呼び出すだけにしています