teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

4

jQueryでn番目の要素にアクセスする方法を見つけた

2018/12/11 04:15

投稿

miyabi-sun
miyabi-sun

スコア21461

answer CHANGED
@@ -54,6 +54,18 @@
54
54
  なんで急にthis削ったの?
55
55
  今回の不具合はここが一番怪しい、修正すれば動くと思うよ。
56
56
 
57
+ > `var dt_height = $('.child', this).outerHeight();`
58
+
59
+ 【追記】合計値が足される問題が片付いても動かないバグみっけた
60
+ `for (i = 0; i < length; i++)`の形式でループさせてるけど、
61
+ その変数`i`はどこにも使われていない。
62
+
63
+ 複数要素該当する場合、outerHeightは最初の要素の縦幅を返すそうだよ。
64
+ [リファレンスのouterHeight](http://api.jquery.com/outerheight/)の第一行目にバッチリと`for the first element`と記載されている。
65
+
66
+ jQueryだと`$('.child', this).eq(i)`みたいな感じでi番目のchildを取り出す事を明示しないとダメ。
67
+ [リファレンスのeq](https://api.jquery.com/eq/#eq-index)に英語だけど使い方が載ってるよ。
68
+
57
69
  ---
58
70
 
59
71
  という訳でこれらを修正すれば動くようになるでしょう。

3

確認方法も追記

2018/12/11 04:14

投稿

miyabi-sun
miyabi-sun

スコア21461

answer CHANGED
@@ -9,6 +9,32 @@
9
9
 
10
10
  ではコードを読んでいきます。
11
11
 
12
+ > 配列がtableごとでリセットされず意図しないheightになってしまいます。
13
+
14
+ 本当?これ確認した?
15
+ こうすればarrayの中身がデベロッパーツール(F12キー)のconsoleで表示されるから確認してみて。
16
+
17
+ ```JavaScript
18
+ $(function () {
19
+ $('.parent').each(function () {
20
+ var array = [];
21
+ for (var i = 0; i < $('.child', this).length; i++) {
22
+ var dt_height = $('.child', this).outerHeight();
23
+ array.push(dt_height);
24
+ var maxH = Math.max.apply(null, array);
25
+ $('.child').css({
26
+ "height": maxH + "px"
27
+ });
28
+
29
+ // arrayの中身を確かめる為にconsole上に表示する
30
+ console.log(array);
31
+ }
32
+ });
33
+ });
34
+ ```
35
+
36
+ 私の机上デバッグだと正しく初期化されて、要素数1、2、3を繰り返すだけに見えるからね。
37
+
12
38
  > `$('.parent').each(function () {`
13
39
 
14
40
  ふむふむ…

2

校正

2018/12/11 01:43

投稿

miyabi-sun
miyabi-sun

スコア21461

answer CHANGED
@@ -1,5 +1,5 @@
1
1
  配列の初期化は`var array = []`や`array.length = 0;`で正しく行えます。
2
- 代入を伴う方法は参照が剥がれてしまうので、引数等で持ってきた元の配列に副作用を与えたいニッチな要件では`array.length = 0;`を使う事がありますが、ネタとして知っておくと良いかも知れませんが、基本的にあんまりよろしい方法ではなく使わないで済むなら使わないほうが良いでょう
2
+ 代入を伴う方法は参照が剥がれてしまうので、引数等で持ってきた元の配列に副作用を与えたいニッチな要件では`array.length = 0;`を使う事がありますが、基本的にあんまりよろしい方法ではなく使わないで済むにこたことはありません
3
3
 
4
4
  今回は配列の初期化が原因ではないようです。
5
5
  こういった勘違いで明後日の方向を向いてしまい大ハマリしてしまう事は私もよくやるので、
@@ -7,6 +7,8 @@
7
7
 
8
8
  ---
9
9
 
10
+ ではコードを読んでいきます。
11
+
10
12
  > `$('.parent').each(function () {`
11
13
 
12
14
  ふむふむ…
@@ -14,23 +16,26 @@
14
16
  > ` for (var i = 0; i < $('.child', this).length; i++) {`
15
17
 
16
18
  は?なんで急に書き方が変わるの?
19
+ each使えばthisが上書きされるから困ったんだと思うけど、
20
+ childの中身は普通に考えればchild内で全て解決出来るはずだから、改めて`$(this)`すれば大抵は事足りるはずだよ。
17
21
 
22
+ ループというのは小さい範囲で描いたほうがなにかと作りやすく不具合も出にくい。
23
+ 外に出せるものは外に出そう!
24
+
18
25
  > `$('.child').css({`
19
26
 
20
27
  いや、今まで第二引数にthis入れて`$('.child', this)`にしてたよね?
21
28
  なんで急にthis削ったの?
29
+ 今回の不具合はここが一番怪しい、修正すれば動くと思うよ。
22
30
 
23
31
  ---
24
32
 
25
33
  という訳でこれらを修正すれば動くようになるでしょう。
26
34
  しかし、全体的にコードの書き方が怪しいのでリファクタリングしましょう。
27
35
 
28
- 例えばループ内でやるべきこととループ後にやるべき事の区別がついてないことが挙げられます。
29
- 配列から最大サイズを出す箇所`var maxH = Math.max.apply(null, array);`や、
30
- その後の高さを設定す箇所はループ内で毎回やるこではありませんよね。
36
+ 他に挙げるとすれば、
31
-
32
- また、Math.maxを通った結果は配列の最大値にきまっているので変数名にするまでもありません。
37
+ Math.maxを通った結果は配列の最大値にきまっているので変数名にするまでもありません。
33
- 最後に、jQueryのeachメソッドは戻り値を捨てるので配列を予め宣言する必要がありますが、
38
+ また、jQueryのeachメソッドは戻り値を捨てるので配列を予め宣言する必要がありますが、
34
39
  jQueryの[map](http://js.studio-kingdom.com/jquery/traversing/map)を使えば宣言と配列生成を同時に行えそうですね。
35
40
 
36
41
  このへんを反映するとこのようなコードになります。

1

総評を追加

2018/12/11 01:38

投稿

miyabi-sun
miyabi-sun

スコア21461

answer CHANGED
@@ -1,3 +1,12 @@
1
+ 配列の初期化は`var array = []`や`array.length = 0;`で正しく行えます。
2
+ 代入を伴う方法は参照が剥がれてしまうので、引数等で持ってきた元の配列に副作用を与えたいニッチな要件では`array.length = 0;`を使う事がありますが、ネタとして知っておくと良いかも知れませんが、基本的にあんまりよろしい方法ではなく使わないで済むなら使わないほうが良いでしょう。
3
+
4
+ 今回は配列の初期化が原因ではないようです。
5
+ こういった勘違いで明後日の方向を向いてしまい大ハマリしてしまう事は私もよくやるので、
6
+ 今回の質問はかなりベストなタイミングだったと思います。
7
+
8
+ ---
9
+
1
10
  > `$('.parent').each(function () {`
2
11
 
3
12
  ふむふむ…