🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

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

jQuery

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

Q&A

解決済

2回答

2657閲覧

jQueryのfadeInで読み込んだ画像を同時に表示させたい。

norino

総合スコア10

JavaScript

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

jQuery

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

2グッド

4クリップ

投稿2019/09/25 06:04

編集2019/09/26 06:07

javascript jQuery teratail初心者です。よろしくお願い致します。

webサイトを開くと、fadeInしながらサイトを表示させるといった単純なものを作っています。

画像をたくさん張り付けているサイトを想定して作っていまして、
全てが揃ってから表示できるかを見るために
容量の重い画像から軽い画像を30枚くらい表示させています。
重い画像は、あるサイトの航空写真で40M ぐらいの画像を
30枚のうち半分くらい使っています。

jquery, javascript を使い自分なりに調べながら作っていたところ、
chrome では問題なく表現できているのですが、

firefox, edge, IE(11)では、fadeInしながらパラパラと表示していき、
自分が思い描いている全ての画像が同時にfadeInするといった具合になりません。

いくら調べても分かりません。
こういうものだと納得しなければならないのか、
それとも別の方法があるのか、
コード自体まちがっているのか・・・。

どうかお力添えのほう、よろしくお願いいたします。


説明不足と気づいたことがあって質問したいので追記します。

ローディングを作ろうとしています。
「コンテンツ部分を隠しておく」→「ローディング表示」→「コンテンツ表示」の
「ローディング」の部分は後で作るとして、
すべてが読み込まれたらfadeIn して表示させる部分を作ってみました。

現在 各画像をload イベントでとって、読み込み完了したらカウント重ね、
揃ったら親要素をfadeIn させ表示するまではできているのではないかと思っています。

そこで気づいたのが、上記の方にも書きましたが、
chrome以外のブラウザだけ重い画像がパラパラと遅れて表示していることに。
ブラウザによって全てが揃った状態で表示してくれません。
全てが揃っているというのは確実に表示した状態でという意味です。

自分のなかでは、
読み込み完了 = 表示も完了。
だと思っていたので今のような表示の仕方が納得できないのです。
表示を揃えることってできないのか?と思い質問しました。
ここまで重い画像を載せることはしませんし、
軽い画像では現象が見られないためいいかとは思うのですが
軽い画像でも本当の意味では揃ってないのですよね・・・。

あとこれを書いている最中に疑問に思ったことがあったため
申し訳ないのですが質問させていただきます。
今回と関係あるのかもしれません。
よそ様のサイトを見ているときに回線のせいもあるかもしれませんが、
画像が徐々に表示されている状態は
読み込んでいる最中なのか、読み込み完了はしている状態なのか???
今回の場合ですと、loadイベントの中に入ったのか入っていないのか???
これが分かると読み込み完了の意味が少し理解できるのかな・・・

どうかよろしくお願いします。


