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

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

ただいまの
回答率

90.34%

JQueryでスクロールした時とウィンドウ幅を変更させた時のイベント処理のコードをマージしたいです。

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,038

lingwood

score 33

前提・実現したいこと

ホームページを作っています。
スクロールすると適度な位置でヘッダーを縮小されて上部にfixedされ、
ウィンドウ幅768px以下にした場合にはその際に付与されたクラスを外す
ようにしたいです。

JavaScriptはまだ初心者です。

発生している問題・エラーメッセージ

スクロールして固定するスクリプト単体だと動きますが、
マージすると動かなくなります。

該当のソースコード

■マージしてみたコード

function init() {
var px_change  = 300;
var x = $(window).width();
var y = 769;
window.addEventListener('scroll','resize',function(e){
if ( $(window).scrollTop() > px_change,x <= y){
$("header").addClass("smaller");
} else if ( $("header").hasClass("smaller") ) {
$("header").removeClass("smaller");
}
});
}
window.onload = init();

参考にしたコード 1 元々のコードです。一定(300)までスクロールしたらsmallerをクラスに付与する

function init() {
var px_change  = 300;
window.addEventListener('scroll',function(e){
if ( $(window).scrollTop() > px_change){
$("header").addClass("smaller");
} else if ( $("header").hasClass("smaller") ) {
$("header").removeClass("smaller");
}
});
}
window.onload = init();

参考にしたコード 2 ウィンドウ幅でクラスを追加したり削除したりする

$(window).resize(function(){
    //windowの幅をxに代入
    var x = $(window).width();
    //windowの分岐幅をyに代入
    var y = 640;
    if (x <= y) {
        $('#colorBox').addClass('redbox').removeClass('bluebox');
        $('#imageBox').addClass('morning-b').removeClass('morning-a');
    }else{
        $('#colorBox').addClass('bluebox').removeClass('redbox');
        $('#imageBox').addClass('morning-a').removeClass('morning-b');
    }
});

試したこと

ネットで調べたりしながらコードを分けて書いてみたりといろいろな書き方を試してみましたが満足に動かなかったです。

お力添えいただけますよう、何卒よろしくお願い申し上げます。

【追記 1】

ご指摘をいただきまして、コードを変更してみたのですが、ウィンドウをリサイズするとクラスが解除されて
しまいヘッダーが元に戻ってしまいました。
その後もうまくできず良くわからなくなってきてしまい、
取り急ぎ取得したいイベントの「状態・こうしたい」という形をもう具体的に追記させて頂きたく思います。

スクロールすると適度な位置でヘッダーを縮小されて上部にfixedされ、
ウィンドウ幅768px以下にした場合にはその際に付与されたクラスを外す
ようにしたいです。

1.ウィンドウ幅768px以上の時

スクロールさせた時
・スクロールしていない状態の時にはヘッダーは通常通りに表示
・一定の場所までスクロールすると別のクラスを付与

スクロールを戻した時
・付与したクラスをリムーブ、ヘッダーを元に戻します。

ウィンドウ幅768px以上の時にウィンドウ幅を変更
・スクロールさせた時、スクロールを戻した時(これは変わらないですが)の
状態と変わらない。

2.ウィンドウ幅768以下の時

スクロールさせた時、スクロールを戻した時
・ウィンドウ幅768px以下なのでクラスの付与はしない

ウィンドウ幅768px以上に変更した場合
・スクロールの位置でクラスの付与がされいる、されていない状態に
変わらなければならない

となります。
よろしくお願い致します。

【追記 2】

function init() {

var y  = 300;
var x = 768;
var scroll = $(window).scrollTop();
var width = $(window).width();

window.addEventListener('scroll', function(e){

if ( scroll > y ) {  //スクロール量がy(300)より大きい時
    $("header").addClass("smaller");

        } else if ( $(window).scrollTop() < y ) { 

    $("header").removeClass("smaller");

        } else if ( $(window).width() < x ) {

    $("header").removeClass("smaller");

        } else if ( $(window).width() > x ) {

    $("header").addClass("smaller");

         }

    });

window.addEventListener('resize', function(e){

if ( width < x ) { //widthがx(768)より小さい

    $("header").removeClass("smaller");

        } else if ( $(window).scrollTop() < y ) { 

    $("header").removeClass("smaller");

        } else if ( $(window).width() < x ) {

    $("header").addClass("smaller");

        }
    });
}
window.onload = init();

