LoginSignup
KLB686
@KLB686

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

下記添付gif(以下「画像①」とする)の動きを再現したい

!### 解決したいこと
下記添付gif(以下「画像①」とする)の動きを再現したい

自分で試したこと

「javascript 画像 切り替え」
「jquery 画像切り替え」
「javascript 左から右に切り替え」

等でネット検索。
フェードイン、時間経過によって画像が切り替わる実装については確認できた。
一方で、白い半透明な画像→本体の画像に上書きされていくようなサンプルを見つけることができなかった。

整理できたこと

・当アカウントの前回質問の応用で解決できそう
 https://qiita.com/KLB686/questions/37f5ca67d54b15d4c9e4
・しかし、「白い半透明な画像→通常の画像」「順番にフェードインする」「要素ごとに左から右/右から左にフェードインの方向が変わる」ことについて具体的な実装方法が分からない

まとめ

調べる力、知識不足からくる質問となり、申し訳ございません。
ヒントや方針のみのアドバイスでもいただければ大変助かります。

当方、HTML.CSS.JS初学者です。
質問内容、分かりづらい箇所あれば厳しくご指摘いただければと存じます。

何卒よろしくお願い申し上げます。

0602 11:15 追記

ご回答いただいた方々、ありがございました!
いただいたアドバイスにて理想に近い挙動をほぼ実現することはできました!
一方で、一点だけ解決しない点がありましたので追記させていただきます。

解決したいこと

スクロール時、3つある[container]クラスそれぞれに対し、フェードインされてしまう

動き

動き.gif

コード

HTML

             <div class="p-service__mainWrap">
              <ul class="p-service__mainBox" id="js-serviceMainBox">
                <li>
                  <!---->
                  <div class="container">
                    <div class="obj"></div>
                    <img
                      class="p-service__mainPhoto"
                      src="assets/images/common/main/Service/image-2.png"
                      alt="見出(300*200)"
                    />
                  </div>
                  <!---->
                  <div class="p-service__mainHeading">
                    <div class="p-service__mainBottom">
                      <p class="p-service__mainTtl">○○○○サービス</p>
                      <p class="p-service__mainTxt">
                        サービステキストサービステキストサービステキストサービステキストサービステキストサービステキスト
                        サービステキストサービステキストサービステキストサービステキストサービステキスト
                      </p>
                    </div>
                  </div>
                </li>
                <li>
                  <div class="container">
                    <div class="obj"></div>
                    <img
                      class="p-service__mainPhoto"
                      src="assets/images/common/main/Service/image-2.png"
                      alt="見出(300*200)"
                    />
                  </div>
                  <div class="p-service__mainHeading">
                    <div class="p-service__mainBottom">
                      <p class="p-service__mainTtl">○○○○サービス</p>
                      <p class="p-service__mainTxt">
                        サービステキストサービステキストサービステキストサービステキストサービステキストサービステキスト
                        サービステキストサービステキストサービステキストサービステキストサービステキスト
                      </p>
                    </div>
                  </div>
                </li>
                <li>
                  <div class="container">
                    <div class="obj"></div>
                    <img
                      class="p-service__mainPhoto"
                      src="assets/images/common/main/Service/image-2.png"
                      alt="見出(300*200)"
                    />
                  </div>
                  <div class="p-service__mainHeading">
                    <div class="p-service__mainBottom">
                      <p class="p-service__mainTtl">○○○○サービス</p>
                      <p class="p-service__mainTxt">
                        サービステキストサービステキストサービステキストサービステキストサービステキストサービステキスト
                        サービステキストサービステキストサービステキストサービステキストサービステキストサービステキスト
                      </p>
                    </div>
                  </div>
                </li>
              </ul>
            </div>

CSS

.p-service__mainBox li:nth-child(2) .p-service__mainHeading {
top: 26%;
left: 5%;
}
.p-service__mainHeading {
top: 26%;
right: 5%;
padding: 40px 90px 0 60px;
width: 48%;
height: 85%;
}
.p-service__mainTtl {
font-size: 24px;
}
.p-service__mainTxt {
margin-top: 20px;
font-size: 1vw;
}

//

