jQuery イベント
jQuery イベントに関する参考資料です。基本的なイベント(リスナー)の設定方法や、各種イベント(クリック、ホバー、スクロール、リサイズ、ロード)を使ったサンプルや解説を掲載しています。
作成日:2018年2月10日
jQuery イベントの概要
イベントとは、プログラムを作動させる何らかのきっかけのようなものです。例えば、ユーザーがマウスを動かしたり、クリックしたり、キーボードからテキストを入力する等や、システムで発生するタイマーや非同期要求の完了などがあります。
イベントの発生に応じて呼び出される処理のことを、イベントリスナーやイベントハンドラーと言います。jQuery では、イベントリスナーを設定するために、いくつかの構文を用意しています。
以下はイベント名ごとに簡単に設定できるショートハンドメソッドの書式です。
$(セレクタ).イベント名(function(e){ 実行する処理 });
「jQuery の ready 関数」も、イベントを利用したものの1つで、 DOM ツリーがロードされた(ページの読み込みが完了した)という ready イベントに対しての処理になります。
$(document).ready(function(){ 実行する処理 });
イベントリスナーの設定例
以下は、クリックイベントの例で、ユーザーがリンクをクリックすると現在の時刻を表示するサンプルです。
<p><a href="#" id="disp_time">時刻を表示</a></p>
$('#disp_time').click(function() { $(this).text((new Date()).toLocaleString()); return false; });
id が disp_time の a 要素をクリックすると、その要素 $(this) のテキストを現在の時刻に変更します。
イベントが発生した要素を取得(参照)する $(this)
イベント(リスナー)を設定している click(function() {...}) の中で $(this) と記述すると、イベントが発生した要素を取得(参照)することができます。上記の例では $(this) は $('#disp_time') を指します。
(new Date()).toLocaleString() は JavaScript の Date オブジェクトを生成して、それをローカルなタイムゾーンに基づいて日付を文字列に変換しています。
以下と同じことになります。
$('#disp_time').click(function() { var d = new Date(); //Dateオブジェクトを生成 var t = d.toLocaleString(); //日付を文字列(時刻)に変換 $('#disp_time').text(t); //テキストを現在の時刻に変更 return false; });
イベントリスナーの登録
イベントの発生に応じて呼び出される処理のことをイベントリスナーと言い、これを登録(記述)することでイベントが発生した際の、動作を設定することができます。jQuery では、イベントリスナーを設定するために、いくつかの構文を用意しています。
ショートハンドメソッド
以下はイベント名ごとに設定するショートハンドメソッドの書式です。
イベントの処理も、通常はページの読み込みが完了したら行うので、「ready 関数」の中に記述します。
jQuery(function($){ //ready 関数 $(セレクタ).イベント名(function(e){ 実行する処理 }); });
イベントリスナーに渡されている引数 e はイベントオブジェクトと言い、マウスの座標や押されたキーの種類など、イベントに関わる情報を持つイベント・オブジェクトです。イベントリスナーの中で利用しない場合は、省略しても問題ありません。
この書式でサポートされているイベントには以下のようなものがあります。
blur | focus | keyup | mouseleave | ready |
change | focusin | load | mousemove | resize |
click | focusout | unload | mouseout | scroll |
dblclick | keydown | mousedown | mouseover | select |
error | keypress | mouseenter | mouseup | submit |
以下は、クリックイベントの例で、ユーザーがリンクをクリックすると背景色を変更するサンプルです。
<p><a href="#" class="sample">クリックすると背景色と文字色が変わります。</a></p>
$('a.sample').click(function() { $(this).css({backgroundColor:'#F59FA1', color: '#fff'}); return false; });
class が sample の a 要素をクリックすると、その要素 $(this) の背景色と文字色を変更します。
$(this) は、イベントが発生した要素の jQuery オブジェクト $('a.sample')を指します。単にthis としてしまうとそれは、JavaScript オブジェクトを意味するので、$()関数を使って jQuery オブジェクトに変換しています。
また、「return false;」は a 要素をクリックするとリンク先へ移動するのを防ぐために指定します。 a 要素のクリックイベントの設定のイディオムとして覚えておくと良いと思います。
.on() を使ったイベントの設定
前述のショートハンドメソッド以外に、次のように .on() を使ってイベントを定義することもできます。
jQuery(function($){ //ready 関数 $(セレクタ).on('イベント名', function(e){ 実行する処理 }); });
実は、ショートハンドメソッドは、この .on() を使ったイベントの設定の簡略版です。
//ショートハンドメソッド $('a.sample').click(function() { $(this).css({backgroundColor:'#F59FA1', color: '#fff'}); return false; });
//.on() を使っての設定 $('a.sample').on('click', function() { $(this).css({backgroundColor:'#F59FA1', color: '#fff'}); return false; });
jQuery が標準で対応していない(=イベントメソッドとして提供されていない)イベントにアクセスするにはこの方法を使う必要があります。
.on() を使うと、複数のイベントリスナーをまとめて設定したり、一度に複数のイベントタイプを定義できたりと色々な設定が可能です。
以下のようにすると、1つの要素に複数のイベントを設定することができます。(イベントごとに異なる処理を記述することができます)
$('.sample').on({ 'click': function(){...}, 'dblclick': function(){...} });
また、.on() の第1引数に、イベントをスペース区切りで複数指定すると、それらのどのイベントが発生しても同じ処理をさせることができます。
以下は、テキストエリアにユーザーが入力する際に、その文字数を表示する例ですが、3つのイベント(keydown keyup change)を指定しています。
$("textarea").on('keydown keyup change', function() { var count = $(this).val().length; $("#count").text(count); });
その中でも、覚えておいて便利なのは「JavaScript/jQuery を使って後から追加した要素に対してもイベントを設定できる」という点です。
文書上に存在しない要素に対してイベントリスナーを追加
以下のサンプルでは、a 要素をクリックすることにより、jQuery を使って後から div 要素を追加しています。
<div id="jqs-2"> <p><a href="#" id="jqt_2">クリックすると div 要素を追加します。</a></p> </div>
$("#jqt_2").click(function() { $("#jqs-2").append('<div class="blue"></div>'); return false; });
この場合、後から追加した div 要素にイベントを設定するには、.on() を使う必要があります。
一番簡単なのは、以下のように .on() を使って document に対してイベントを設定する方法です。
$(document).on('イベント名', '追加する要素', function(){ イベント発生時の処理 });
以下は .on() を使った設定例です。
$(document).on('click', '.blue', function(){ $(this).css('background-color', '#F5E6E7'); });
以下のように、ショートハンドメソッドで後から追加した要素にイベントを設定しても、何も起こりません。
$(".blue").click(function() { $(this).css('background-color', '#F5E6E7'); });
※ .load()、 .unload()、 .error() は jQuery3.0 で廃止(削除)されました。これらのイベントを使用するには、.on()を使う必要があります。
$(window).load(function(){ ... }); //jQuery3.0 で廃止 //jQuery3.0 からは以下のように.on()を使う必要があります。 $(window).on("load", function(){ ... });
また、.on("ready", function) も jQuery3.0 で廃止(削除)されました。以下を実行すると、jQuery1.11 では「document ready」と出力されますが、jQuery3.3 では何も出力されません(エラーもなし)。
$(document).on("ready", function() { console.log("document ready"); });
.off() を使ったイベント設定の取り消し
.off() は設定されているイベントを取り消します(登録を解除します)。
<div> <p><a href="#" id="jqt_3">アラート表示</a></p> <button class="off" >イベント取り消し</button> </div>
上記のような HTML があり、以下のようにイベントを設定した場合
$("#jqt_3").on( 'click', function(){ alert("アラート表示"); return false; }); //または、以下でも同じことです。 $("#jqt_3").click(function(){ alert("アラート表示"); return false; });
上記で設定したイベントを取り消すには、以下のように記述します。
$("#jqt_3").off('click');
以下はサンプルです。
$("#jqt_3").on( 'click', function(){ alert("アラート表示"); return false; }); $("button.off").click(function() { $("#jqt_3").off('click'); });
document に対して .on() を使ってイベントを設定した場合
$(document).on('イベント名', '追加する要素', function(){ イベント発生時の処理 }); //上記の書式で設定した場合は、以下のように記述します。 $(document).off('イベント名', '追加する要素');
.one() イベント発生時に一度だけ処理を実行
one() は、指定した要素にイベントが発生した場合、一度だけ実行する処理を記述できます。
$(セレクタ).one('イベント名', function(){ 一度だけ実行する処理 });
<p><a href="#" id="jqt_4">アラート表示(1度だけ)</a></p>
$("#jqt_4").one('click', function(){ alert("一度だけ表示します。"); return false; });
以下のように、on() と off() を使って書き換えることも可能です。
$("#jqt_4").on('click', function(){ alert("一度だけ表示します。"); $( this ).off(); return false; });
以下は、四角いボックスをクリックすると、one() を使ってクリックした回数を表示するサンプルです。
<div id="jqs-5"> <div class="blue"></div> <div class="blue"></div> <div class="blue"></div> <div class="blue"></div> <div class="blue"></div> <p class="clear">クリックされたボックスの合計:<span class="total_click">0</span></p> </div>
.blue { padding: 10px; margin: 10px; border: 1px solid #E7E3E3; background-color: #E5F6F9; cursor: pointer; width: 50px; height:50px; float: left; } .clear { clear: both; }
var n = 0; $("#jqs-5 div").one('click', function() { $(this).css('background-color', '#F5E6E7'); n++; // n = n + 1; とほぼ同じ意味です。 $("span.total_click").text(n); });
n++; はインクリメント演算子と言って n = n + 1; とほぼ同じ意味です。
クリックされたボックスの合計:0
以下は占いのサンプルです。
// 占いのメッセージを配列として準備 var fortunes = [ '素敵な1日になりそうです!', '良いことがありそうです。', '可もなく不可もなくって感じです。', 'つらい1日になるかも知れません。' ]; // ボタンをクリックすると1度だけ、ランダムでメッセージを表示 $("#jqt_6").one('click', function(){ var rand = Math.floor( Math.random() * 4 ); $("#fortune").text(fortunes[rand]); });
Math.random() は乱数を発生するメソッドです。
cursor: pointer
a 要素や button 要素などにマウスを重ねると、カーソルの形状がポインター(指の形)に変わりますが、div 要素などにカーソルを重ねてもカーソルの形状は変わりません。
a 要素や button 要素以外のクリックイベント等を設定した要素に、CSS の cursor プロパティで pointer を設定することで、ユーザーにクリックできることを伝えることができます。
div.event { cursor: pointer; }
イベントが発生した時の情報を取得
jQuery では発生したイベントの情報を、イベントオブジェクトから取得することができます。イベントオブジェクトには色々なプロパティやメソッドが用意されていて、それらを利用することで情報を取得したり、操作することができます。
イベントオブジェクトは、イベントリスナー(イベントハンドラー)の引数に渡されます。
jQuery(function($){ $(セレクタ).on('イベント名', function(イベントオブジェクト){ イベントオブジェクトを使って処理を記述 }); });
以下は、eventSample と言うクラスの div 要素の中でマウスを動かす(mousemove イベント)と、その X 座標を表示する例です。
イベントオブジェクトは、イベントリスナーの引数に渡さるので、その clientX プロパティの値を text() を使って表示しています。渡されるイベントオブジェクトの引数名はここでは「eventObject」としていますが、何でもかまいません。
$("div.eventSample").on( 'mousemove', function(eventObject){ $(this).text("clientX: " + eventObject.clientX); });
以下のサンプルでは、更に Y 座標の位置の表示と、X 座標の位置により背景色を変更しています。
<div class="eventSample"> </div>
$(".eventSample").on( 'mousemove', function(eventObject){ $(this).text("clientX: " + eventObject.clientX + " clientY: " + eventObject.clientY); if(eventObject.clientX < 300) { $(this).css('background-color', '#E5F6F9'); }else if(eventObject.clientX < 450) { $(this).css('background-color', '#D9F7E4'); }else{ $(this).css('background-color', '#F8E3E3 '); } });
以下はマウス座標関連のプロパティです。
プロパティ名 | 説明 |
---|---|
screenX/screenY | スクリーン(モニター全体)上の座標 |
pageX/pageY | ページ(ドキュメント全体)の座標 |
clientX/clientY | ブラウザーの表示領域での座標(スクロールしても同じ位置) |
offsetX/offsetY | 要素内での座標(Firefox では利用不可) |
ただし、Firefox では offsetX/offsetY プロパティは利用できまないので、代わりに e.originalEvent.LayerX/e.originalEvent.LayerY を利用します。
以下は押されたキーのキーコードを表示する例です。
キーが押されたと言うイベントは .keydown() または .keypress() を利用します。どのキーコードかを調べるには「which」プロパティを使います。
<div id="jqs-8"> <p>押されたキーの key code : <span></span></p> </div>
テキストエリアなどの特定の要素へのキーを使った入力ではないので、対象を「window」にしています。「document」や「"html"」、「"body"」でも機能します。
$(window).keydown(function(e) { $("#jqs-8 span").text(e.which); });
押されたキーの key code :
以下は、特定のキーを押すと表示されている赤い丸を移動させるサンプルです。
<div id="jqs-9" class="jqs_div" style="height:150px;"> <div class="redball"></div> </div>
.redball { width: 50px; height: 50px; border-radius:25px; background-color: #EB2C2F; position: relative; //要素を移動するにはこの指定が必要です margin: 50px auto; }
「r」を押すと右へ10px、「l」を押すと左へ10px、「u」を押すと上へ10px、「d」を押すと右へ10px 移動させます。
各キーのキーコードは以下の通りです。
- r : 82
- l : 76
- u : 85
- d : 68
switch() 文を使い、それぞれのキーが押されたら、animate() メソッドを利用して要素を移動させています。
$("html").keyup(function(e){ switch(e.which){ case 82: // Key:r $('#jqs-9 .redball').animate({left: '+=10'},100); break; case 76: // Key: l $('#jqs-9 .redball').animate({left: '-=10'},100); break; case 85: // Key:u $('#jqs-9 .redball').animate({top: '-=10'},100); break; case 68: // Key:d $('#jqs-9 .redball').animate({top: '+=10'},100); break; } });
+=10(-=10)は現在値からアニメーションの値を算出しそれに 10 を加算(減算)します。
各種イベント
マウスオーバーイベント関連
特定の要素にマウスが重なった際のイベントには、「mouseover/mouseout」と「mouseenter/mouseleave」があります。
更に「mouseenter/mouseleave」を1つにまとめた「hover」もあります。
mouseover/mouseout
mouseover() と mouseout() は、特定の要素の上にマウスが重なったタイミングを検知して、処理を実行します。
以下はショートハンドメソッドの書式です。
$(セレクタ).mouseover(function() { セレクタで指定した要素にマウスが重なった時に実行する処理 }); $(セレクタ).mouseout(function() { セレクタで指定した要素にマウスが外れた時に実行する処理 });
通常これらは、組み合わせて使用するので、まとめて以下のように記述します。
$(セレクタ).mouseover(function() { セレクタで指定した要素にマウスが重なった時に実行する処理 }).mouseout(function() { セレクタで指定した要素にマウスが外れた時に実行する処理 });
以下は、マウスポインターが画像に乗った時に画像の透明度(opacity)を上げ、外れた時に元に戻すサンプルです。
<p id="jqs-10"><img src="../images/sample1.jpg" alt=""></p>
まず画像の透明度(opacity)を 0.7 に設定しておきます。その後、mouseover と mouseout で画像の透明度を変更します。
$("#jqs-10 img").css('opacity', '.7'); $("#jqs-10 img").mouseover(function(){ $(this).css('opacity', 1); }).mouseout(function() { $(this).css('opacity', .7); });
mouseenter/mouseleave
mouseenter() と mouseleave() も、特定の要素の上にマウスが重なったタイミングを検知して、処理を実行します。書式も mouseover/mouseout とほぼ同じです。
以下はショートハンドメソッドの書式です。
$(セレクタ).mouseenter(function() { セレクタで指定した要素にマウスが重なった時に実行する処理 }); $(セレクタ).mouseleave(function() { セレクタで指定した要素にマウスが外れた時に実行する処理 });
通常これらは、組み合わせて使用するので、まとめて以下のように記述します。
$(セレクタ).mouseenter(function() { セレクタで指定した要素にマウスが重なった時に実行する処理 }).mouseleave(function() { セレクタで指定した要素にマウスが外れた時に実行する処理 });
以下は、マウスポインターが画像に乗った時に画像を入れ替え、外れた時に元に戻すサンプルです。
<p id="jqs-11"><img src="../images/sample02.jpg" alt="subway"></p>
$("#jqs-11 img").mouseenter(function(){ $(this).attr("src", "../images/sample03.jpg").attr("alt", "beach"); }).mouseleave(function() { $(this).attr("src", "../images/sample02.jpg").attr("alt", "subway"); });
mouseover と mouseenter の違い
ほとんど同じに見える mouseover/mouseout と mouseenter/mouseleave ですが、要素が入れ子になっている場合に、わずかの違いがあります。通常はそれほど意識する必要はありませんが、違いを確認してみます。
まずは、mouseover/mouseout のサンプルです。以下のような入れ子になった div 要素がある場合の例です。
<div class="outer"> <div class="inner"> </div> </div>
マウスポインタが重なったり外れたりする際に、どのようなイベントが発生するかを、console.log() を使って調べてみます。
$("#jqs-12 .outer").mouseover(function(e) { $(this).css('opacity', .5); console.log('mouseover:' + e.target.className); }).mouseout(function(e) { $(this).css('opacity', 1); console.log('mouseout:' + e.target.className); });
mouseover/mouseout
.outer
.inner
上記サンプルで、対象の要素を横一線に横断するようにマウスポインターを動かした場合の結果は以下のようになります。
mouseover:outer mouseout:outer mouseover:inner mouseout:inner mouseover:outer mouseout:outer
mouseover/mouseout イベントが、外側の要素を出入りした時だけでなく、外側と内側の要素を出入りした時にも発生していることがわかります。
今度は mouseenter/mouseleave でマウスポインタが重なったり外れたりする際に、どのようなイベントが発生するかを、console.log() を使って調べてみます。
$("#jqs-13 .outer").mouseenter(function(e) { $(this).css('opacity', .5); console.log('mouseenter:' + e.target.className); }).mouseleave(function(e) { $(this).css('opacity', 1); console.log('mouseleave:' + e.target.className); });
mouseenter/mouseleave
.outer
.inner
上記サンプルで、対象の要素を横一線に横断するようにマウスポインターを動かした場合の結果は以下のようになります。
mouseenter:outer mouseleave:outer
今度は、外側の要素に出入りした場合にだけイベントが発生し、外側と内側の要素を行き来した場合にはイベントは発生しないことがわかります。
hover
mouseenter/mouseleave は、まとめて利用することが多いイベントなので、これらをひとまとめに設定するために hover というメソッドが用意されています。
以下が書式です。
$(セレクター).hover( function(e) { セレクタで指定した要素にマウスが重なった時に実行する処理 }, function(e) { セレクタで指定した要素にマウスが外れた時に実行する処理 } );
以下は、マウスポインターが画像に乗った時にボーダーを表示し、外れた時にボーダーを消すサンプルです。
<p id="jqs-14"><img src="../images/sample03.jpg" alt="each"></p>
ボーダーを表示する際に、全体の幅が変わらないように、ボーダーの幅の分だけ幅と高さを調整しています。
$("#jqs-14 img").hover( function(){ $(this).css({border:'5px solid #F3B256',width:'290px',height:'190px' }); }, function() { $(this).css({border:'none',width:'300px',height:'200px'}); });
クリックイベント click()
以下はクリックイベントのショートハンドメソッドの書式です。
$(セレクタ).click(function() { セレクタで指定した要素をクリックした時に実行する処理 });
以下はリンク(a 要素)をクリックすると写真を表示するサンプルです。
<div id="jqs-15"> <p><a href="../images/sample.jpg">写真を表示</a></p> <p><img src="../images/sample.jpg" alt="オブジェ"></p> </div>
この例では、最初に写真を CSS の visibility を使って非表示(hidden)にしておきます。そしてクリックすると visibility を visible に変更して写真を表示させています。
CSS の display: none を使っても可能ですが、その場合、非表示の際は、写真の領域(高さと幅)が確保できません。もちろん、それが意図したことであれば問題ありません。
$("#jqs-15 img").css('visibility', 'hidden'); $("#jqs-15 a").click(function() { $("#jqs-15 img").css('visibility', 'visible'); return false; });
return false
リンク(a 要素)はクリックされると、 href 属性に指定されたリンク先に移動するのがデフォルトの動作です。
そのため、リンク(a 要素)にクリックイベントを設定しても、そのリンクがクリックされると href 属性に指定されたリンク先に移動してしまいます。
このデフォルトの動作を、防ぐには click イベントの最後に「return false」を追加します。
このようにすることで、リンク(a 要素)がクリックされた場合は jQuery の命令だけが実行されます。また、JavaScript がオフの場合は、a 要素のリンクが有効になるので、href 属性に写真へのリンクなどを指定しておけば、ユーザーはその写真を見ることができます。
return false を指定しても、デフォルトの動作が実行されてしまう場合は、プラグイン(スムーズスクロールなど)が影響していないかを調べてみる必要があるかも知れません。
シンプルなフォトギャラリー
以下はリンクをクリックすると写真が変わるサンプルです。この例では複数のリンクがあります。
<div id="jqs-16"> <ul> <li><a href="../images/sample01.jpg">黄色の花</a></li> <li><a href="../images/sample02.jpg">山の湖</a></li> <li><a href="../images/sample03.jpg">ビーチの夕日</a></li> <li><a href="../images/sample04.jpg">紅葉</a></li> </ul> <p><img src="../images/sample01.jpg" alt="黄色の花"></p> </div>
以下のサンプルは、複数のリンク(a 要素)に対して :eq フィルターを使って、それぞれのリンクに対してクリックイベントを設定しています。
$("#jqs-16 a:eq(0)").click(function() { $("#jqs-16 img").attr('src','../images/sample01.jpg').attr('alt', '黄色の花'); return false; }); $("#jqs-16 a:eq(1)").click(function() { $("#jqs-16 img").attr('src','../images/sample02.jpg').attr('alt', '山の湖'); return false; }); $("#jqs-16 a:eq(2)").click(function() { $("#jqs-16 img").attr('src','../images/sample03.jpg').attr('alt', 'ビーチの夕日'); return false; }); $("#jqs-16 a:eq(3)").click(function() { $("#jqs-16 img").attr('src','../images/sample04.jpg').attr('alt', '紅葉'); return false; });
このコードでも問題はないのですが、$(this) を使うと、もっと簡潔に、そして後で変更する場合も簡単な書き方ができます。
$(this) はイベント(この例ではクリック)が発生した要素を取得するセレクタです。イベントリスナーの click(function() {...}) の中で $(this) と記述すると、イベントが発生した要素を取得(参照)することができます。
$(this) を使って記述すると以下のようになります。
$("#jqs-16 a").click(function() { $("#jqs-16 img").attr('src', $(this).attr('href')).attr('alt', $(this).text()); return false; });
クリックされた a 要素の href 属性は $(this).attr('href')、クリックされた a 要素のテキストは $(this).text() で取得しています。
以下は、シンプルなフォトギャラリーの例です。この例では、CSS で ul 要素にクラス hidden を指定してフォトギャラリーで使用する写真を非表示にしています。
.hidden { display: none ; }
写真の下に、それぞれの img 要素の alt 属性を使ってタイトルを表示し、その下に「prev」「next」のコントロール用のリンクを配置しています。
<div id="jqs-17"> <ul id="photolist" class="hidden"> <li><img src="images/sample01.jpg" alt="黄色の花"></li> <li><img src="images/sample02.jpg" alt="山の湖"></li> <li><img src="images/sample03.jpg" alt="ビーチの夕日"></li> <li><img src="images/sample04.jpg" alt="紅葉"></li> </ul> <p id="photo"><img src="images/sample01.jpg" alt="黄色の花"></p> <p id="phototitle"></p> <p><a id="prev" href="#">prev</a> <a id="next" href="#">next</a></p> </div>
1行目は、写真の総数を変数 total に取得しています。
2行目は、現在何番目の写真が表示されているかを判定するためのカウンタ用の変数を初期化(0に)しています。
3行目は、最初に表示している写真(img 要素)の alt 属性を取得してタイトルとして表示しています。
5行目から、クリックイベントの設定をしています。
var total = $("#jqs-17 .hidden img").length; //写真の総数を取得 var count = 0; //カウンタ用の変数を初期化 $("#phototitle").text($("#photo img").attr("alt")); //最初に表示している img 要素の alt 属性をタイトルとして表示 $("#next").click(function() { count ++; //next をクリックするとカウンタを1つ増加 if(count == total) {count = 0;} //カウンタを調整 $("#photo").html($("#photolist li").eq(count).html()); $("#phototitle").text($("#photolist li").eq(count).find("img").attr("alt")); return false; }); $("#prev").click(function() { count --; //prev をクリックするとカウンタを1つ減少 if(count < 0 ) {count = total -1;} //カウンタを調整 $("#photo").html($("#photolist li").eq(count).html()); $("#phototitle").text($("#photolist li").eq(count).find("img").attr("alt")); return false; });
6行目は、next をクリックすると次の写真を表示するために、カウンタを1つ増加させています。
7行目は、カウンタが写真の総数に達したら、最初の写真を表示するために 0 にして調整しています。
8行目は、$("#photolist li").eq(count).html() でカウンタに対応する li 要素の html(img 要素の HTML)を、表示している写真 $("#photo") の HTML としています。
9行目は、写真のタイトルのテキストをカウンタに対応する li 要素の中の img 要素の alt 属性で設定しています。
この例では、ul 要素内に img 要素を直接記述しているため、これらの img 要素は非表示であってもページが読み込まれるとロードされます。そのため画像の数が多かったり、重かったりするとページの読み込みに時間がかかることになります。
以下は、img 要素を直接記述する代わりに、画像のパスと alt 属性の値を span 要素に文字列で記述する例です。
前の例との違いは、HTML で非表示にしている ul 要素内の li 要素に、それぞれ img_src, img_alt というクラスを指定した span 要素を img 要素の代わりに記述しています。その他は同じです。
注意:前の例と以下の例を同じページに記述して試す場合は、それぞれの id 属性の値を異なるものにする必要があります。
<div id="jqs-17"> <ul id="photolist" class="hidden"> <li><span class="img_src">images/sample01.jpg</span><span class="img_alt">黄色の花</span></li> <li><span class="img_src">images/sample02.jpg</span><span class="img_alt">山の湖</span></li> <li><span class="img_src">images/sample03.jpg</span><span class="img_alt">ビーチの夕日</span></li> <li><span class="img_src">images/sample04.jpg</span><span class="img_alt">紅葉</span></li> </ul> <p id="photo"><img src="images/jquery/sample01.jpg" alt="黄色の花"></p> <p id="phototitle"></p> <p><a id="prev" href="#">prev</a> <a id="next" href="#">next</a></p> </div>
1行目は、li 要素の総数を変数 total に取得しています。
7~9行目は、カウンタに対応する li 要素内の span 要素のテキストを取得してそれらを、それぞれ src 属性、alt 属性に設定しています。
10~11行目は、写真のタイトルのテキストをカウンタに対応する li 要素内のクラス img_alt の span 要素のテキストに設定しています。
var total = $("#jqs-17 .hidden li").length; //li 要素の総数を取得 var count = 0; $("#phototitle").text($("#photo img").attr("alt")); $("#next").click(function() { count ++; if(count == total) {count = 0;} $("#photo img") .attr('src', $("#photolist li").eq(count).find('span.img_src').text()) .attr('alt', $("#photolist li").eq(count).find('span.img_alt').text()); $("#phototitle") .text($("#photolist li").eq(count).find('span.img_alt').text()); return false; }); $("#prev").click(function() { count --; if(count < 0 ) {count = total -1;} $("#photo img") .attr('src', $("#photolist li").eq(count).find('span.img_src').text()) .attr('alt', $("#photolist li").eq(count).find('span.img_alt').text()); $("#phototitle") .text($("#photolist li").eq(count).find('span.img_alt').text()); return false; });
前のサンプルとほぼ同じものができます。こちらのサンプルはページの読み込みの際に、それぞれの画像を読み込んでいないので、それぞれの画像を初回表示する際に、ロードすることになります。
スクロールイベント
以下はスクロールイベントのショートハンドメソッドの書式です。
$(セレクタ).scroll(function() { セレクタで指定した要素をスクロールした時に実行する処理 });
セレクタは div 要素などを指定できますが、ここではブラウザをスクロールした場合についてみてみます。そのためセレクタには window を指定します。
スクロール距離(量)は scrollTop() を利用して取得できます。scrollTop() はマッチした最初の要素の縦スクロールオフセットを返します。
以下はセレクタに window を指定しているので、ブラウザのトップからのスクロール量を変数 scroll_y に取得してそれを表示しています。
<div id="jqs-19"> <p></p> </div>
$(window).scroll(function() { var scroll_y = $(this).scrollTop(); //$(this) は $(window) $("#jqs-19 p").text("スクロール距離(量): " + scroll_y); });
スクロール量が一定の値以上になった場合に、何らかの処理を行うには以下のようにします。
<div id="jqs-20"> <div></div> </div>
$(window).scroll(function() { var scroll_y = $(this).scrollTop(); //垂直方向のスクロール量 if(scroll_y > 26000) { //スクロール量が 26000 以上になった場合 $("#jqs-20 div").css({backgroundColor:'#F8DBDC' , width: '200px' }); }else{ //それ以外の場合 $("#jqs-20 div").css({backgroundColor:'#E5F6F9' , width: '50px' }); } });
上記の例の場合、スクロール量を数値(26000)で指定していますが、この場合、もし文書の内容が追加されたり削除されるとこの値も変更しなければなりません。
ドキュメント上での要素の表示位置を取得するには、offset() を使用します。
offset() はマッチした要素の、ドキュメントの左上からの相対位置を返すので、上からの位置を取得するには、top プロパティを利用します。
var offset_top = $(セレクタ).offset().top;
以下は、スクロールしてコンテンツの位置より 300px 手前でそのコンテンツの背景色と幅を変更する例です。
<div id="jqs-20_2" class="jqs_div"> <div></div> </div>
$(window).scroll(function() { var scroll_y = $(this).scrollTop(); if(scroll_y > $("#jqs-20_2 div").offset().top - 300) { $("#jqs-20_2 div").css({backgroundColor:'#F8DBDC' , width: '200px' }); }else{ $("#jqs-20_2 div").css({backgroundColor:'#E5F6F9' , width: '50px' }); } });
以下では、スクロールしてコンテンツが 300px 以上現れたときに処理を実行しています。
<div id="jqs-21"> <div></div> </div>
$(window).scroll(function(){ var scroll_y = $(this).scrollTop(); //垂直方向のスクロール量 var window_height = $(this).height(); //ウィンドウの高さ var target_pos_top = $("#jqs-21 div").offset().top; //トップからの位置 if (scroll_y > target_pos_top - window_height + 300) { $("#jqs-21 div").css({backgroundColor:'#D3F7E1' , width: '200px' }); }else{ $("#jqs-21 div").css({backgroundColor: '#E5F6F9' , width: '50px' }); } });
4行目で id が #jqs-21 の div 要素のトップからの位置を取得して、変数 target_pos_top に代入しています。
5行目の target_pos_top - window_height + 300 は、スクロールして対象の要素(#jqs-21)が、ブラウザの下辺から300pxの位置になるまでの量です。この量がスクロール量より大きくなった場合に処理を実行しています。
スクロールする量を offset() や scrollTop()、要素の高さを取得する height() などを使って導き出したりします。
リサイズイベント $(window).resize()
ウィンドウのサイズを変更(リサイズ)した際に何らかの処理をするには、 $(window).resize() を使用します。
$(window).resize(function() { /* リサイズされた際に行ないたい処理 */ });
リサイズイベントの場合、ウインドウをリサイズしている間中(ウインドウをドラッグしている間中)指定した処理が短い間隔で何回も呼ばれてしまい、ブラウザに負荷がかかったり、リサイズが終了した後も指定した処理が続いてしまう可能性などがあります。
そのような事態を避けるためには、setTimeout() と clearTimeout() を使ってリサイズ操作が終わった時にだけ処理を実行するようにします。
- setTimeout()メソッド
- このメソッドに関数と時間(ミリ秒)を指定すると、指定した時間が経過したときに、指定した関数が実行されます。 また setTimeout() の戻り値(タイマーID:整数)を claerTimeout() に渡すと関数の実行が取り消されます。
var timer = window.setTimeout(function(){ 何らかの処理や関数 }, 遅延時間);
リサイズ操作が終了した時点でのみ何らかの処理を実行する場合は以下のようにします。
var timer = false; $(window).resize(function() { if (timer !== false) { clearTimeout(timer); } timer = setTimeout(function() { // リサイズが終了した時点で行う処理または関数を記述 }, 200); });
- タイマー ID (変数 timer) を false に設定しておきます
- setTimeout() で 200ミリ秒後に「リサイズが終了した時点で行う処理」を指定します
- リサイズイベントが発生する度に、(timer !== false) が評価されます。 timer は整数なので clearTimeout(timer)が実行され「リサイズが終了した時点で行う処理」の実行が取り消されます
- これにより最後のリサイズイベントの場合のみ 200ミリ秒後に「リサイズが終了した時点で行う処理」が実行されます
ロード load
document-ready ハンドラには、DOM 解析が完了した(DOM を使って jQuery で HTML を操作できるようになった)時点で実行したい処理を記述します。
ready() を使用すると、大きな画像などの重いファイルがある場合、それらを読み込む前にプログラムが動作してしまい、ファイルの情報をうまく取得ができなかったり、うまく行かないことがあります。(HTML/DOM の読み込みが終わったタイミングでは、まだ画像などのコンテンツは読み込まれていない場合があります)
全ての画像が読み込まれなければ正しく動作しないような処理を行う場合は load イベントを使用します。但し、jQuery3.0 からはショートハンドの .load() は廃止になっているので、以下のように .on() を使って記述します。
$(window).on("load", function() { // 画像の高さを取得 var imgHeight = $('img').height(); // コンソールに画像の高さを出力 console.log(imgHeight); });
jQuery3.0 からは以下のショートハンドの記述はエラーになります。
$(window).load(function() { //jQuery3.0 からはエラーになります // 画像の高さを取得 var imgHeight = $('img').height(); // コンソールに画像の高さを出力 console.log(imgHeight); });
また、jQuery1.x の場合は以下のように document-ready ハンドラ内に、 $(window).on("load",...) を記述しても問題ありませんが、jQuery3.0 からは何も起きません(以下の場合、エラーも表示されませんが、高さも出力されません)。
$(function(){ $(window).on("load", function() { // 画像の高さを取得 var imgHeight = $('img').height(); // コンソールに画像の高さを出力 console.log(imgHeight); }); });
jQuery3.0 からの場合は、 $(window).on("load",...) を使う場合は、document-ready ハンドラは使えないようなので(実際には不要なので)、直接記述します。(ロードしてあるので、document-ready ハンドラは不要)
$(window).on("load", function() { // 画像の高さを取得 var imgHeight = $('img').height(); // コンソールに画像の高さを出力 console.log(imgHeight); });
フォーム関連イベント
フォーム関連のイベント(focus()、blur() 、change() 、submit())やフォーム要素の値の操作は 「jQuery フォームの操作」をご覧ください。
フォーム部品の利用
フォーム(form 要素)を使うとユーザーが入力した内容をサーバー上のプログラムにデータとして送信することができますが、サーバー上のプログラムにデータを送信する必要がない場合は、form 要素は使わずにフォームの部品だけを利用することができます。
以下は input 要素と button 要素を使って、ユーザーの入力した値の乗算の結果を表示する例です。
<input type="text" size="10" id="value1" placeholder="value1"> x <input type="text" size="10" id="value2" placeholder="value2"> <button id="calculate">実行</button> <p class="margin_top30">掛け算の値:<span id="calculation_result"></span></p> <p id="alert" style="color:red;"> </p>
乗算の結果の出力は「実行」と言うボタンがクリックされた場合のクリックイベントとして処理します。
input 要素の値は val() で取得することができます。
ユーザーから入力された値を使う場合は、不正な値が入力されていないかを確認します。この例の場合は入力された値が数値でなければメッセージを表示して return で終了しています。
4行目はもしすでにメッセージが表示されている場合は、一度クリアする処理です。
入力された値が数値の場合のみ、それらの値を掛け算した結果を出力しています。
$("#calculate").click(function() { var val1 = $("#value1").val(); var val2 = $("#value2").val(); $("#alert").text(" "); if(!$.isNumeric(val1) || !$.isNumeric(val2)) { $("#alert").text("半角文字の数値を入力してください。"); return; }else { $("#calculation_result").text( val1 * val2 ); } });
掛け算の値:
関連ページ:消費税計算ツール
input イベント
input 要素や textarea 要素の内容(値)が変更された際に発生するイベントに change と input があります。
change イベントは要素の変更が終わったとき(テキストフィールドやテキストエリアの場合はフォーカスを失った時)に発生するのに対し、input イベントは要素の値が変更されるたびに発生するのでリアルタイムで処理を実行することができます。
以下はに change と input イベントの違いを確認するサンプルです。
input イベントは変更がリアルタイムに反映されるのに対して、change イベントではテキストフィールドがフォーカスを失った時に反映されます。
また、change イベントはショートハンドメソッドがありますが、input イベントにはショートハンドメソッドがないので on() を使います。
<input type="text" id="input" size="30" placeholder="テキストを入力"> <div class="outputs"> <p id="output1" class="output"></p> <p id="output2" class="output"></p> </div>
$("#input").on('input', function() { $("#output1").text($("#input").val()); }); $("#input").on('change', function() { $("#output2").text($("#input").val()); });
input イベント
change イベント
以下はレンジ入力(type="range" の input 要素)の変更をリアルタイムに反映させる例です。
スライダー()の width と height の値を変更すると、div 要素の幅と高さ、及び現在のスライダーの値をリアルタイムに反映させます。
<p> width: <input type="range" name="width" min="5" max="300" value="50" step="1"> <span class="width_val">50</span> </p> <p> height: <input type="range" name="height" min="5" max="300" value="50" step="1"> <span class="height_val">50</span> </p> <div id="box"></div>
//name='width' の input 要素に input イベントを設定 $("[name='width']").on('input',function() { //name='width' の input 要素の値 let width_value = $(this).val(); $(".width_val").text(width_value); $("#box").width(width_value); }); //name='height' の input 要素に input イベントを設定 $("[name='height']").on('input',function() { //name='height' の input 要素の値 let height_value = $(this).val(); $(".height_val").text(height_value); $("#box").height(height_value); });
アロー関数を使う場合は this が参照できないので、引数にイベントオブジェクト(この例では e)を受け取りイベントの発生している要素に currentTarget でアクセスして、その value プロパティで値を取得します。
//アロー関数を使う場合 $("[name='width']").on('input',(e) => { let width_value = e.currentTarget.value; $(".width_val").text(width_value); $("#box").width(width_value); });
width: 50
height: 50