HTML

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <title></title> 8</head> 9<style> 10 .gallery { 11 display: none; 12 } 13 14 .gallery .container { 15 display: flex; 16 justify-content: center; 17 flex-wrap: wrap; 18 max-width: 1000px; 19 margin: 0 auto; 20 background-color: #ebb7b7; 21 } 22 23 .gallery .container .im { 24 display: inline-block; 25 flex: 1 1 300px; 26 max-width: 300px; 27 } 28 </style> 29<body> 30 <div class="gallery"> 31 <div class="container"> 32 <img src="../images/bg00.jpg" alt="" class="im"> 33   <img src="../images/bg01.jpg" alt="" class="im"> 34   <img src="../images/bg02.jpg" alt="" class="im"> 35   <img src="../images/bg03.jpg" alt="" class="im"> 36   <img src="../images/bg04.jpg" alt="" class="im"> 37   <img src="../images/bg05.jpg" alt="" class="im"> 38   <img src="../images/bg06.jpg" alt="" class="im"> 39   <img src="../images/bg07.jpg" alt="" class="im"> 40   <img src="../images/bg08.jpg" alt="" class="im"> 41   <img src="../images/bg09.jpg" alt="" class="im"> 42   <img src="../images/bg10.jpg" alt="" class="im"> 43   <img src="../images/bg11.jpg" alt="" class="im"> 44   <img src="../images/bg12.jpg" alt="" class="im"> 45   <img src="../images/bg13.jpg" alt="" class="im"> 46   <img src="../images/bg14.jpg" alt="" class="im"> 47   <img src="../images/bg15.jpg" alt="" class="im"> 48   <img src="../images/bg16.jpg" alt="" class="im"> 49   <img src="../images/bg17.jpg" alt="" class="im"> 50   <img src="../images/bg18.jpg" alt="" class="im"> 51   <img src="../images/bg19.jpg" alt="" class="im"> 52   <img src="../images/bg20.jpg" alt="" class="im"> 53   <img src="../images/bg21.jpg" alt="" class="im"> 54   <img src="../images/bg22.jpg" alt="" class="im"> 55   <img src="../images/bg23.jpg" alt="" class="im"> 56   <img src="../images/bg24.jpg" alt="" class="im"> 57   <img src="../images/bg25.jpg" alt="" class="im"> 58   <img src="../images/bg26.jpg" alt="" class="im"> 59   <img src="../images/bg27.jpg" alt="" class="im"> 60   <img src="../images/bg28.jpg" alt="" class="im"> 61   <img src="../images/bg29.jpg" alt="" class="im"> 62   <img src="../images/bg30.jpg" alt="" class="im"> 63 </div> 64 </div> 65 66 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> 67 <script> 68 var img = document.querySelectorAll('.im'); 69 var loadCount = 0; 70 var imgLength = img.length; 71 for (var i = 0; i < img.length; i++) { 72 73 var image = new Image(); 74 image.src = img[i].src; 75 img[i].src = ''; 76 77 img[i].addEventListener('load', function (e) { 78 loadCount++; 79 if (loadCount === imgLength) { 80 $('.gallery').fadeIn(1500); 81 } 82 }, false); 83 img[i].src = image.src; 84 } 85 86 </script> 87</body> 88</html>
naomi3, shinji709👍を押しています

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

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

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

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

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

norino

2019/09/25 20:21

m.ts10806さん、見て頂いてありがとうございます。 こんなの自分で作れるようになりたいですね。 私の説明不足で、あと下手ですいません。 私が作ろうとしているのは、サイトを読み込む際にゲージを表示して 100%になったらfadeInさせて表示をする。 ってな感じですが、ゲージの部分を後回しにして、 先に画像をすべて読み込んだらの部分を作っています。 しかし、なぜか chromeでは fadeInしてくるときには ちゃんと画像が表示している、全部そろって fadeInしていますが、 他のブラウザでは重い画像だけ fadeInしている最中にパラパラと 遅れて表示していくんですよね。一緒にじゃないいんですよね。 各画像を 'load'イベントでとって、読み込み完了したらカウントしていき、 全部の読み込み完了したら親要素を fadeInってことは 綺麗に全部そろって出てくるってことだと思っていたので 納得いかないんですよね。 ちなみに軽い画像だけだとできているんですよ。 読み込み完了 = 表示も完了。 ってことではないんですかね? 説明下手かもしれませんが、よろしくお願いいたします。
m.ts10806

2019/09/25 21:45

「ゲージ」というと「ローディング」と表現した方が正しいですね 質問編集して追記いただけますか? 基本は「コンテンツ部分隠しておく」→「ローディング表示」→「コンテンツ表示」 ですが、「ローディング」を「本当にコンテンツすべて読み込み具合を表記」とするとそれなりに難易度が高いです。
norino

2019/09/26 05:59

アドバイスありがとうございます。 追記情報届いてるのかもしれませんが報告しときます。 追記の仕方が間違っているかもしれませんが・・・。 至らなかったらすいません。 あと、m.ts10806さんにお聞きしたいことがあります。 「本当にコンテンツすべて読み込み具合を表記」の難易度が高いと書かれているのですが、 ローディングの%がたまっていく表現のことが難しいといった意味なのでしょうか? それとも今回の質問の遅延をなくして表示の部分が、実は何か私の考えが及ばない領域の 部分があって、なんたらかんたら~って意味なのでしょうか? javascript で何ができるのか、どこまでできるのか、とかがまだまだ分からない者なので どうかよろしくお願いします。
m.ts10806

2019/09/26 06:20

>ローディングの%がたまっていく表現のこと これです。ネットワーク環境や実際に読み込むべきコンテンツ数から計算する必要があります(もっとも、手法としては出てるので探せばみつかるかもしれませんが)
norino

2019/09/26 09:04

返信ありがとうございます。 コンテンツ数と、読み込み時間が長くなるようならば強制的に表示させるといったやり方は ネットにあるのですが、重い画像だとズレるのは仕方がないことなのでしょうか? 追記部分にも書いたのですが、少しずつ画像が表れている部分って 読み込みは終わっていることになるのでしょうかね? しかし、chromeでは表現できているし・・・。
naomi3

2019/09/28 10:45

deferredを使って、すべての画像のロードが完了したときまで待って、fadeInを開始すればどうでしょう。
norino

2019/09/29 04:46

naomi3さん、アドバイスありがとうございます。 deferred ?? 初めて聞いたので、今から調べてやってみます。 お時間かかるかも知れませんが頑張ります。
guest

回答2

0

DOM関係に詳しくないので間違っていたらごめんなさい。

読み込み完了 = 表示も完了。

loadはあくまで画像ファイルが読み込めた状態です。
この後に表示できるようにデコード処理が走ります(load=ダウンロード、decode=圧縮ファイルの展開/解凍のイメージ)。
ファイルサイズが大きい画像はデコード処理も時間がかかります。

IEとEdgeを捨てるなら、decode()がpromiseを返すので、デコードが終わったあとの処理が書けます。デコードが終わるまでローディングを表示させれば意図した動きになりませんか?

  • 全ての画像を一気に制御したいなら[Promise.all()

](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/all)で待てばOKだと思います。

  • Edgeも近々Chromeとほぼ同じになるのでIEを捨てるのは有りだと思います。

参考(OffscreenCanvasとか面白い紹介が有ります)
画像に関する新しい DOM API の紹介

投稿2019/10/05 02:56

編集2019/10/05 06:35
oikashinoa

総合スコア2826

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

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

norino

2019/10/05 19:47

oikashinoaさん、ありがとうございます。 お返事おそくなってすいません。 読み込みと表示は一緒ではない。ものすごくすっきりしました。 そして、decode()・・・。初めて聞く言葉。 まだまだ勉強不足です。deferred, promise もまだ勉強が始まったばかりなので decode の理解にいくまで時間がかかります。 ちゃんと理解したいのでもう少しお待ちください。 下のリンクの記事も必ず読みます。
norino

2019/10/09 06:09

たった今deferredの勉強が終了しました。 遅くてすいません。もう少し時間がかかります。 リンク記事読みました。 まだまだ私には難しいですけど、最初の方のdecode関係の記事が oikashinoさんがおっしゃっていたとおりのことが書いており、 勉強になりました。ありがとうございます。
norino

2019/10/15 16:11

解決に遅くなりました。 今回はnaomi3さんが色々解決策を出してくださったので そちらをベストアンサーにさせて頂きます。 しかし、oikashinoさんのdecode案がとても勉強になりました。 Promise.all バージョンも自分で出来ましたし、 お二人のおかげで色々なことが身についたと思います。 oikashinoさん、本当にありがとうございました。
oikashinoa

2019/10/15 21:50

遅くまでお疲れさまでした。
guest

0

ベストアンサー

いろいろと試してみましたが、ロード完了までフェードイン開始を待てないようで、重い画像の場合は表示処理のために時間がかかっているようです。
そこでロードではなく、フェードインの方をコマ送りにして処理を軽くしてみました。フェードインはopacity属性をなめらかに1.0に近づけていくものです。重い画像の場合は処理がなめらかさについていけずに、遅延を生じてしまうのでしょう。粗くすることで遅延を防ぐことができます。粗く(framesを少なくする)しすぎると、アニメーションがぎこちなくなるので、数値を調整してみてください。

変更部分のみ

CSS

1 .gallery { 2 opacity: 0.0; 3 }

JavaScript

1 var frames = 10; // コマ送りのコマ数 2 var loadingDelay = 2000; // ロード時間 3 var fadingDuration = 2000; // フェードイン時間 4 5 // Promiseオブジェクトを返す即時関数を実行 6 var promise = (function() { 7 var deferred = $.Deferred(); 8 9 setTimeout(function() { 10 // loadingDelayミリ秒後に実行される 11 12 // resolveした直後に最初のfadeInALittleが実行される 13 deferred.resolve(1.0 / frames); // 最初のfadeInALittleに渡される引数を指定 14 }, loadingDelay); 15 16 return deferred.promise(); 17 })(); 18 19 // 不透明度を徐々に0.0→1.0に上げて行き、コマ送りでフェードイン 20 21 for (var i = 0; i < frames; i++) { 22 // 非同期関数fadeInALittleを順に実行予約 23 promise = promise.then(fadeInALittle); 24 } 25 26 function fadeInALittle(opacity) { 27 var deferred = $.Deferred(); 28 29 setTimeout(function() { 30 // fadingDuration / framesミリ秒後に実行される 31 32 console.log(opacity); 33 // 実際に不透明度を設定 34 $('.gallery').css('opacity', opacity); 35 36 // resolveした直後に次のfadeInALittleが実行される 37 deferred.resolve(opacity + 1.0 / frames); // 次のfadeInALittleに渡される引数を指定 38 }, fadingDuration / frames); 39 40 return deferred.promise(); 41 }

oikashinoaさんのdecodeを使った別解です。
スムーズに表示されますね。

Chromeで表示されなくなってしまっていたので、その対応を行いました。

JavaScript

1 var promiseArray = []; 2 3 $('.im').each(function(index, imgElement) { 4 // 各々の画像をロード&デコードする予約を集める 5 promiseArray.push(loadAnImg(imgElement)); 6 }); 7 8 function loadAnImg(imgElement) { 9 // src属性を退避 10 imgElement.originSrc = imgElement.src; 11 // 勝手にロード&デコードが始まらないように、一旦src属性を無効化 12 imgElement.src = ''; 13 // ロード&デコードを監視するためのImageオブジェクト 14 var imgObj = new Image(); 15 16 var deferred = $.Deferred(); 17 18 // ロード&デコードを開始 19 imgObj.src = imgElement.originSrc; 20 21 // デコードが終了したときに実行される関数を予約 22 imgObj.decode() 23 .catch(function() { 24 // デコードが失敗した時も成功と同じに見なすための空の関数 25 }) 26 .finally(function() { 27 // デコードが成功または失敗したとき(Chrome対応)に実行される 28 29 // src属性を復元 30 imgElement.src = imgElement.originSrc; 31 deferred.resolve(); 32 }); 33 34 return deferred.promise(); 35 } 36 37 $.when.apply(null, promiseArray).done(function() { 38 // すべてのPromiseオブジェクトがresolveされたときに実行される 39 40 $('.gallery').fadeIn(1500); 41 });

ちゃんと理解したいとのことなので、コメントをつけました。

投稿2019/10/05 01:56

編集2019/10/05 21:27
naomi3

総合スコア1105

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

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

norino

2019/10/05 19:31

naomi3さん、ありがとうございます。 そしてお返事遅くなって、すいません。 naomi3さんにアドバイスしてもらったdeferredが、 まだ僕には早かったせいか、難しいです。 お恥ずかしい話、callBackの考え方とかがまだまだ苦手な段階なもので、 コードを見ているとたまに混乱しています。 まだdeferredの使い方の段階です。遅くてすいません。 時間がなくて毎日勉強できないので 時間がかかるかもしれませんが、ちゃんと理解したいので もうしばらくお待ちください。
norino

2019/10/05 19:52

どんどん追加されてくー。 ありがとうございます。
norino

2019/10/09 06:05

ただいま自分の中で deferred の理解がある程度得られたと思います。 今からnaomi3さんのコードをやっていきます。 遅くて本当にすいません。
norino

2019/10/10 21:27

naomi3さん、質問よろしいですか? imgObj.src = imgElement.originSrc; をして imgObjがデコード完了したらresolve()してタイミングとっている。 その中で、imgElement.src = imgElement.originSrc;で復元してますよね? これって、1度デコードしたパスは、さっきとは別の場所に入れてもすぐに描画できてしまう。 って解釈であっていますか? 私の中の勝手なイメージですが、imgObjのデコード完了後に imgElement.src = imgElement.originSrc;をするとさっきとは別のデコード(描画?)が始まって imgObjの全てのデコード完了タイミングと、imgElementの全てのデコード完了タイミングがずれて fadeIn中に画像が表示されて揃わない。 ってな感じなこと考えちゃってます。自分のイメージを言葉で表すのが下手でごめんなさい。 ここら辺の関係を教えてもらえると助かります。 どうかよろしくお願い致します。
naomi3

2019/10/11 11:59

> これって、1度デコードしたパスは、さっきとは別の場所に入れてもすぐに描画できてしまう。 はい。その通りです。 > imgElement.src = imgElement.originSrc;をするとさっきとは別のデコード(描画?)が始ま ることはありません。 重い画像を作り、何度もテストしています。 心配ならば次のように書き換えても、動作は全く変わりません。 function loadAnImg(imgElement) { imgElement.originSrc = imgElement.src; imgElement.src = ''; var deferred = $.Deferred(); imgElement.src = imgElement.originSrc imgElement.decode() .catch(function() { }) .finally(function() { deferred.resolve(); }); return deferred.promise(); }
norino

2019/10/13 05:57

naomi3さん、いつもありがとうございます。 すぐ復元できるのは、キャッシュに保存されるからってことであってますよね? それと何度も申し訳ないのですが、また質問よろしいでしょうか? Promiseがなんとなく分かってきましたが、今回の.catchって必要なのでしょうか? .finallyについて調べたところ、成功・失敗にかかわらずって書いてあったので いらないかと思いきや、取ってしまったら Uncaught (in promise) DOMException ってエラーが出ました。これがchrome対応ですよね? これの説明、もしくは書いてあるところ教えてもらえないでしょうか? どうかお願いいたします。
naomi3

2019/10/13 06:30

>すぐ復元できるのは、キャッシュに保存されるからってことであってますよね? そういうことと思います。 >.finallyについて調べたところ、成功・失敗にかかわらずって書いてあったので >いらないかと思いきや、取ってしまったら >Uncaught (in promise) DOMException >ってエラーが出ました。これがchrome対応ですよね? .catch()も.finally()もChrome対応です。 もう消してしまいましたが、FireFoxでは、decode()がすべてresolve()するので、.catch()も.finally()も、$.Deferred()もpromise()も不要です。 ところが、Chromeでは、ものによってreject()するため、新たなDeferredオブジェクトを作り、.finally()によってresolve()、reject()を捕まえ、双方の場合でresolve()しているのです。 >今回の.catchって必要なのでしょうか? .catch()を取っても動作上は問題ありません。しかし、なければエラーメッセージを出すので、あった方がお行儀がよいということです。
naomi3

2019/10/13 09:58

補足: decode()によってPromiseオブジェクト(Deferredオブジェクト)が作られるのですが、Promiseオブジェクトは一度resolve()またはreject()すると再利用できないので、$.Deferred()によって新たなDeferredオブジェクトを作っています。
norino

2019/10/15 16:31

解決に遅くなりました。 naomi3さんのコードをもとに、Promise.allの使ったバージョンも自分でできました。 naomi3さんとoikashinoさんのおかげで、 deferred,decode,promise の3つの理解が深まりました。 $.when.applyで終わっても良かったんですが、 oikashinoさんのPromise.allも試したかったので時間がかかりました。申し訳ないです。 あと、何気にloadAnImgを関数化してimgElementをクロージャ化しているところも 勉強になりました。最初 for文バージョンで作っていてdecodeの中をimg[i]とかしてたら、 うまく画像を復元できていなかったので。 こういうのもクロージャになるんだなと知れて嬉しかったです。 naomi3さん的には何もしてないかもしれませんが、勉強になりました。 本当に長い間ありがとうございました。 それでは失礼します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問