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

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

ただいまの
回答率

88.59%

jQuery 取得した座標で行う条件分岐がうまくいかない

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 463

kusaka00

score 54

宜しくお願いします。
自分の勉強用にパララックスとアニメーションを使ったを1枚ペラのページになります。

■質問内容

座標を取得して基準となる数値より大きくなれば「class="img_box"」に「bottom_move」のクラスを追記し、
アニメーションを発動させる作りになっています。

所定の位置までスクロールを下げると一旦は「class="img_box"」に「bottom_move」のクラスが追記され、
アニメーションが発動するのですが、少しづつスクロールを下げていくと「class="img_box"」についた「bottom_move」が外され
付いたりしてclass="img_box "のついた画像の動きがおかしくなってしまいます。

他にも同じような事をしてる箇所はあるのですが、そこでは普通に動作しているので、原因がよくわからないです。
何卒、ご教授をお願い致します。

■下記作成したページ(※解決後に削除するので、ソースも張ります)
http://manajp.com/sample/sample.html

■HTML

<body>
    <section id="first" class="content">
        <p class="logo">jQuery x HTML5 x CSS3</p>
        <article class="first_box">
            <h1>Parallax sample.</h1>
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
        </article>
    </section>

    <section id="second" class="content">
        <article class="second_box">
            <h2>Only CSS.</h2>
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
        </article>
    </section>

    <section id="third" class="content">
        <article class="third_box">
            <h2>Without jQuery</h2>
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
        </article>
        <img class="img_box" src="img/img-parallaxsample01.jpg" />
    </section>

    <section id="theend" class="content">
        <h2>The End.</h2>
    </section>
</body>

■CSS

body {
  margin: 0;
  min-width: 320px;
}

img {
    width: 100%;
    height: auto;
}

article h2, article h1 {
  font-size: 3.6em;
  line-height: 1em;
  margin: 25px 0;
}

.content {
  border-bottom: 1px solid rgba(0, 0, 0, 0.4);
  border-top: 1px solid rgba(255, 255, 255, 0.3);
  box-shadow: 0 0 50px rgba(0, 0, 0, 0.8);
  color: #333;
  margin: 0 auto;
  /*padding-top: calc(1150 / 1150 * 100%);*/
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: hidden;
}

#first {
  background: url(./img/bg-parallaxsample01.jpg) 50% 0 no-repeat fixed;
  background-size: cover;
}

#second {
  background: url(./img/bg-parallaxsample02.jpg) 50% 0 no-repeat fixed black;
  background-size: cover;
}

#third {
  background: url(./img/bg-parallaxsample03.jpg) 50% 0 no-repeat fixed black;
  background-size: cover;
}

#theend {
  background: url(./img/bg-parallaxsample04.jpg) 50% 0 no-repeat fixed #e6cda4;
  background-size: cover;
}

/* section first */
.logo {
  color: rgba(255, 255, 255, 0.9);
  font-size: 4em;
  font-weight: bold;
  margin: 0;
  position: fixed;
  top: calc(100 / 1150 * 100%);
  left: calc(50 / 1150 * 100%);
  text-shadow: 0 -1px rgba(0, 0, 0, 0.4);
}

.first_box {
  background: rgba(255, 255, 255, 0.9);
  border: 1px solid rgba(150, 150, 150, 0.1);
  box-shadow: 0 0 8px 4px rgba(0, 0, 0, 0.4);
  padding: 18px;
  position: absolute;
  top: calc(300 / 1150 * 100%);
  width: calc(800 / 1150 * 100%);
  left: -100%;
  transition: all 1s 0s ease;
}

.first_box.right_move {
    -webkit-transform:translateX(150%);
            transform:translateX(150%);
}


/* section second */
.second_box {
    position: absolute;
    top: calc(80 / 1150 * 100%);
    background: rgba(51, 51, 51, 0.9);
    border: 1px solid rgba(150, 150, 150, 0.1);
    box-shadow: 0 0 8px 4px rgba(0, 0, 0, 0.4);
    color: white;
    margin-left: calc(100 / 1150 * 100%);
    padding: calc(10 / 1150 * 100%) calc(20 / 1150 * 100%);
    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.5);
    line-height: 1.5em;
    width: calc(445 / 1150 * 100%);
    transition: all 1s 0s ease;
}

/* section third */
.third_box {
    background: rgba(51, 51, 51, 0.9);
    border: 1px solid rgba(150, 150, 150, 0.1);
    box-shadow: 0 0 25px rgba(0, 0, 0, 0.3);
    color: white;
    padding: calc(10 / 1150 * 100%) calc(20 / 1150 * 100%);
    margin: calc(100 / 1150 * 100%) 0 0 60%;
    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.5);
    line-height: 1.5em;
    color: white;
    position: absolute;
    top: 0;
    right: -50%;
    transition: all 1s 0s ease;
    width: 40%;
}

.third_box.left_move {
    -webkit-transform: translateX(-116%);
            transform: translateX(-116%);
}


.img_box {
    border: 8px solid white;
    box-shadow: 0 0 8px 4px rgba(0, 0, 0, 0.4);
    height: auto;
    width: calc(400 / 1150 * 100%);
    position: absolute;
    left: calc(30 / 1150 * 100%);
    top: 0;
    /*-webkit-transform: rotate(-8deg);
    transform: rotate(-8deg);*/
    transition: all 1s 0s ease;
}

