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

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

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

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

Q&A

解決済

2回答

2090閲覧

【js】createElementでonerrorの時に表示されない画像を繰り返し作る

niutsuhime

総合スコア10

JavaScript

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

0グッド

0クリップ

投稿2017/04/30 13:32

###前提・実現したいこと

javascriptで、ブラウザ上で動くアルバムのようなプログラム?を作っています。
その際、ランダムに画像を表示することができればと思い、javascriptでなんとか画像の有無を調べ、存在が確認された画像のみをシャッフルして表示させるシステムを作りたいと思いました。

javascriptで画像の有無を直接調べることが困難なのは検索で知ったのですが、もしかしたら画像を一瞬だけ表示させ、その横幅を調べ、0(あるいは特定の数値)以外であれば……という風にできないかと考えました。

そのために、createElementで一瞬だけ画像を表示させた際、存在しなかった画像を表示させない・もしくは代替画像に置き換える、ということができないかと考えています。

###該当のソースコード

私が考えた「画像を表示させ、存在しない画像に関しては表示しない」コードが以下のものになります。

javascript

1function hidden(){ 2 for (var pagei = 1; pagei < maxPage+1; pagei++){ 3 for (var noi = 1; noi < maxNo+1; noi++){ 4 //アルバムの全ページの全画像について繰り返しを命令 5 var img = document.createElement("img"); 6 img.src = "page/file" + pagei + "/" + noi + ".jpg"; 7 img.id = "img" + ((pagei-1) * maxNo + noi); 8 img.addEventListener("error", this.remove , false); 9 img.className = "hidden"; 10 var objBody = document.getElementsByTagName("body").item(0); 11 objBody.appendChild(img); 12 } 13 } 14}

これだと、確かにthis.removeは動いてくれたのですが、以降createElement自体が消去されてしまい、たとえば1枚目と3枚目のみ画像が存在した時、2枚目でonerrorが働いて3枚目以降が表示されなくなってしまうという状況になってしまいました。

また、代替表示として以下のものも考えたのですが(addEventListenerの箇所以外変わっていません)、こちらは書き方が悪いのかうまくEventが働いてくれませんでした。
ちなみに途中に出てくるnoimage.jpgは1px*1pxの真っ白なjpg画像です。

javascript

1function hidden(){ 2 for (var pagei = 1; pagei < maxPage+1; pagei++){ 3 for (var noi = 1; noi < maxNo+1; noi++){ 4 var img = document.createElement("img"); 5 img.src = "page/file" + pagei + "/" + noi + ".jpg"; 6 img.id = "img" + ((pagei-1) * maxNo + noi); 7 img.addEventListener("error", this.src="storage/sozai/noimage.jpg" , false); 8 img.className = "hidden"; 9 var objBody = document.getElementsByTagName("body").item(0); 10 objBody.appendChild(img); 11 } 12 } 13}

そもそもjavascript向きのプログラムでないことは重々承知なのですが、後学のためにも、どうすればこのような繰り返しの際にerrorを追加できるのかどうか知りたいです。
なにとぞよろしくお願いします。

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

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

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

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

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

guest

回答2

0

ごめんなさい、私の理解が至っていないかもしれないのですが
サーバー側で画像の一覧をjsonで返すような仕組みをつくり
ajaxで受け取って処理するのが妥当では?

投稿2017/05/01 01:02

yambejp

総合スコア114779

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

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

niutsuhime

2017/05/06 12:59

すみません、実は私の表記し忘れなのですがサーバーを介さずローカルで動くプログラムを作っていたんです。 そのような処理方法もあるんですね。まだ知識が及ばずyambejpさんのおっしゃっていることをきちんと理解できているのか自信がないので、しっかり調べてみます。ありがとうございました。
guest

0

ベストアンサー

試していませんが、こんな感じでどうでしょう。JavaScript はブロックスコープを持たないので(letやcatch節を除く)変数が上書きされていくのが問題なのかと予想しました。

JavaScript

1function hidden(){ 2 for (var pagei = 1; pagei < maxPage+1; pagei++){ 3 for (var noi = 1; noi < maxNo+1; noi++){ 4 //アルバムの全ページの全画像について繰り返しを命令 5 ( function( pagei, noi, maxNo ) { // 即時関数 6 var img = document.createElement("img"); 7 img.src = "page/file" + pagei + "/" + noi + ".jpg"; 8 img.id = "img" + ((pagei-1) * maxNo + noi); 9 img.addEventListener("error", img.remove , false); 10 img.className = "hidden"; 11 document.body.appendChild(img); 12 } )( pagei, noi, maxNo ); 13 } 14 } 15}

【Document.body - body要素を取得する】
https://syncer.jp/javascript-reference/document/body

【JavaScript中級者への道【3. 関数スコープ】 - Qiita】
http://qiita.com/matsuby/items/1010ae38ee6258fd8020

投稿2017/04/30 15:40

kei344

総合スコア69400

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

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

niutsuhime

2017/05/06 13:01

参考になるURLまで貼っていただいて恐縮です。 思っていた通りに動きました! 本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問