質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

2回答

2183閲覧

jqueryで繰り返す処理の時に配列をリセットしたい

unison_t

総合スコア13

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2018/12/10 10:53

複数table内にあるdl配下のdtの高さを取得し、そのtable内での最大値で揃えたい

下記のようにtable内にdlを3つ配置し、そのdtの高さを最大値で揃えようとしています。
tableが複数あるためeach functionでそれぞれのtable内のdtの高さを配列に入れ最大値を取得、.cssでdtの高さを設定しようとしたのですが
配列がtableごとでリセットされず意図しないheightになってしまいます。
初心者のため見苦しいコードですが、ご助言いただけますと幸いです。

発生している問題・エラーメッセージ

配列がリセットされず高さが足されていってしまいます。

該当のソースコード

html

1<div class="wrapper"> 2<table class="parent"> 3 <tbody> 4 <tr> 5 <td> 6 <dl> 7 <dt class="child">テキスト</dt> 8 <dd></dd> 9 <dd></dd> 10 <dd></dd> 11 </dl> 12 <dl> 13 <dt class="child">テキスト</dt> 14 <dd></dd> 15 <dd></dd> 16 <dd></dd> 17 </dl> 18 <dl> 19 <dt class="child">テキスト</dt> 20 <dd></dd> 21 <dd></dd> 22 <dd></dd> 23 </dl> 24 </td> 25 </tr> 26 </tbody> 27</table> 28<table class="parent"> 29 <tbody> 30 <tr> 31 <td> 32 <dl> 33 <dt class="child">テキスト</dt> 34 <dd></dd> 35 <dd></dd> 36 <dd></dd> 37 </dl> 38 <dl> 39 <dt class="child">テキスト</dt> 40 <dd></dd> 41 <dd></dd> 42 <dd></dd> 43 </dl> 44 <dl> 45 <dt class="child">テキスト</dt> 46 <dd></dd> 47 <dd></dd> 48 <dd></dd> 49 </dl> 50 </td> 51 </tr> 52 </tbody> 53</table> 54<table class="parent"> 55 <tbody> 56 <tr> 57 <td> 58 <dl> 59 <dt class="child">テキスト</dt> 60 <dd></dd> 61 <dd></dd> 62 <dd></dd> 63 </dl> 64 <dl> 65 <dt class="child">テキスト</dt> 66 <dd></dd> 67 <dd></dd> 68 <dd></dd> 69 </dl> 70 <dl> 71 <dt class="child">テキスト</dt> 72 <dd></dd> 73 <dd></dd> 74 <dd></dd> 75 </dl> 76 </td> 77 </tr> 78 </tbody> 79</table> 80</div> 81

js

1$(function () { 2 $('.parent').each(function () { 3 var array = []; 4 for (var i = 0; i < $('.child', this).length; i++) { 5 var dt_height = $('.child', this).outerHeight(); 6 array.push(dt_height); 7 var maxH = Math.max.apply(null, array); 8 $('.child').css({ 9 "height": maxH + "px" 10 }); 11 } 12 }); 13});

試したこと

array.length = 0;
var array = [];
を思い当たる箇所に挿入してみましたが想定している動作にはなりませんでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

配列の初期化はvar array = []array.length = 0;で正しく行えます。
代入を伴う方法は参照が剥がれてしまうので、引数等で持ってきた元の配列に副作用を与えたいニッチな要件ではarray.length = 0;を使う事がありますが、基本的にあんまりよろしい方法ではなく使わないで済むにこしたことはありません。

今回は配列の初期化が原因ではないようです。
こういった勘違いで明後日の方向を向いてしまい大ハマリしてしまう事は私もよくやるので、
今回の質問はかなりベストなタイミングだったと思います。


ではコードを読んでいきます。

配列がtableごとでリセットされず意図しないheightになってしまいます。

本当?これ確認した?
こうすればarrayの中身がデベロッパーツール(F12キー)のconsoleで表示されるから確認してみて。

JavaScript