デベロッパーツールを見ながらやってみましたところ、
上記のコードで、
【GOOD】
①指定したスクロール量に達した際にsmallのクラスが付与できました。
②スクロールを戻すとクラスをリムーブできました。
②ウィンドウ枠を768px以下にしたところクラスがつかないようになりました。
スクロールしてもつかない状態になりました。

【BAD】
①ウィンドウ枠768px以上でかつsmallが付与されている状態でウィンドウ枠を
動かすとsmallが一旦リムーブされてしまいました。
②ウィンドウ枠768px以下でsmallがついていない状態からウィンドウ枠を戻しても
クラスが付与されません。
③ウィンドウ枠768px以下でスクロールされた状態からウィンドウ幅を広げても
元に戻らず → (つまりsmallが付与されていない?)
スクロールさせてあげなければならない。

という状況になっております。

【追記 3】

次に以下の通りにしてみました。

function init() {

var y  = 300;
var x = 768;
var scroll = $(window).scrollTop();
var width = $(window).width();

window.addEventListener('scroll', function(e){

if ( scroll > y ) {  //スクロール量がy(300)より大きい時
    $("header").addClass("smaller");

        } else if ( $(window).scrollTop() < y ) { 

    $("header").removeClass("smaller");

        } else if ( $(window).width() < x ) {

    $("header").removeClass("smaller");

        } else if ( $(window).width() > x ) {

    $("header").addClass("smaller");

         }

    });
}
window.onload = init();

【GOOD】
①指定したスクロール量に達した際にsmallのクラスが付与できました。
②スクロールを戻すとクラスをリムーブできました。
②ウィンドウ枠を768px以下にしたところクラスがつかないようになりました。
スクロールしてもつかない状態になりました。
④ウィンドウ枠768px以上でかつsmallが付与されている状態でウィンドウ枠を
動かすとsmallが一旦リムーブされていたのがリムーブされなくなりました。

【BAD】
①ウィンドウ枠768px以下でsmallがついていない状態からウィンドウ枠を戻しても
クラスが付与されません。
②ウィンドウ枠768px以下でスクロールされた状態からウィンドウ幅を広げても
元に戻らず → (つまりsmallが付与されていない?)
スクロールさせてあげなければならない。

この書き方は正しい?のでしょうか?

【追記 4】

//書き直し


$(window).resize(function(){
    var w = $(window).width();
    var x = 768;

console.log( $(window).scrollTop(),$(window).width(),w);

    if (x <= y) {
        $('header').addClass('smaller');
    } else if ( $(window).scrollTop() <= 300 ) {
        $('header').removeClass('smaller');
    } else {
        $('header').removeClass('smaller');
    }
});


$(window).scroll(function(){

console.log( $(window).scrollTop(),$(window).width(),sc);

    var sc = $(window).scrollTop();
    var h = 300;

    if (h <= sc) {
        $('header').addClass('smaller');
    } else {
        $('header').removeClass('smaller');
    }
});



//ここまで


/*******************10/26ここまでダメ******************************/
/*
function init() {

var y = 300;
var x = 768;

console.log( $(window).scrollTop(),$(window).width());

window.addEventListener('scroll', function(e){

    if ( $(window).scrollTop() > y ) {

    $("header").addClass("smaller");

    } else {

    $("header").removeClass("smaller");

    }
});


console.log( $(window).scrollTop(),$(window).width());

window.addEventListener('resize', function(e) {

    if ( $(window).width() > x ) { //widthがx(768)より小さい

    $("header").addClass("smaller");

    } else {

    $("header").removeClass("smaller");

    }

});

}*/

window.onload = init();

/*
    $("header").addClass("smaller");

        } else if ( $(window).scrollTop() < y ) { //それ以外の時にheaderがsmallerを持っていたら外しましょう

    $("header").removeClass("smaller");

        } else if ( $(window).width() < x ) {

    $("header").removeClass("smaller");

        } else {

    $("header").addClass("smaller");

         }

    });
console.log( $(window).scrollTop(),width);

/*window.addEventListener('resize', function(e){

if ( width < x ) { //widthがx(768)より小さい

    $("header").removeClass("smaller");

        } else if ( $(window).scrollTop() < y ) { 

    $("header").removeClass("smaller");

        } else if ( $(window).width() < x ) {

    $("header").addClass("smaller");

        }
    });
}
*/

いろいろと追記を変更してみました。
追記4のように書き直してみまして良さそうだなと思ったのですが、

やっぱり768px以下の際にスクロールすると
headerにsmallerがついてしまいます。

