
Sponsored Link
[jQuery]onとoff
on()メソッド
構文
- $(セレクタ).on( イベント名 [,object], function(event){})
- $(調査範囲).on( イベント名, セレクタ [,object], function(event){})
- $(調査範囲).on( object, セレクタ [,object] )
- $(セレクタ).on( object )
何が出来るのか
基本的には下記の事が出来ます。
- 後から要素を追加した場合もイベント発火させる
- 複数のイベントを発火させる
詳しく見てみましょう。
1. 後から要素を追加した場合もイベント発火させる
例えば、下記のソースがあったとします。
共通ソース
<body>
<div>Example Message!!</div>
<script>
$(function(){
var button = $("<button>").text("button");
$("div").append(button);
});
</script>
</body>
まずは、htmlファイル上に始めからある要素に対して、イベントを発火するケースです。
今回の場合、div要素に対してクリックイベントを発動させます。
構文1 $(セレクタ).on( イベント名 [,object], function(event){})
$('div').on("click", function(){
alert("Hello Work!!");
});
$('div').on("click", {test: 100}, function(event){
alert(event.data.test); // =>100
});
// これでも可能
var obj = {
test: 100,
fuga: 500,
hoge: "お腹すいた"
};
$('div').on("click", obj, function(event){
alert(event.data.test); // =>100
alert(event.data.fuga); // =>500
alert(event.data.hoge); // =>お腹すいた
});
これでclickイベントが発火します。
objectのプロパティを取得することも出来ます。
次に、後から要素を追加した場合です。
今回の場合、button要素に対してクリックイベントを発動させます。
後から要素を追加する場合、最初の例のような
$('button').on("click", function(){
alert("Hello Work!!");
});
と、いう書き方では発火しません。
これは最初にページを読み込んだ際に、button 要素が存在していなかった為にイベントが発火出来ないようです。
これをイベント発火させる為には下記のように書きます。
構文2 $(調査範囲).on( イベント名, セレクタ [,object], function(event){})
$(document).on("click", "button", function() {
alert("Hello Work!!");
});
$(document).on("click", "button", {test: 100}, function(event){
alert(event.data.test); // =>100
});
これでbuttonをクリックした際にアラートが立ちます。
ちなみに、$(document)
とありますが、囲まれている部分が対象となりますので
$('body').on("click", 'button', fn);
$('div').on("click", 'button', fn);
でもイベント発火します。
2. 複数のイベントを発火させる
onメソッドは複数のイベントを指定することが出来ます。
例えば、
$(document).on("click mouseenter", "button", function() {
alert("Hello Work!!");
});
これでボタンをクリックした時と、マウスカーソルがボタン要素に入ったときにアラートが立ちます。
半角スペースで区切って複数のイベントを書くことで、複数のイベントにも対応させる事が出来ます。
また、objectでイベントを指定することも出来ます。
Ex.1)構文3 $(調査範囲).on( object, セレクタ [,object] )
var obj{};
obj.mouseenter = function(event) {
$(this).css('color', '#f00');
};
obj.mouseleave = function(event) {
$(this).css('color', '#000');
};
obj.click = function(event) {
$(this).css('color', '#0f0');
};
$(document).on(obj, 'button');
// この書き方も可能
$(document).on({
'mouseenter': function(event) {
$(this).css('color', '#f00');
},
'mouseleave': function(event) {
$(this).css('color', '#000');
},
'click': function(event) {
$(this).css('color', '#0f0');
}
}, 'button');
これで、
- ボタンにカーソルが入ったら文字色が赤
- ボタンからカーソルが離れたら文字色が黒
- ボタンをクリックしたら文字色が緑
になります。
また、第二引数にセレクタを記載せず、
頭にセレクタを記載する方法でも同じイベントが発生します。
構文1では動的に追加した要素には反応しませんが、構文4では動的に追加した要素にも反応します。(理由は分かりません・・・)
Ex.2)構文4 $(セレクタ).on( object [, object])
var obj{};
obj.mouseenter = function(event) {
$(this).css('color', '#f00');
};
obj.mouseleave = function(event) {
$(this).css('color', '#000');
};
obj.click = function(event) {
$(this).css('color', '#0f0');
};
$('button').on(obj);
// この書き方も可能
$('button').on({
'mouseenter': function(event) {
$(this).css('color', '#f00');
},
'mouseleave': function(event) {
$(this).css('color', '#000');
},
'click': function(event) {
$(this).css('color', '#0f0');
}
});
また、ちょっとハマったケースです。
Ex.) イベントが効かない
var obj {
test: 100,
fuga: 500,
hoge: "お腹すいた"
};
obj.mouseenter = function(event) {
$(this).text(event.data.test);
};
obj.mouseleave = function(event) {
$(this).text(event.data.fuga);
};
obj.click = function(event) {
$(this).text(event.data.hoge);
};
$(document).on(obj, 'button'); //=>効かない!
$('button').on(obj); //=>効かない!
これは全て効きません。効かないというと語弊がありますが・・・。
console.logで確認すると分かりますが、ちゃんとイベントは発生しています。
が、object値が渡されていないのでエラーが発生しイベントが中止されます。
あくまでも第一引数はイベントを指定するobjectであって、
その中身(今回の場合はobj.test
, obj.fuga
, obj.hoge
)は渡しません。
イベントを発生させるには、
- functionの中身をobject値を含ませないようにする(前例の構文4)
- 第三引数でobject値を渡すようにする(後述のEx.3、Ex.4)
と設定するようにしましょう。
それでは次はobject値を渡すため、第三引数を指定した例を見てみましょう。
Ex.3)構文3 $(調査範囲).on( object, セレクタ [,object] )
var obj = {
test: 100,
fuga: 500,
hoge: "お腹すいた"
};
var obj2 = {
test: 101,
fuga: 501,
hoge: "お腹いっぱい"
};
obj.mouseenter = function(event) {
alert(event.data.test);
};
obj.mouseleave = function(event) {
alert(event.data.fuga);
};
obj.click = function(event) {
alert(event.data.hoge);
};
$(document).on(obj, 'button', obj);
$(document).on(obj, 'div', obj2);
これで、
- ボタンにカーソルが入ったら 100 のアラート
- ボタンからカーソルが離れたら 500 のアラート
- ボタンをクリックすると お腹すいた のアラート
になります。
divについては、
- divにカーソルが入ったら 101 のアラート
- divからカーソルが離れたら 501 のアラート
- divをクリックすると お腹いっぱい のアラート
になります。
また下記の方法でも同様に動作します。
Ex.4)構文4 $(セレクタ).on( object [, object])
var obj = {
test: 100,
fuga: 500,
hoge: "お腹すいた"
};
var obj2 = {
test: 101,
fuga: 501,
hoge: "お腹いっぱい"
};
obj.mouseenter = function(event) {
alert(event.data.test);
};
obj.mouseleave = function(event) {
alert(event.data.fuga);
};
obj.click = function(event) {
alert(event.data.hoge);
};
$('button').on(obj, obj);
$('div').on(obj, obj2);
最後の2行が変わっただけですが、objectのみで設定する事も可能です。
object値を渡したい場合は、このように設定してみて下さい。
今回は3種類のイベントしか書いてませんが、イベントはたくさんあります。
load
や scroll
や resize
等々、色んなイベントを想定して、
onと一緒に使うと新しい道が開けるかもしれません。
off()メソッド
構文
- $(onメソッドで指定したセレクタ).off()
- $(onメソッドで指定したセレクタ).off( イベント名 )
- $(onメソッドで指定したセレクタ).off( イベント名, セレクタ )
- $(onメソッドで指定したセレクタ).off( イベント名, [セレクタ,] function )
- $(onメソッドで指定したセレクタ).off( 複数のイベント名[, セレクタ] )
何が出来るのか
onメソッドで設定をしたイベントを解除します。
実際に使ってみよう
<body>
<div>Change Message!!</div>
<button id="alert001">Alert 1</button>
<button id="alert002">Alert 2</button>
<div>
<p id="addButton"></p>
</div>
<span>change obj</span>
<input type="button" id="offEvent" value="clear">
<script>
var count = 0;
$(function(){
// button要素をdiv#addButton 内に追加する
var button = $("<button>").attr('id', 'alert003').text("Alert 3");
$("#addButton").append(button); //=>div#addButton内にbutton要素を追加する
var obj = {
text: "Change Text!!!!",
text2: "Add Text!!!!",
text3: "変わりました!!!!!",
text4: "change obj",
str1: "Alert 1だよ",
str2: "Alert 2だよ",
str3: "Alert 3だよ",
};
obj.mouseenter = function(event) {
$(this).text(event.data.text3)
.css({
"font-size" : "20px",
"font-weight" : "bold",
"color" : "#f00"
});
};
obj.mouseleave = function(event) {
$(this).text(event.data.text4)
.css({
"font-size" : "",
"color" : "",
"font-weight" : ""
});
};
function inputText(e) {
$(this).text(e.data.text3);
}
$('#alert001').on('click', obj, function(e) {
alert(e.data.str1); //=> alert 1だよ
});
$('#alert001').on('click', obj, inputText);
$('#alert002').on('click', obj, function(e) {
alert(e.data.str2); //=> alert 2だよ
});
$('div').on('click', '#alert003', obj, function(e) {
alert(e.data.str3); //=> alert 3だよ
});
$('div').eq(0).on('mouseenter mouseleave', obj, function(e) {
$(this).text(e.data.text); //=> カーソルをあてるとテキストが変わる。 カーソルが離れてもテキストが変わる。(同じ文言)
if(e.type === "mouseleave") $(this).text(++count + "回目");
});
$('div').on('click', '#addButton', obj, function(e) {
$(this).append(e.data.text2); //=> クリックするとテキストを追加する
});
$('span').on(obj, obj);
$('#offEvent').on('click', function(event) {
// ここにoffメソッドを書く
});
});
</script>
</body>
上記onメソッドの復習がてら、ざっと挙動を書きます。
- p#addButton内にbutton要素が追加される(id: alert003, value: Alert3)
- alert1 をクリックすると、
"alert 1だよ"
というアラートが立つ - alert1 をクリックすると、ボタンのテキストが
"変わりました!!!!!"
になる - alert2 をクリックすると、
"alert 2だよ"
というアラートが立つ - alert3 をクリックすると、
"alert 3だよ"
というアラートが立つ - Change Message!!にカーソルをあてると、
"Change Text!!!!"
に変わる。
カーソルを外すとカーソルを外した回数が表示される。 - div#addButtonをクリックすると、
"Add Text!!!!"
というテキストが追加される - change obj の箇所にカーソルをあてると、
"変わりました!!!!!"
というテキストが
font-size: 20px, font-weight: bold, color: #f00
で変更される。
カーソルを外すと、"change obj"
というテキストでCSSが元に戻る。
さて、ここからoffメソッドの挙動を追加していきます。
Ex.1)構文1 $(onメソッドで指定したセレクタ).off()
$('#alert002').off();//=> alert2のイベントが解除される
$('div').off(); //=> divのイベントが全て解除される
$('span').off(); //=> spanのイベントが全て解除される
Ex.2)構文2 $(onメソッドで指定したセレクタ).off( イベント名 )
$('div').off('mouseenter') //=> divのmouseeventイベントのみが解除される
$('span').off('mouseleave') //=> spanのmouseleaveイベントのみが解除される
恐らくは直感的に分かると思います。
注意点としては、onメソッドの前の調査範囲で指定したセレクタをoffメソッドで指定しなければなりません。
例えば、p#addButton
のイベントを解除したいと思って、
$('#addButton').off()
$('#addButton').off('click')
などと、記載しても解除されません。
onメソッドの調査範囲で設定しているのは div
ですので、divで設定しましょう。
また、セレクタや関数を指定して設定する事も出来ます。
Ex.3)構文3 $(onメソッドで指定したセレクタ).off( イベント名, セレクタ )
$('div').off('click', '#alert003') //=> divのidがalert003のclickイベントのみが解除される
こうする事で#alert003
のクリックイベントだけを解除できます。
因みに、イベントは半角スペースで区切って複数指定することが出来ます(後述)が、
セレクタと関数については複数を選ぶ事は出来ません。
別々にoffメソッドを指定するか、classで設定するのがいいと思います。
解除する関数を指定することもできます。
第一引数に関数単体を指定して解除という方法は出来ません。
必ず第一引数にはイベントの指定が必要です。
Ex.4)構文4 $(onメソッドで指定したセレクタ).off( イベント名, [セレクタ,] function )
$('#alert001').off('click', inputText) //=>alert001のinputTextイベントのみが解除される
$('#alert001').off(inputText) //=>これは出来ない
関数名で解除することは出来ました。
しかし無名関数の場合は、関数名がないので指定することが出来ません。
その場合は、イベントに名前を付けて、その名前空間で指定することが出来ます。
Ex.5)無名関数を名前空間で解除する
$('#alert001').on('click.inputText', obj, function(e) {
alert(e.data.str1); //=> alert 1だよ
});
// 上記のonの解除は下記のようにする
$('#alert001').off('.inputText');
関数を指定して解除するというよりは、
イベントに名前をつけて、そのイベントを解除するという感じですね。
objectで設定されているイベントを指定することも可能です。
また、objectを丸ごと指定する事も可能です。
Ex.6)構文5 $(onメソッドで指定したセレクタ).off( object )
$('span').off('mouseleave') //=> spanのmouselaveイベントのみが解除される。
$('span').off(obj) //=> spanのobjectのイベントが解除される。
イベントについては、複数のイベントを半角スペースで分けて同時に記載する事が出来ます。
セレクタ箇所にobjectは指定出来ません。第二引数を指定するときは、セレクタを指定して下さい。
Ex.7)構文6 $(onメソッドで指定したセレクタ).off( 複数のイベント名[, セレクタ] )
$('div').off('mouseenter mouseleave') //=> divのmouseenterとmouseleaveイベントが解除される。
$('div').off('mouseenter mouseleave', obj) //=> これは出来ない
.click(fn) と .on(“click”, fn) の違い
A. ありません。
と、言うと語弊があるかもしれないですが、
この構文に限定して言えば同じ働きをします。
$('div').click(function() {
alert("Hello Work!!");
});
と、
$('div').on("click", function() {
alert("Hello Work!!");
});
は同じです。
appendやafter等で動的に要素を追加したとしても同じです。
この構文で書いたコードでは、追加要素を捉えることはできません。
ここで、onの本領が少し発揮されます。
前項で書いた通り、onは動的に追加した要素にも反応するようにする事が出来ます。
clickでは出来ませんので、動的に追加する要素がある場合には統一する意味でもonを使用したほうがいいと思います。
引数のeventって何なの?
jQueryのEventオブジェクトです。
Eventオブジェクトを通して、イベントハンドラに渡されます。
例えば、
$(document).on("click", 'button', function(event){
alert(event.type);
});
とすれば、ボタンをクリックした際に、clickというアラートが立ちます。
eventのプロパティやメソッドは、target以外にも多くありますので、
詳細は下記を確認してみてください。
jQuery.Event – jQuery 日本語リファレンス
公式 | Event Object | jQuery API Documentation