1$(function () { 2 $('.parent').each(function () { 3 var array = []; 4 for (var i = 0; i < $('.child', this).length; i++) { 5 var dt_height = $('.child', this).outerHeight(); 6 array.push(dt_height); 7 var maxH = Math.max.apply(null, array); 8 $('.child').css({ 9 "height": maxH + "px" 10 }); 11 12 // arrayの中身を確かめる為にconsole上に表示する 13 console.log(array); 14 } 15 }); 16});

私の机上デバッグだと正しく初期化されて、要素数1、2、3を繰り返すだけに見えるからね。

$('.parent').each(function () {

ふむふむ…

for (var i = 0; i < $('.child', this).length; i++) {

は?なんで急に書き方が変わるの?
each使えばthisが上書きされるから困ったんだと思うけど、
childの中身は普通に考えればchild内で全て解決出来るはずだから、改めて$(this)すれば大抵は事足りるはずだよ。

ループというのは小さい範囲で描いたほうがなにかと作りやすく不具合も出にくい。
外に出せるものは外に出そう!

$('.child').css({

いや、今まで第二引数にthis入れて$('.child', this)にしてたよね?
なんで急にthis削ったの?
今回の不具合はここが一番怪しい、修正すれば動くと思うよ。

var dt_height = $('.child', this).outerHeight();

【追記】合計値が足される問題が片付いても動かないバグみっけた
for (i = 0; i < length; i++)の形式でループさせてるけど、
その変数iはどこにも使われていない。

複数要素該当する場合、outerHeightは最初の要素の縦幅を返すそうだよ。
リファレンスのouterHeightの第一行目にバッチリとfor the first elementと記載されている。

jQueryだと$('.child', this).eq(i)みたいな感じでi番目のchildを取り出す事を明示しないとダメ。
リファレンスのeqに英語だけど使い方が載ってるよ。


という訳でこれらを修正すれば動くようになるでしょう。
しかし、全体的にコードの書き方が怪しいのでリファクタリングしましょう。

他に挙げるとすれば、
Math.maxを通った結果は配列の最大値にきまっているので変数名にするまでもありません。
また、jQueryのeachメソッドは戻り値を捨てるので配列を予め宣言する必要がありますが、
jQueryのmapを使えば宣言と配列生成を同時に行えそうですね。

このへんを反映するとこのようなコードになります。

JavaScript

1$(function () { 2 $('.parent').each(function () { 3 var $child = $('.child', this); // 二度使うので変数を宣言してキャッシュ取る 4 var heights = $child.map(function () { 5 return $(this).outerHeight(); 6 }).get(); 7 $child.css({ 8 height: Math.max.apply(null, heights) + "px" 9 }); 10 }); 11});

投稿2018/12/11 01:18

編集2018/12/11 04:15
miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

unison_t

2018/12/11 02:05

ご回答及び丁寧な解説ありがとうございます!! ご提示いただいたコードで無事に目的を果たせました。 ループや配列について自分がほぼ無知に近いと再認識しました。 こんなにシンプルに綺麗に書けるようになりたいです。。 とてもわかりやすかったのでじっくり読ませていただいて勉強させていただきます!
unison_t

2018/12/11 02:11

追加でさらに詳しく解説していただき感謝です! ループ、配列でつまづいているのでとても助かります。
unison_t

2018/12/11 05:39

追記ありがとうございます! これまさに悩んでいた箇所の一つです。 しっかり理解せず雰囲気でコードを書いてるのが丸わかりで恥ずかしい限りです。。 不明だったところが全てクリアになり、感動しています!!
guest

0

高さを設定する処理の部分で「すべてのchildクラスを持った要素」に適用しているからだと思います。

$('.child').css({ "height": maxH + "px" });

他の部分ではちゃんと、「(ループで)現在のテーブル配下でchildクラスを持った要素」という指定になっています。$('.child', this)の部分です。

投稿2018/12/10 14:17

NozomuIkuta

総合スコア1260

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

unison_t

2018/12/11 02:01

コメント遅れました、ありがとうございます! 他の方にもご指摘いただきましたように$('.child', this)の部分でおかしくなっていたようです。
NozomuIkuta

2018/12/11 10:11

解決したようでよかったです
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問