
JavaScript勉強中なのですが、removeEventListener("mousemove",funcname,!1)というメソッドの使い方というか、使い所がイマイチピンとこなくてこまっています。
addEventListener("mousemove",funcname,!1)で登録したイベントリスナーを削除するということだと思うのですが、削除した場合としなかった場合の違いって具体的にどういったことなんでしょうか?
メモリリークとかの問題なのでしょうか?
また、具体的に使う場合の簡単な例を教えてもらえないでしょうか?
よろしくお願いいたします。
No.2ベストアンサー
- 回答日時:
主な理由はメモリリーク対策だと思いますが、それ以外にもあります。
window.onloadのようにページ読み込みに1度だけ実行するようなものであれば、
「ハンドラを監視するためのメモリ」を解放することで
厳密にはリークしているわけではありませんが、全体の消費メモリの削減になります。
また、オブジェクトがドキュメントから削除される場合。(これがメモリリークの主な原因です。)
<div id="div1"></div>
<button id="btn1"></div>
document.getElementById('div1').addEventListener('click', func, false);
document.getElementById('btn1').addEventListener('click',
function(){
div1=document.getElementById('div1');
div1.parentNode.removeChild(div1);
} , false);
このような場合では、div1が削除されたあとは、div1に登録されたclickイベントハンドラだけが使用できないまま残ることになります。
この場合も、removeEventListenerでイベントハンドラを削除しておいた方が、余分なメモリを使わなくて済みます。
document.getElementById('div1').addEventListener('click', func, false);
document.getElementById('btn1').addEventListener('click',
function(){
div1=document.getElementById('div1');
div1.removeEventListener('click', func, false); //メモリリーク対策
div1.parentNode.removeChild(div1);
} , false);
もう一つの例。
上の例ではdiv1を削除してから、もう一度btn1を押すと、「div1がない」というエラーになります。
そのため、div1の存在チェックをしてもいいのですが、
function(){
div1=document.getElementById('div1');
if(div1){
div1.parentNode.removeChild(div1);
}
}
ボタンを押したときのイベントハンドラを削除し、何も起こらないようにすることもできます。
document.getElementById('btn1').addEventListener('click',
function(event){
div1=document.getElementById('div1');
div1.removeEventListener('click', func, false); //メモリリーク対策
div1.parentNode.removeChild(div1);
this.removeEventListener(event.type, arguments.callee, false); //連続クリック防止
} , false);
*IE対策として、event.typeではなく'click'で処理する方が良いと思います。
*ボタンの場合はbtn1.disabled=trueという方法もあります。連続クリック防止はこの方法がよく使われます。
あと、!1というのはfalseのショートコーディングだと思います。
No.6
- 回答日時:
#5 です。
重大なミスをしていることに気がつきました。
IE6 SP2- は addEventListener を持たないため、addEventListener で前述のメモリリークパターンにはなりません。
というわけで、サンプルを attachEvent に変更しました。
http://jsfiddle.net/fXHDk/1/
addEventListener でメモリリークパターンが存在するなら、addEventListener を使用可能なブラウザにメモリリークのバグが混入していることになりますね。
候補は IE9, Firefox, Google Chrome, Safari, Opera になるでしょうか。
No.5
- 回答日時:
メモリリークとはブラウザに存在するバグの一種です。
本来解放されるべきメモリが解放されない状態をメモリリークといいます。ブラウザに存在するバグなので「特定のブラウザ」で「特定の状況」にならないとメモリリークは発生しません。
有名どころとして IE6 SP2- に存在した循環参照によるメモリリークパターンがあります。(Windows XP SP3 で修正済み)
http://msdn.microsoft.com/ja-jp/library/bb250448 …
典型的なメモリリークパターンのサンプルを http://jsfiddle.net/fXHDk/ に置きました。
私の見たところでは #2 の方のコードはこのパターンではないようです。
他のメモリリークパターンも勿論あると思いますが、どのブラウザでどういう状況で発生するメモリリークなのか、を説明しないと質問者さんにも伝わらないのではないかなと思います。
# 私は「循環参照はバグが混入しやすい部分なので、可能な限り循環参照しないパターンにする方がよい」とアドバイスを受けたことがあります。
# おそらく、babu_baboo さんも同じような考えを持っているのだと思います。(違ったらすみません)
---
addEventListener でイベントを定義するとブラウザは定義した回数だけメモリを消費します。
これは仕様通りの動作なのでメモリリーク(バグ)ではありません。
#2 でも指摘されていますが、一回だけ使用する window.onload など既に不要となったイベントがあれば removeEventListener で削除しておくのは良い習慣です。
不要になったイベントを削除することで低スペックなPCでも十分なパフォーマンスで動作することが出来るようになります。
また、window.onunload 時に全てのイベントを削除しておくことも良い習慣だといわれます。
(この習慣によって循環参照によるメモリリークを完全に防ぐことが出来ます。)
---
> addEventListener("mousemove",funcname,!1)
DOM4 では addEventListener の第三引数を指定しなかったときに false が適用される仕様を策定中です。
http://dvcs.w3.org/hg/domcore/raw-file/tip/Overv …
まだ Working Draft なので DOM4 に準じた書き方にするのはどうかと思いますが、念のため。
!1 はショートコーディングだと思いますが、false と比較して遅くなる点を指摘しておきます。
誤解されがちですが、「ショートコーディング === 高速」ではありません。
高速化するためにコードが長くなることはよくあります。
No.1
- 回答日時:
とうろくするものあれば、さくじょするのもあり・・・
ひつようが なくなったら はずすべき。(ふだんの かいとうでは めったに だれも かきませんね)
でも、すぐに また つかうのなら それは、つかいかたが おかしい。
「れい」に、なってない?!
function handler (event) {
switch (event.type) {
case 'click' :
alert ('ok');
break;
case 'load' :
document.addEventListener ('click', handler, false);
window.addEventListener ('unload', handler, false);
break;
case 'unload' :
document.removeEventListener ('click', handler, false);
window.removeEventListener ('unload', handler, false);
break;
}
}
window.addEventListener ('load', handler, false);
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
MAX関数を使ってからLEFT JOIN...
-
createElementで作成した要素を...
-
javascriptでpostした値が取得...
-
innerHTMLに入れたリンクが反応...
-
読み込んだQRコードをフォーム...
-
removeAttribute()メソッドで削...
-
jQueryで同じid属性が複数あっ...
-
jQueryでクリックされた要素のi...
-
レイアウト枠に説明表示(ウィ...
-
オンマウスで流れる文字
-
バッチファイルでカウントアッ...
-
eclipseでcssを使うためには?
-
jspでcssが読み込めない
-
htmlの記述で link rel=styles...
-
掲示板で投稿内にリンクがある...
-
1枚の画像をクリックすると複数...
-
JSPでの画像ファイル表示
-
jQueryで同じクラス名のものを...
-
画像をクリックしてその地点の...
-
リキッドデザイン3カラム左端幅...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
MAX関数を使ってからLEFT JOIN...
-
javascriptテキストBOX色を元に...
-
読み込んだQRコードをフォーム...
-
removeAttribute()メソッドで削...
-
IFRAMEの表示/非表示を切り替え...
-
VBAのことについて教えてくださ...
-
プルダウンメニュ 展開時にずら...
-
removeEventListenerについて
-
javascriptでpostした値が取得...
-
プルダウンとチェックボックス...
-
クリックすると隠れたテキスト...
-
指定字数以降隠す
-
ホームページ(デフォルトペー...
-
特定のものにだけスクリプトを...
-
自働生成される<div>タグに連番...
-
テキストエリア内の一部の文字...
-
背景色を透明化
-
テキストボックスに入力された...
-
隣のフレームの中のスタイルを...
-
java折りたたみタグを複数設置...
おすすめ情報