.p-service__mainBox li {
position: relative;
display: flex;
}
.p-service__mainBox li:nth-child(N + 2) {
margin-top: 120px;
}
.p-service__mainBox li:nth-of-type(2n) {
flex-direction: row-reverse;
}
.p-service__mainPhoto {
width: 50%;
}
.p-service__mainHeading {
position: absolute;
z-index: -1;
background-color: #f0f0f0;
}

//

/* フェードインに関係のあるところ */

.container {
width: 100%;
}

.p-service__mainBox li:nth-of-type(2n) > .container {
display: flex;
flex-direction: row-reverse;
}

.obj {
position: absolute;
background-color: #999999;
width: 50%;
height: 100%;
opacity: 0;
}

.p-service__mainbox li:first-child > .p-service__mainphoto {
position: absolute;
width: 50%;
}

.fadeinRight {
animation-name: fadeinRight;
animation-duration: 1s;
animation-fill-mode: forwards;
opacity: 0;
}

.fadeinRightImg {
animation-name: fadeinRight;
animation-duration: 0.5s;
animation-fill-mode: forwards;
animation-delay: 1s;
opacity: 0;
}
@keyframes fadeinRight {
from {
opacity: 0;
transform: translateX(-300px);
}

to {
opacity: 1;
transform: translateY(0);
}
}

.fadeinLeft {
animation-name: fadeinLeft;
animation-duration: 0.5s;
animation-fill-mode: forwards;
opacity: 0;
}

.fadeinLeftImg {
animation-name: fadeinLeft;
animation-duration: 0.5s;
animation-fill-mode: forwards;
animation-delay: 0.5s;
opacity: 0;
}

@keyframes fadeinLeft {
from {
opacity: 0;
transform: translateX(300px);
}

to {
opacity: 1;
transform: translateY(0);
}
}


