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

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

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

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

jQuery

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

Q&A

解決済

2回答

1065閲覧

配列とfor文で連続する画像のidを一括取得したい

type

総合スコア11

JavaScript

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

jQuery

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

0グッド

0クリップ

投稿2019/07/11 02:23

編集2019/07/11 04:43

配列とfor文で連続する画像のidを一括取得したい

HTML,JavaScript,CSSでサイトをつくっています。
画像を拡大するボタンを押すと画像が拡大される機能をすべての画像に適用したいのですが
配列の最後(ここでいうとpicture6)にしか適用されません。

発生している問題

このコードだとpicture6にしかfunctionの機能が適用されない。
全てのpicture1~6に適用したい。

該当のソースコード

html

1<input type="button" value="画像を拡大" onclick="zoom()">

javascript

1 2var num = [1,2,3,4,5,6]; 3var w = 100; 4var timerId; 5 6 for(var i of num) { 7 8 function zoom() { 9 w = Number(document.getElementById('picture'+i).getAttribute('width')); 10 timerId = setInterval('change();', 100); 11 } 12 13 function change() { 14 w += 10; 15 document.getElementById('picture'+i).setAttribute('width', w); 16 if (w > 500) { 17 clearInterval(timerId); 18 } 19 } 20 }

追記

上のコードを訂正しましたが、今度は画像が永遠に拡大していってしまいます。
if (w > 200)...で止まるようにしたつもりだったのですがどこが悪いのか分かりません。

JavaScript

1var num = [1,2,3,4,5,6]; 2var w = 100; 3var timerId; 4 5 6function zoom() { 7for(var i of num) { 8w = Number(document.getElementById('picture'+i).getAttribute('width')); 9timerId = setInterval('change();', 100); 10} 11} 12 13function change() { 14for(var i of num) { 15w += 10; 16document.getElementById('picture'+i).setAttribute('width', w); 17if (w > 200) { 18clearInterval(timerId); 19} 20} 21}

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

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

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

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

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

m.ts10806

2019/07/11 03:16 編集

>かなり初心者なので許してください 誰にも許しを請う必要はないと思います。 誰もが最初は初心者ですし、見当違いなことをやっていたとしても初心者の自覚がある人であればそれを責める人はいないでしょう。 ただ、できれば質問内容は要件のみにしてもらったほうが良いので、質問を編集して質問に「初心者アイコン」をつけるにとどめておいてください。
type

2019/07/11 02:38

ご指摘ありがとうございます。変更しました。
guest

回答2

0

ベストアンサー

関数は「道具」に近いものです。
道具を用意しておいて適宜使うものとなります。

仕様的には下記

関数は呼び出されて初めて実行されます。
変数も実行されたときに渡されたものが利用されます。

下記のようにして「何が有効となっているか」確認してみると良いです。

js

1 for(var i of num) { 2 3 function zoom() { 4 console.log(i); 5 w = Number(document.getElementById('p'+i).getAttribute('width')); 6 timerId = setInterval('change();', 100); 7 } 8 9 function change() { 10 w += 10; 11 document.getElementById('p'+i).setAttribute('width', w); 12 if (w > 500) { 13 clearInterval(timerId); 14 } 15 } 16 }

ブラウザの開発ツールのConsoleを確認すると「6」と出ていると思います。

変数にはスコープというものがあります。

今回書かれたコードはほぼ100%に近い割合で押される前にfor文の実行が終わります。
終わっている、ということはnumをループしている中でiを渡していますが、残っているのは「最後の値だけ」となります。

検証コード

js

1for(var i=0;i<100;i++){ 2 3} 4console.log(i); 5//出リュク結果:100

故に、「6」が採用され、現在起きているように「最後の画像だけに処理が実行される」という状況が起きるわけです。

どうしたらいいか?

ここまで来たらもしかしたら予想がつくかもしれませんが
「ボタンを押したときにnumをループして処理をする」です。

ヒントにやってみてください。

ワンアップ

現在の作りだと「画像が増えると配列にも値を追加する」という必要が出てきます。
もう少し効率的に作ることができます。
「JavaScriptで配列で情報(今回はimgタグ)を取得する」です。

HTMLの構成がどうなっているか分かりませんが、対象ではない画像が画面内に他にもあるようでしたら
画像にclassをつけてgetElementsByClassName()でも良いですし、画面内に対象の画像がないのでしたらimgタグ直指定でgetElementsByTagName()でも良いでしょう。
querySelectorAll()などもあります

この場合、IDはなくても良いですね。

サンプルコード