このsmallerがつくと、ウィンドウがスクロールの際にカックンとなり、
ちょっとページ内リンクにいきなりとんだような動作をします。
そのため、メニューバーの表示にズレが生じるなど問題があります。

コンソールログも入れてみたのですが、
良くわからなかったです。

いろいろ頑張ってみたのですが、
どんどん改悪してしまいました。

【追記5】

すみません、こちらの件ですがどなた様か
ジャストで答えと簡単で良いので解説をご教示いただけないでしょうか。

ずっと解にたどり着くよう導いてきてくださいましたtimy様に
ご指南頂くのが本来ベストかと思いますが、

人それぞれに多様な思想、思惑がおありだと思いますので、
無理をお願いするのもと思いまして・・・

本当に申し訳ございませんが、
何卒よろしくお願い申し上げます。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

+2

window.addEventListener('scroll','resize',function(e){


このコールの仕方がまずありえないですよね。指定するイベントタイプは一つです。
if文の条件式を2つカンマで区切っているのもNGです。

window.addEventListener('scroll', function(e){
  if ( $(window).scrollTop() > px_change){
    $("header").addClass("smaller");
  }
});

window.addEventListener('resize', function(e){
  if ( x <= y ) {
    $("header").removeClass("smaller");
  }
});


scrollイベント、resizeイベントをそれぞれ書いてやればOKなはず。

スクロールすると適度な位置でヘッダーを縮小されて上部にfixedされ、 
ウィンドウ幅768px以下にした場合にはその際に付与されたクラスを外す 

この文章の表現通りならこうなると思いますが実際は「スクロールを戻した時」「ウィンドウ幅を広げた時」の対応もおそらく必要ですよね。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/10/26 16:26

    追記3を見ました。
    resizeイベントの処理がなくなっていますが省略しただけでしょうか?
    ではないですよね。
    全体に「枠(幅)を動かしても何も起こらない」状態になったのはresizeイベントを処理していないからでしょう。

    > スクロールさせてあげなければならない。

    scroll イベントしか処理していないので、「スクロールした時に幅がチェックされる」という変な流れになっています。scroll イベントでウィンドウ幅だけを単体でチェックしても意味がないはずです。それはresizeイベントで見ないと。「スクロールは300以上だが幅は768未満の場合どうする?」のように「同時に」両方見て判定することを想定しています。
    GOOD/BADを見ると今まで不明だった幅とスクロールが矛盾する場合の想定動作がわかってきましたが、スクロールした時はスクロール優先、リサイズした時は幅優先、のようなので上記のような同時判定も不要かもしれません。

    そもそも最初の if 文にscroll 変数が使われたままの時点でGOOD①の動作にはならないと思うんですが、不可解ですね。
    イベントリスナーの最初に console.log でスクロールと幅の値を出力してやり、 if 文の全てのブロックにもそれぞれ console.log を仕込んでどこが処理されているか逐一確認すれば様子がわかってくるんじゃないでしょうか。

    条件判定も else if ... で一つずつ見ていくんじゃなく、「addClassする条件」「removeClassする条件」のif文が一つずつでelseは要らないはずです。「両方を満たす場合」がないように条件式を書くべきです。

    キャンセル

  • 2016/10/26 16:45

    timy 様

    お世話になります。
    ご返信ありがとうございます。

    つまり、scrollイベントとresizeイベントはやっぱり両方が必要ということですね。

    ありがとうございます。すぐやってみます。

    キャンセル

  • 2016/10/27 10:40

    timy 様

    おはようございます。お世話になります。
    すみません、やはりできませんでした。

    何度も何度も書き直したりして試してみたのですが、
    コンソールログの使い方も良くわからなかったです。

    >そもそも最初の if 文にscroll 変数が使われたままの時点でGOOD①の動作にはならない>と思うんですが、不可解ですね。

    ただ、追記4の書き方に変更したらスクロールに値が出たのですが、
    イベントリスナーでは値がずっと0のままでした。

    これは、条件式の問題なのでしょうか?
    書き方?文法?は正しいのでしょうか?
    いろいろな書き方があるみたいでどれが正しいのでしょうか?
    scrollイベントとresizeイベントは別々に書いてもちゃんと判定するのでしょうか?

    if文一つだけでやったのですが、結局smallerが戻らなかったり、
    ウィンドウサイズを狭めた際にもsmallerがついてしまったりしました。

    キャンセル

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

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

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

  • トップ
  • HTMLに関する質問
  • JQueryでスクロールした時とウィンドウ幅を変更させた時のイベント処理のコードをマージしたいです。