jQueryで動的に要素を追加することをマニピュレーションといいます。動的なサイトを作成するには欠かせないものですが、時には困ったことが起こります。
例えば動的に作成した要素にイベント処理を行うときです。サンプルを見ながら問題点と解決を考えていきます。
サンプル1:ある要素をクリックしたら別の要素の文字色が変わるものです。
HTMLコード
<p class="aa">AAAA</p> <p class="bb">ここをクリックするとAAAAが赤字になる。</p>
CSSコード
.bb { background-color: yellow; width: 200px; height: 100px; cursor:pointer; }
jQueryコード
$(function(){ $('.bb').click(function() { $('.aa').css('color','red'); }); })
ここまでは特に問題はないと思います。
ここで、p要素の「ここをクリックするとAAAAが赤字になる。」部分をjQueryで動的に追加するとどんな結果になるでしょう。
スクリプトは次のように記述しました。
この場合にはクリックイベントが発生した時点で「.bb」は存在していませんので思惑どおりに動作しません。
サンプル2:動的にp要素を追加してイベントに反応させたいがうまくいかない例
$(function(){ $('.bb').click(function() { $('.aa').css('color','red'); }); $(".aa").after('<p class="bb">ここをクリックするとAAAAが赤字になる。</p>'); })
イベントが発生した段階ではまだ存在しない要素には反応しません。このサンプルの場合わかりやすいようにイベントの命令文の後に要素を作成しています。イベントハンドラの前に「.bb」を作成しておけばよいという突っ込みはなしとして、例えばあるイベントを行うと要素が作成されて、別のイベントで作成された要素に対してのイベントを設定する状況は多くでてきます。このような場合は、まだ作成されていない要素へのイベントはうまく動作しません。
卒業作品作成のとき受講生からの質問も比較的多い事例です。ハマりやすい内容ですから対策をしっかりマスターしておきましょう。
将来の要素にイベントを設定するにはon()を使用
先ほどのサンプルの問題を解決するにはon()を使用します。
具体例は次のようになります。
$(function(){ $(document).on('click' , '.bb', function() { $('.aa').css('color','red'); }); $(".aa").after('<p class="bb">ここをクリックするとAAAAが赤字になる。</p>'); })
新たに作成する要素の親要素が存在する場合はdocumentの代わりにその親要素にすることができます。
ここまでの説明はドーナツ本にも書かれていますし、ネットにも色々書かれています。
hoverイベントの場合
ところでイベントがclickではなくhoverだったらどのように書けばいいのでしょう。
これはあまり情報がでていません。
サンプル4:「.bb」にマウスホバーしたら「.aa」の文字色が赤に変わる例
HTMLコード
<p class="aa">AAAA</p> <p class="bb">ここにマウスを重ねるとAAAAが赤字になる。</p>
CSSコード
.bb{ background-color:yellow; width:200px; height:100px; cursor:pointer; }
jQueryコード
$(function(){ $('.bb').hover(function() { $('.aa').css('color','red'); },function(){ $('.aa').css('color','black'); }); })
ここまではクリックイベントのサンプル1と同じ状態でイベントがhoverに変わっただけです。
次に要素を動的に作成してhoverイベントを使ってみました。
サンプル5:将来の要素にhoverイベントを設定(動作しない例)
$(function(){ $('.bb').hover(function() { $('.aa').css('color','red'); },function(){ $('.aa').css('color','black'); }); $(".aa").after('<p class="bb">ここにマウスを重ねるとAAAAが赤字になる。</p>'); })
hovaerの例もやっぱりclick と同様にまだ作成されていない要素へのイベントは思惑通りに反応しません。
on()で将来の要素にhoverイベントを設定する方法
on()でhoverを使用する方法です。
サンプル6:将来の要素にhoverイベントを設定する例
$(function(){ $(document).on({ 'mouseenter' : function() { $('.aa').css('color','red'); }, 'mouseleave' : function(){ $('.aa').css('color','black')} }, '.bb'); $(".aa").after('<p class="bb">ここにマウスを重ねるとAAAAが赤字になる。</p>'); })
on()の書き方がclickと違いますね。
比較的使う可能性の高いものですから、将来できる要素のためのhoverイベントの書き方も知っておくとよいでしょう。
hoverイベントの正体
jQueryの古いバージョンでは、hoverイベントは実は「mouseenter」と「mouseleave」のエイリアスでした。jQueryのバージョンアップとともに「mouseenter」と「mouseleave」の使われ方は変更され、現在では次のようになっています。
hoverイベントの使い方
命令文;
},function(){
命令文;
});
「mouseenter」と「mouseleave」の使い方
‘mouseenter’:function(){
命令文;
},
‘mouseleave’:function(){
命令文;
}
});
以上の2つはどちらの書き方でも結果は同じになります。
今回のテーマの将来の要素のためのhoverイベントは次のようになります。
将来の要素のためのhoverイベントの書き方
‘mouseenter’ : function() {
命令内容;
},
‘mouseleave’ : function(){
命令内容 }
},
‘将来の要素のセレクタ’);