提示のものより画像は少ないですし名前も変えてありますが(あとインターバルの秒数も)
こんな感じでもできます。

js

1var num = [1, 2, 3, 4]; 2var timerId = null; 3 4function zoom() { 5 timerId = setInterval('change()',1000); 6} 7 8function change(i) { 9 for(var i of num) { 10 w = Number(document.getElementById('p' + i).width); 11 if(w >= 200){ 12 clearInterval(timerId); 13 break; 14 } 15 document.getElementById('p' + i).setAttribute('width', w+10); 16 } 17}

投稿2019/07/11 02:43

編集2019/07/11 05:21
m.ts10806

総合スコア80765

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

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

type

2019/07/11 04:28

処理の順番やタイミングが重要だという事に気づけました!ありがとうございます。 以下のコードで全ての画像が拡大されることが出来るようになったのは良いのですが 今度は画像が永遠に拡大していってしまいます。 if (w > 200)...で止まるようにしたつもりだったのですがどこが悪いのでしょうか? ```JavaScript var num = [1,2,3,4,5,6]; var w = 100; var timerId; function zoom() { for(var i of num) { w = Number(document.getElementById('picture'+i).getAttribute('width')); timerId = setInterval('change();', 100); } } function change() { for(var i of num) { w += 10; document.getElementById('picture'+i).setAttribute('width', w); if (w > 200) { clearInterval(timerId); } } } ```
m.ts10806

2019/07/11 04:35

コードを質問本文に追記していただけますか? コメント欄ではマークダウン使えませんので
type

2019/07/11 04:44

追記しました。よろしくお願いします。
m.ts10806

2019/07/11 04:44

下記のようにしてみると分かりますが、 function change() { console.log(w); この時点では「0」となってます。 changeに引数で渡すか、 timerId もwも画像毎にもったほうが良いかもしれません。 それか、change()内でもwidthを取得するか・・
type

2019/07/11 04:44

アドバイスありがとうございます。 試行錯誤してみます。
m.ts10806

2019/07/11 04:46 編集

change内でforは不要かもしれませんね。 change()にiを渡して個々に処理させるのが良さそうです。 それなりに組みなおす必要がありそうです。 私も軽く書いてみます。
m.ts10806

2019/07/11 05:21

色々やってみた結果のサンプルコードを追記しました。 ちょっと最初に想定していたものと違うコードになってしまいましたが、ひとまず。
type

2019/07/11 05:39

ありがとうございます!正常に動きました!
m.ts10806

2019/07/11 05:41

私のコードは動作確認済みなので動くはおおよそ当然と言えば当然なのですが、 ご自身で試行錯誤した結果もご提示いただけますか? ここで「もらったコードが動いたから終わり」としてしまうとそこで本当に終わりです。 できれば自身でもやってみて「答え合わせ」感覚で私のコードを使ってほしいのです。 実現する方法は1つではありません。
guest

0

連続する画像のid

が微妙ですね
1,2,3 -ひとつ飛んで- 5,6
だったときにじゃあ、適用するのは1,2,3の方なのか、5,6の方なのかという課題が残ります

通常なら「idがpictureから始まるimg」のような抽出の仕方になります。
ただpicturexのような数字以外がOKなのか?
picture1がpicture01だったらどうなのか?
などフィルタ処理には定義が必要になります

sample

javascript

1<script> 2window.addEventListener('DOMContentLoaded', function(e){ 3 console.log(document.querySelectorAll('img[id^=picture]').length); //pictureから始まるimgは6個 4}); 5</script> 6 7<img alt="1" id="picture1"> 8<img alt="2" id="picture2"> 9<img alt="3" id="picture3"> 10<img alt="4" id="picture4"> 11<img alt="5" id="picture5"> 12<img alt="6" id="picturex"> <!--pictureから始まるので対象--> 13<img alt="7" id="dummy7"> <!--pictureから始まらないので対象外--> 14<span id="picture1">8</span> <!--spanなので対象外--> 15

これを絞り込んで

javascript

1window.addEventListener('DOMContentLoaded', function(e){ 2 console.log([].filter.call(document.querySelectorAll('img'),x=>x.id.match(/^picture\d+$/)).length); 3});

のようにすれば、pictureからはじまる数値がつづくimgのような指定もできる

投稿2019/07/11 03:03

編集2019/07/11 03:44
yambejp

総合スコア114572

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

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

type

2019/07/11 04:37

なるほど確かにその方が確実ですね。ありがとうございます。 今回は課題としての作成でfor文と配列を使いたかったので次の機会に使ってみようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問