
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で質問しましょう!
似たような質問が見つかりました
- Access(アクセス) AccessVBAで任意の複数リンクテーブルをAccessVBAを動かす際に削除したいと考えておりま 1 2022/11/17 15:45
- Visual Basic(VBA) i=cells(Rows.Count, 1)とi=cells(Rows.Count, 2)の違い 2 2022/04/06 10:04
- ノートパソコン ソフトアンインストール残存ファイル 3 2022/09/13 18:15
- その他(ネットショッピング・通販・ECサイト) ピザハットアプリについて 2 2022/12/17 10:07
- 教えて!goo なんで同じ質問を繰り返す人の質問に「指摘」すると削除されるのですか? 5 2023/06/08 20:37
- サーバー windowsサーバの権限設定、フォルダ削除できないアカウントを作りたい 1 2023/04/07 09:58
- その他(教育・科学・学問) シンプルと複雑の違い 1 2022/08/12 13:31
- X(旧Twitter) 楽天モバイルなどで作った電話番号をTwitter認証用に登録する場合について 1 2023/02/04 21:42
- 知的財産権 ハンドルネームに商標登録されている名前を使えますか? 1 2023/04/11 16:45
- その他(データベース) pythonでsqlight勉強中、クエリー結果の利用法教えて下さい 1 2022/04/28 20:38
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
jQueryで特定id以外の下にある...
-
<div ~ </div> で囲まれたテキ...
-
クリックで特定のdiv要素が表示...
-
<Div>の中の要素の数を調べる
-
classList で、class名が付かな...
-
ラジオボタンの切替で表示する...
-
VBScript+IEのチェックボック...
-
jqueryを使って無駄なspanタグ...
-
xmlの同一要素名を配列に入れる...
-
クリックすると隠れたテキスト...
-
テキストエリア内の一部の文字...
-
displayの状態を取得したい
-
10秒後に1秒ごとに1行づつ表示...
-
[急ぎ] videoタグで埋め込んだm...
-
iframe内のリンクが飛ばないの...
-
document.all.id1.innerText="ok";
-
JavaScript オンマウスで画像...
-
読み込んだQRコードをフォーム...
-
innerHTMLに入れたリンクが反応...
-
getElementByIdの戻り値がnull...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
MAX関数を使ってからLEFT JOIN...
-
javascriptテキストBOX色を元に...
-
読み込んだQRコードをフォーム...
-
指定したパスが現URLに含まれて...
-
removeEventListenerについて
-
iframe内のリンクが飛ばないの...
-
createElementで作成した要素を...
-
IFRAMEの表示/非表示を切り替え...
-
jQueryで同じ要素の先頭へ親要...
-
ページ読み込み完了の3秒後にリ...
-
jQueryで特定id以外の下にある...
-
jQueryで同じid属性が複数あっ...
-
表示・非表示のスクリプトで、...
-
jQueryでシンプルドラッグドロ...
-
Gif画像のアニメーションが再生...
-
【HP作成】クリックすると下...
-
クリックすると下に説明文が出...
-
背景色を透明化
-
プルダウンとチェックボックス...
-
javascriptでpostした値が取得...
おすすめ情報