-----
<ul>
<li>test1</li>
<li>test2</li>
<li>test3</li>
</ul>
<script type='text/javascript'>
(function(){
var li = document.getElementsByTagName('li');
for(var i=0,max=li.length; i<max; i++){
li[i].onclick = function(){
alert(i);
};
}
})();
</script>
-----
上記スクリプトを実行すると、全てのli要素でクリックしたときに "3" がalertされます。
0,1,2 をそれぞれalertしたいのですが、どういった方法が考えられるでしょうか?
現在作成しているスクリプトでは、下記のようにidに値を保持しています。
もう少しスマートな方法がある気がするのですが…。
---
li[i].id = 'test' + i;
li[i].onclick = function(){
alert(this.id.replace(/^test(\d+)/, '$1'));
};
---
No.8ベストアンサー
- 回答日時:
メモリーリークにみえて、そうでない・・・
>HTMLObjectに勝手にプロパティ
これはよくないことだじょ!そうおそわった。
ついでにいうと、いべんとをなんこもていぎするより
No3.みたいにおおもとにひとつでじゅうぶん。
innerHTMLで、ぜんたいをかきかえたとしてもOK!
と、TAGindex
http://www.tagindex.com/cgi-lib/q4bbs/patio.cgi
でおそわったじょ!
参考URLの掲示ありがとうございます。
> メモリリーク
非常に難解で、まだ完全には理解できていないのですが、
「要素ノードとクロージャの間で循環的に参照(循環参照)してしまい、タブを閉じる際にIEがこれを解放しないためにリークする」
という理解でいいのでしょうか?
調査の結果、メモリリークの回避手段がいくつかあることがわかりました。
----
1. 関数をネストしない
HTML ページの DOM オブジェクトへの循環参照はメモリ リークが発生します。
http://support.microsoft.com/kb/830555/ja
IEのメモリリーク問題
http://p2b.jp/index.php?UID=1131336575
2. elementNode=null; で参照を外す
IE6のメモリリークを華麗に回避 - zorioの日記
http://d.hatena.ne.jp/zorio/20080609/1213028969
3. document一つをイベントリスナに登録し、クロージャを使わない (#3と同じ)
掲示板/JavaScript質問板/過去ログ/一覧/ onclik時に上部へ行く方法(特殊) - TAG index Webサイト
http://www.tagindex.com/kakolog/q4bbs/1301/1650. …
4. 使い終わったイベントハンドラを外す関数を定義する
クロージャとメモリリークについてのコピペ - JavaScriptとかPerlとかPHPとかさくらとか勉強する (>702の createLeakFreeClosure(closure) )
http://d.hatena.ne.jp/lesamoureuses/20080416/120 …
----
「循環の仕組み」が不完全な理解なので、「1=理解、2=何となく理解、3,4=理解不能」と心許ないのが現状です。
今のところ、2. を応用して
----
(function(){
var li = document.getElementsByTagName('li');
for(var i=0,max=li.length; i<max; i++){
li[i].onclick = (function(i){
return function(){// functionを返す(クロージャ)
alert(i);
};
})(i);
li[i] = null;// 要素ノードの参照を外す
}
})();
----
で運用しようと考えていますが、これで問題ないでしょうか?
また、間違って理解しているところはないでしょうか?
(曖昧な理解なだけに心配です…。)
No.11
- 回答日時:
ごめん!かんちがい!
>li[i] = null; // 要素ノードの参照を外す
'}'のいち、みまちがえてました。
onclickをうわがきされると、うごかなくなるよ
この回答への補足
まだ理解がおぼつかないですが、引き延ばしても仕方がないのでこれにて締め切りたいと思います。
そこでまたわからないことがあれば質問するかもしれません。その時はよろしくお願いします。
ありがとうございました。
> onclickをうわがきされると、うごかなくなるよ
そうですね。
window.onload と同じく、同じ場所に上書きされると初めに登録したイベントが動かなくなります。
それは承知しているのですが、今回の場合同じ場所にonclickイベントを登録する意義が見あたらないのでいいかなと。
また、「コードはシンプルに」という点には拘ってまして、長いコードは出来るだけ避けたいという思いがあります。
でも、「イベントリスナを使う癖を付けておいた方が良いのでは」という気もしますし、
addEvent() 的な関数を使用して elementNode=null; がいいような気もします。
落としどころが難しく、悩みます…。
No.9
- 回答日時:
そもそも、「保持する」必要ありますか?
まぁリソースは有効活用したほうがいいですが・・・
<script type='text/javascript'>
window.onload=function(){
var li = document.getElementsByTagName('li');
for(var i=0; i<li.length; i++){
li[i].onclick = function(){
var li = document.getElementsByTagName('li');
for(var i=0;i<li.length;i++){
if(li[i]==this) break;
}
alert(i);
};
}
};
</script>
<ul>
<li>test1</li>
<li>test2</li>
<li>test3</li>
</ul>
> そもそも、「保持する」必要ありますか?
実際には要素ノードリストを2組持ち、iの値で2つを関連づけています。
関連付けの仕組みを変えればiが不要となるはずですが、アルゴリズムを根本から直す必要がありそうです。
ちなみに、http://vird2002.s8.xrea.com/test/dl2tab.html が実際のスクリプトです。
「同じノードを探し出す」
初めはそのようにしていましたが、そもそも一度捕まえたノードは再利用した方が効率がいいんじゃないか、と思い質問に至りました。
掲示されたコードはアプローチの一つとして参考にさせていただきます。
ありがとうございます。
No.7
- 回答日時:
前々からできるかどうか不安だった方法を、この際だから調べてみました。
邪道かも。決していい方法であるとは思っていません。
ie8,FireFox,Operaで確認。(うまくいくのか・・・うれしいような残念なような・・・)
HTMLObjectに勝手にプロパティ追加してます。
<ul>
<li>test1</li>
<li>test2</li>
<li>test3</li>
</ul>
<script type='text/javascript'>
window.onload=function(){
var li = document.getElementsByTagName('li');
for(var i=0,max=li.length; i<max; i++){
li[i].i=i
li[i].onclick = function(){alert(this.i);
};
}
}
</script>
> HTMLObjectに勝手にプロパティ追加してます。
こ、こんな方法があるとは…。
FirebugのDOMタブを見ると、「プロパティi」がちゃんと見えています。
IE7でも動きました。動いてしまうんですね…。
ちょっと怖くて使えそうにありませんが、興味深い現象でした。
ありがとうございます。
No.6
- 回答日時:
window.onload = function (){
var li = document.getElementsByTagName('li');
for(var i=0,max=li.length; i<max; i++){
make_li_func(li[i],i);
}
}
function make_li_func(li,no){
var i=no+1;
var func=li;
func.onclick = function(){
alert(i);
}
}
で出来ました。
もしかして、原理はbabu_babueさんと同じかしら?
回答ありがとうございます。
新しくユーザ定義関数を定義したのですね。
もうちょっと簡略化して、
---
var li = document.getElementsByTagName('li');
function test(node,i){
node.onclick = function(){
alert(i);
};
}
for(var i=0,max=li.length; i<max; i++){
test(li[i],i);
}
---
でも出来ました。
> もしかして、原理はbabu_babueさんと同じかしら?
「引数で値を渡す」という発想はbabu_babueさんと同じだと思います。
無名関数に引数を渡すためにクロージャを使っていたところが違う部分ですね。
No.4
- 回答日時:
一例です。
<ul>
<li>test1</li>
<li>test2</li>
<li>test3</li>
</ul>
<script type='text/javascript'>
(function(){
var li = document.getElementsByTagName('li');
for(var i=0,max=li.length; i<max; i++){
li[i].onclick = (function(j){
return function(){alert(j);}
})(i);
}
})();
解説は以下をご参照ください。
http://www.atmarkit.co.jp/fdotnet/ajaxjs/ajaxjs0 …
参考URLまでありがとうございます。
今読み終わったところです。
クロージャという仕組みを使っているのですね。
クロージャとは「関数を戻り値に持つ関数」で掲示されているコードでは
無名関数がクロージャとして機能している、と理解しました。
#1の方もクロージャを使われていたことから、クロージャを使う方法は広く使われているようだと想像できます。
理解が深まりました。ありがとうございます。
No.3
- 回答日時:
//@cc_on
document./*@if(@_jscript)attachEvent('on'+ @else@*/addEventListener(/*@end@*/
'click', function (evt) {
var c = 0, e = evt./*@if(@_jscript) srcElement @else@*/ target /*@end@*/;
if ('LI' == e.tagName) {
while (e = e.previousSibling) if ('LI' == e.tagName) c++;
alert(c);
}
}, false);
//ぜんかくくうはくは、てきとうになおしてね ばぶ~!
//これだといべんとを、はがしてないよね
No.2
- 回答日時:
(function(){
var li = document.getElementsByTagName('li'), o, c = 0;
while (o = li[c]) o.onclick = (function(i){ return function() {alert(i);};})(c++);
})();
でも、メモリーリーク。
この回答への補足
ひょっとして、#2だけメモリリーク、でしょうか。
- #2でもメモリーリーク (#1,2の両方)
- こういうコートがあるけど、メモリーリーク (#2だけ)
見方によって、受け取り方が変わってしまいますね…。
何度もありがとうございます。
#1,2ともにメモリリークするコードと指摘されているのでしょうか…。
何のために#1からこのように変化したのかが理解できていません。(汗)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
jQueryで電卓を作っているのですが
-
【jQuery】hoverしたn秒後にイ...
-
JQueryタブのアクティブ アン...
-
jquery ドロップダウンメニュー...
-
jqueryのsortableで一部ソート...
-
jquery中のmatch関数が正常に動...
-
【短い】1つだけ展開/表示/非表...
-
FireFoxのjavascriptでonloadで...
-
jqueryにてIEでの不具合 each...
-
クリックで表示、非表示するメ...
-
JQuery UIで、表示したタブの中...
-
DOM の 要素の数え方について
-
多階層ドロップダウンのスマホ...
-
チェックボックスに入っている...
-
MAX関数を使ってからLEFT JOIN...
-
javascriptテキストBOX色を元に...
-
createElementで作成した要素を...
-
背景色を透明化
-
JavaScriptにて『var val2 = "d...
-
【jQuery】2分割レイアウトで、...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
jqueryのsortableで一部ソート...
-
jquery ドロップダウンメニュー...
-
JQueryタブのアクティブ アン...
-
jQueryのeqで最後からn番目以降...
-
チェックボックスに入っている...
-
「jQuery」アコーディオンメニ...
-
クリックした<a>タグのみにClas...
-
javascriptでEnterキーをtabキ...
-
【JQuery】アコーディオンの入...
-
タブ切り替えの初期表示について
-
jQueryでネスト構造の<li>がク...
-
どの<li><a> が押されたか判別...
-
大量のチェックボックス状態取...
-
フルスクリーンについて・・・
-
jQueryのhide,showで中の要素が...
-
【jQuery】遅延実行(タイムラ...
-
アコーディオン自動開閉メニュ...
-
jQueryで表示する吹き出しdivの...
-
JqueryFileTree.js でフォルダ...
-
タブ切り替えの初期表示に関して
おすすめ情報