JS  ライブラリ;JQUERY プラグイン;inview を追加している

  window.addEventListener("load", function () {
    function fadeAnime() {
      $(".container").each(function () {
        $(".container").on("inview", function (event, fadeInS) {
          if (fadeInS) {
            var indexA = $(".container").index(this);
            var q = 300;

            var $serviceMainHeading = $serviceMainBox.find(
                ".p-service__mainHeading"
              ),
              $serviceMainPhoto = $serviceMainBox.find(
                ".p-service__mainPhoto"
              ),
              $serviceMainTtl = $serviceMainBox.find(".p-service__mainTtl"),
              $serviceMainTxt = $serviceMainBox.find(".p-service__mainTxt");

            $serviceMainHeading.css("opacity", 0);
            $serviceMainPhoto.css("opacity", 0);
            $serviceMainTtl.css("opacity", 0);
            $serviceMainTxt.css("opacity", 0);

            //こここ
            if (indexA % 2 == 0) {
              //セット
              $serviceMainHeading.addClass("fadeinLeft");
              setTimeout(function () {
                $(".container").children(".obj").addClass("fadeinRight");
                $(".container")
                  .children(".p-service__mainPhoto")
                  .addClass("fadeinRightImg");
                setTimeout(function () {
                  $serviceMainTxt.addClass("fadeinLeft");
                  $serviceMainTtl.addClass("fadeinLeft");
                }, q);
              }, q);
              console.log(indexA);
            } else {
              $serviceMainHeading.addClass("fadeinRight");
              setTimeout(function () {
                $(".container").children(".obj").addClass("fadeinLeft");
                $(".container")
                  .children(".p-service__mainPhoto")
                  .addClass("fadeinLeftImg");
                setTimeout(function () {
                  $serviceMainTxt.addClass("fadeinRight");
                  $serviceMainTtl.addClass("fadeinRight");
                  console.log(indexA);
                }, q);
              }, q);
            }
          }
          //こここ
        });
      });
    }
    fadeAnime();

実装のイメージ

・fadeAnime > [.container]それぞれが画面内に入ったら[if (indexA % 2 == 0)]で分岐する
・分岐ごとに[fadeinRight・fadeinLeft]等をセレクタに追加する

問題点の整理

・スクロールをすると要素[.container]の子要素に[fadeinRight][fadeinLeft]の両方が追加されてしまう
・条件分岐→上から何番目の[.container]か判定→該当CSS追加 できるように作成したつもりだが実現できず
・プラグイン;inview の使い方を誤っているか、条件分岐のどちらかが違う可能性が高いと考える
が不備を特定できず

まとめ

折角アドバイスをいただいたのに、再度の質問になり申し訳ございません。
どのあたりに不備があるのか、改善点についてのヒント等をご指摘いただければ幸いでございます。

よろしくお願い申し上げます。

挙動を再現成功 0602 1606

まず、ご質問について回答いただきました方々ありがとうございます。
何度も編集して読みづらくなり申し訳ございません。

無事挙動を再現できました。
ありがとうございました。

以下、最後の疑問点として追記させていただきます。

関数内に入る前と後の$(this)について

console.logにて検証.jpg

結果だけで考えれば、[$(this)を関数に入る前に変数に格納(退避)すればよかった]ですが、
感覚的に変数に格納するしないで画像のようにオブジェクトに変化が起きるのかがいまいちわかりませんでした。

もしよろしければ、この疑問に対する、もしくは投稿者の知識不足についてのアドバイスをいただれば幸いでございます。

0

5Answer

Comments

  1. @KLB686

    Questioner
    @isshy_exception 様

    回答ありがとうございます!

    添付のURL、確認させていただきました!
    実装のイメージにとても近いものでした。ありがとうございます。

    自分の力では見つけることができませんでした。
    ありがとうございます!参考にさせていただきます!
  2. @KLB686

    Questioner
    恐れ入ります。
    質問内容、更新をさせていただきました。

    もしお時間あれば、ご一読、何かしらのアドバイスをいただければと存じます。

Comments

  1. @KLB686

    Questioner
    @_y_s 様

    ご回答ありがとうございます!!

    前回もご回答いただいたと記憶しております。(間違っていればすみません

    ありがとうございます!記載いただいたコード、参考にしながらコーディングしてみます!
  2. @KLB686

    Questioner
    @_y_s 様

    お世話になっております。
    回答内容、大変参考になりまして、実装のあと一歩のところまで来ることができました。

    一方で、質問内容を更新をさせていただいております。
    もしお時間あれば、ご一読、何かしらのアドバイスをいただければと存じます。

「白い半透明な画像→通常の画像」「スクロールで順番にフェードインする」「偶数奇数でフェードインの方向が変わる」というポイントを盛り込んだ、それっぽいものを作ってみました。
参考になれば幸いです。
ソースを見てみてわからないポイントなどあれば、質問いただければ解説いたします。

See the Pen fadein by yotty (@yotty) on CodePen.


スクロールで表示される動きはこちらを参考にしました。

0Like

Comments

  1. @KLB686

    Questioner
    @YottyPG 様

    ご回答ありがとうございます!!

    こちら、一度確認してコーディングしてみます!
    分からない箇所がでてきましたら、ご質問させていただきます。

    前回もご回答いただいたと記憶しております。
    誠にありがとうございます!
  2. @KLB686

    Questioner
    @YottyPG 様

    お世話になっております。
    前回は詳細なご回答ありがとうございました。
    回答内容、大変参考になりました。
    実装のあと一歩のところまで来ることができました。

    一方で、質問内容を更新をさせていただいております。
    もしお時間あれば、ご一読、何かしらのアドバイスをいただければと存じます。

スクロール時、3つある[container]クラスそれぞれに対し、フェードインされてしまう

「container」をクラスに持つオブジェクト全てに対して処理をしているためそのような動きになっていると思われます。
inviewが発火したオブジェクトのみに適用したいと思うので、$(".container")となっている箇所を$(this)に変更することでうまくいかないでしょうか?

- $(".container").children(".obj").addClass("fadeinRight");
+ $(this).children(".obj").addClass("fadeinRight");
0Like

Comments

  1. @KLB686

    Questioner
    @YottyPG 様

    アドバイスありがとうございます!!
    やってみます!
  2. @KLB686

    Questioner
    アドバイスいただいた、下記の内容で修正してみました!

    【修正箇所】
    - $(".container").children(".obj").addClass("fadeinRight");
    + $(this).children(".obj").addClass("fadeinRight");

    【修正実施】
    $(".container") → $(this)

    【実施結果】
    (".obj").addClass("fadeinRight")が挙動しなくなった
    ※画像の前にでてくる灰色のオブジェクトがフェードインしなくなった という意味

    挙動自体は添付gifと同じ挙動になった為、「クラスに持つオブジェクト全てに対して処理」について自分の見落としがあると感じました。

    いただいたアドバイスを元にもう一度修正してみます!
  3. すみません、setTimeoutで別の関数内に入って、thisの内容が変わっていてうまくいってないんだと思います。
    setTimeoutに入る前に発火した要素を変数に退避して、$(".container")をすべてその変数で書き換えてうまくいかないでしょうか?

    イメージ以下のようなかたちです。


    var container = $(this);

    setTimeout(function () {
    container.children(".obj").addClass("fadeinRight");
    container
    .children(".p-service__mainPhoto")
    .addClass("fadeinRightImg");
  4. @KLB686

    Questioner
    度々お手間とらせてしまい申し訳ございません!

    ありがとうございます!

    やってみます!!!
  5. @KLB686

    Questioner
    @YottyPG 様

    アドバイスの通り、発火した要素を変数に退避することで挙動を再現することができました!!本当にありがとうございます!

    今回、自力で辿り着けなかった「発火した要素から考える」「変数に退避する」について
    console.logにて検証してみました。

    質問を再度編集しております。

    これは発火した要素である[$(this)]が関数内で処理されることで
    [WINDOW]オブジェクト(全オブジェクトの親要素になるオブジェクト)に変化してしまったという解釈でよろしいのでしょうか。

    お時間あれば、ご回答をいただければと存じます。

javascriptのthisについてはこの記事が大変参考になると思います。

thisについての理解に不安がありますが、ここからは私の理解で説明させていただきます。
間違っている内容があったらすみません。ご自身でもthisについていろいろ調べてみてください。

今回でいえば、
$(".container").on("inview", function (event, fadeInS) {
これは「container」をクラスに持つ要素を持つオブジェクトが表示されたら発火され、その要素から呼ばれたことになるので、このfunctionのスコープ内のthisはイベント発火元の表示された「container」をクラスに持つ要素になります。

ただ、その関数内で
setTimeout(function () {
とsetTimeout()を利用して新たな関数が呼び出されています。

setTimeout()はwindowオブジェクトのメソッドなので、このスコープ内でのthiswindowになります。




thisはスコープによって変動するので、使い方に注意が必要そうです。
今回でいえばイベントハンドラから要素が取れるので、退避したりせずとも、以下のようにするのが一番よかったのかもしれません。

$(event.currentTarget).children(".obj").addClass("fadeinRight");
$(event.currentTarget)
    .children(".p-service__mainPhoto")
    .addClass("fadeinRightImg");
...
0Like

Comments

  1. @KLB686

    Questioner
    @YottyPG 様

    度々のご回答ありがとうございます。
    添付URL、確認させていただきました。

    大変分かりやすい記事で上記で説明いただいた内容とあわせて
    少し理解が深まったと感じました。

    【解釈】
    ・$(this)はfunctionを基準に考える
    ・functionを呼び出した時の直前にオブジェクトを参照する
    ・ただし、例外や注意点がある
    □メソッドがWINDOWメソッド等、特定オブジェクトを参照する場合
    □添付URL > 「関数の中の関数」より、関数呼び出し時に[.]を使っていない場合

    上記のように解釈しました。
    まだまだ本当に勉強不足だなと感じましたが、お力添えのおかげで少し知識がついたような気がしております。

    より簡潔なコードにできるよう、イベントハンドラから要素取得する方針で再度コードを修正しております。

    本当にご親切にご回答いただき、誠にありがとうございました。

    私事ですが、未経験ながら8月からフロントエンジニアとしてデビューをする運びとなりました。
    前職が語学教師でして本当に正直不安しかありませんが、またこちらで質問させていただく機会があると思います。その際は、是非厳しい目でご指摘いただければ幸いです。
  2. すみません、引数`event`は「イベントハンドラ」ではなく、正しくは「イベントオブジェクト」ですね。
    失礼いたしました。

    最初はわからないことも多くあるかと思いますが、実際に手を動かしながら知識を深めていってください。
    お互いエンジニアとして頑張っていきましょう!

Your answer might help someone💌