.img_box.bottom_move {
    -webkit-transform: translateY(116%) rotate(-12deg);
            transform: translateY(116%) rotate(-12deg);
}

/* section the end */
#theend h2 {
  color: white;
  font-size: 4em;
  left: 50%;
  margin-left: calc(150 / 1150 * -100%);
  position: absolute;
  text-shadow: 0 0 16px rgba(140, 123, 96, 0.8);
  top: calc(180 / 1150 * 100%);
  width: calc(300 / 1150 * 100%);
}

■jQuery

$(function(){
    //最初に非表示
    //$('.content div, .content i').css("opacity","0");
    window.onload = function () {
        $('.first_box').addClass('right_move');
    };

    $(window).scroll(function (){
        $("#first").each(function(){
            var imgPos = $(this).offset().top;
            var scroll = $(window).scrollTop();
            var windowHeight = $(window).height();
            var goukei = windowHeight/windowHeight;
            if (scroll > windowHeight/windowHeight){
                $('.first_box').addClass('right_move');
                $("i, div",this).css("opacity","1" );
                $("i",this).css({
                    "font-size": "100px",
                    "padding": "0 20px 40px"
                });
            } else {
                $('.first_box').removeClass('right_move');
                $("i, div",this).css("opacity","0" );
                $("i",this).css({
                    "font-size": "20px",
                    "padding": "20px"
                });
            }
        });
        $("#second").each(function(){
            var imgPos = $(this).offset().top;
            var scroll = $(window).scrollTop();
            var windowHeight = $(window).height();
            if (scroll > imgPos - windowHeight + windowHeight/3){
                $('.second_box').css("opacity","1" );
            } else {
                $('.second_box').css("opacity","0" );
            }
        });
        $("#third").each(function(){
            var imgPos = $(this).offset().top;
            var scroll = $(window).scrollTop();
            var windowHeight = $(window).height();
            var goukei = imgPos - windowHeight + windowHeight/3
            if (scroll > imgPos - windowHeight + windowHeight/3){
                $('.third_box').addClass('left_move');
                $('.third_box').css("opacity","1" );
            } else {
                $('.third_box').removeClass('left_move');
                $('.third_box').css("opacity","0" );
            }
        });
        $(".img_box").each(function(){
            var imgPos = $(this).offset().top;
            var scroll = $(window).scrollTop();
            var windowHeight = $(window).height();
            var goukei = imgPos - windowHeight + windowHeight/2
            if (scroll > imgPos - windowHeight + windowHeight/2){
                $('.img_box').addClass('bottom_move');
                $('.img_box').css("opacity","1" );
            } else {
                $('.img_box').removeClass('bottom_move');
                $('.img_box').css("opacity","0" );
            }
        });
    });
});

以上となります。
宜しくお願い致します。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

.bottom_moveを付け外す条件文に問題がありそうですね。

ソースコードを見る限り、スクロールイベントが発火するたびにimgPosの値が変更されているようです。
つまり.bottom_moveが付与されるたびにimgPosの値が変更されているため、一定の位置まで

if (scroll > imgPos - windowHeight + windowHeight/2){
    $('.img_box').addClass('bottom_move');
    $('.img_box').css("opacity","1" );
} else {
    $('.img_box').removeClass('bottom_move');
    $('.img_box').css("opacity","0" );
}


の条件式にtrue,falseが交互に返っているのだと思います。

下記のように変数の値をコンソールで確認してみるとわかりやすいかと思います。

$(".img_box").each(function(){
    var imgPos = $(this).offset().top;
    var scroll = $(window).scrollTop();
    var windowHeight = $(window).height();
    var goukei = imgPos - windowHeight + windowHeight/2
    console.log("imgPos:" + imgPos);
    console.log("scroll:" + scroll);
    console.log("windowHeight:" + windowHeight);
    console.log("goukei:" + goukei);
    if (scroll > goukei){
        $('.img_box').addClass('bottom_move');
        $('.img_box').css("opacity","1" );
    } else {
        $('.img_box').removeClass('bottom_move');
        $('.img_box').css("opacity","0" );
    }
});

すごく雑ですが、下記のようにするとクラスの付け外しが意図通りになるかと思います。

$(function(){
    var imgTop = $(".img_box").offset().top;
    $(window).scroll(function (){
        $(".img_box").each(function(){
            var scroll = $(window).scrollTop();
            var windowHeight = $(window).height();
            if (scroll > imgTop - windowHeight + windowHeight/2){
                $('.img_box').addClass('bottom_move');
                $('.img_box').css("opacity","1" );
            } else {
                $('.img_box').removeClass('bottom_move');
                $('.img_box').css("opacity","0" );
            }
        });
    });
});

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/19 17:29

    ご回答いただき、ありがとうございます。
    今回は「scroll > goukei」が成立した後、表示された画像が
    下に下がるアニメーションを付けていたため、「imgPos」の座標が変わってしまい、
    「scroll > goukei」が成り立たなくなって、
    「bottom_move」が外されてしまっていたってことですね。

    そのため、スクロールごとに「imgPos」の座標を読み込むのを止めて、
    最初の1回だけにしたんですね。

    すごく納得できました。
    頂いたソースに変えたらイメージ通りの動きになりました。
    有難うございます。

    キャンセル

  • 2019/06/19 22:14

    です!解決したみたいでよかったです◎

    キャンセル

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

  • ただいまの回答率 88.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る