![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
-----
<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で質問しましょう!
似たような質問が見つかりました
- JavaScript html5に変えるとスライドショーが消えてしまった。 3 2022/03/26 19:53
- HTML・CSS CSS のみのタブ切り替えについて 1 2023/01/11 16:47
- JavaScript javascript作成してます。ラジオボタンで判定するコードを書いてます。 1 2023/07/18 11:03
- PHP style.cssのjQuery条件付きcssが機能しない 4 2022/07/17 18:27
- その他(プログラミング・Web制作) pythonリストの特定の値を表示htmlで表示できない 2 2022/05/14 05:48
- JavaScript javascriptのちょっとした動作不良(原因は突き止めたのですが) 1 2023/06/15 19:58
- HTML・CSS HTML & CSS 縦ボックス内の文字の左右センタリング 3 2023/03/25 04:23
- HTML・CSS テキストを画面の真ん中に配置したいです。 2 2022/11/25 16:11
- HTML・CSS display flex の使い方 1 2022/04/25 19:13
- PHP アコーディオンPHPが上手くいかない 3 2022/07/15 16:29
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
jqueryのsortableで一部ソート...
-
「jQuery」アコーディオンメニ...
-
どの<li><a> が押されたか判別...
-
開閉式ツリー型メニューについて
-
.innerHTMLの不一致?
-
PukiWikiの左メニューでonMouse...
-
jQuery タブメニューへのダイ...
-
jQueryについて質問なのですが...
-
カテゴリページ内 複数タブ
-
別フレームからの背景の変更
-
javascriptでEnterキーをtabキ...
-
滑らかに開閉するメニューを作...
-
jQueryスライドメニューの初歩...
-
jquery ドロップダウンメニュー...
-
MAX関数を使ってからLEFT JOIN...
-
createElementで作成した要素を...
-
iframe内のリンクが飛ばないの...
-
Lightbox2でのキャプションにつ...
-
画像ファイルの合成
-
クリックで背景変更するタグ
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
jqueryのsortableで一部ソート...
-
クリックした<a>タグのみにClas...
-
どの<li><a> が押されたか判別...
-
【javascript で動的に a タグ...
-
文字と数字が混在する要素のsor...
-
javascriptでEnterキーをtabキ...
-
チェックボックスに入っている...
-
複数のラジオボタン項目でのテ...
-
jquery ドロップダウンメニュー...
-
jQueryのeqで最後からn番目以降...
-
JavaScriptで、?マークとコロ...
-
質問に答えていくと、回答によ...
-
Jqueryでリストのスクロール
-
多階層ドロップダウンのスマホ...
-
JQueryタブのアクティブ アン...
-
gridstack.jsについて教えてく...
-
タブ切り替えの初期表示について
-
オンマウスで画像ロールオーバ...
-
「jQuery」アコーディオンメニ...
-
複数の画像をランダム(シャッ...
おすすめ情報