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

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

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

CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

jQuery

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

1回答

5305閲覧

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

lingwood

総合スコア40

CSS3

CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

jQuery

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2016/10/19 01:16

編集2016/10/31 06:14

###前提・実現したいこと
ホームページを作っています。
スクロールすると適度な位置でヘッダーを縮小されて上部に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様に
ご指南頂くのが本来ベストかと思いますが、

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

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

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

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

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

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

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

guest

回答1

0

Javascript

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

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

Javascript

1window.addEventListener('scroll', function(e){ 2 if ( $(window).scrollTop() > px_change){ 3 $("header").addClass("smaller"); 4 } 5}); 6 7window.addEventListener('resize', function(e){ 8 if ( x <= y ) { 9 $("header").removeClass("smaller"); 10 } 11});

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

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

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

投稿2016/10/19 04:09

timy

総合スコア168

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

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

lingwood

2016/10/19 07:44

timy 様 お世話になります。 ご回答誠にありがとうございます。 今しがた拝見しまして、コードを入れてみましたが、 ご指摘の通り動きに問題がありました。 また、バラバラのコードですと、ウィンドウリサイズ時にクラスが 解除されてしまって、ヘッダーが元に戻ってしまうようです。 いろいろコード変更してやってみているのですが、 どうにもできないです。 せっかくご教示頂いたのに活かしきれずすみません。 もしお時間ございましたらもう少しお付き合い頂ければと思います。 何卒よろしくお願い申し上げます。
timy

2016/10/19 08:23

「ウィンドウ幅」と「スクロール位置」の二つの条件で同じ要素を操作していますので両者が矛盾する場合の仕様を整理しましょう。 最初のコードに書かれていたif文、 if ( $(window).scrollTop() > px_change,x <= y){ が 「スクロール位置が300以上**かつ**ウィンドウ幅が768以下」 の意図なのか、あるいは 「スクロール位置が300以上**または**ウィンドウ幅が768以下」 なのかによって変わってきますが、いずれにしても両方を同時にチェックして判定するのが本来の意図のようですね。 それならリサイズ、スクロール両方のイベントで同じ関数を呼んでその中で判定処理をすればいいと思います。
lingwood

2016/10/19 09:12

timy 様 お世話になります。 ご教授いただきまして、誠にありがとうございます。ご指摘いただきました通りです。 いろいろやってみておりまして、 「リサイズ、スクロール両方のイベントで同じ関数を呼んでその中で判定処理」 とのことですが、解釈間違えてますでしょうか? 期待する動きにはなっていませんでしたが・・・泣 ``` function init() { var px_change = 300; var y = $(window).width(); var x = 769; window.addEventListener('scroll', function(e){ if ( $(window).scrollTop() > px_change ) { $("header").addClass("smaller"); } else if ( y <= x ) { $("header").addClass("smaller"); } else if ( $("header").hasClass("smaller") ) { $("header").removeClass("smaller"); } }); window.addEventListener('resize', function(e){ var px_change = 300; var y = $(window).width(); var x = 769; if ( y <= x ) { $("header").removeClass("smaller"); } else if ( x <= y ) { $("header").addClass("smaller"); } }); } window.onload = init(); ``` 理解力に乏しく本当にすみません。
timy

2016/10/20 04:24

全体の構造としては、 - 初期化時にその時点でのスクロール位置とウィンドウ幅を変数に代入しておく - check_header() のような関数を定義(もちろん名前は任意) - window.addEventListner で resize, scroll イベントの両方から check_header() を呼ぶ。 check_header() の処理は、smaller クラスを適用または除去する条件を満たしたか? を判定して処理。 つまり、 -「前回のスクロール位置(変数)が閾値未満」かつ「現在のスクロール位置が閾値以上」ならaddClass -「前回のウィンドウ幅(変数)が閾値以上」かつ「現在のウィンドウ幅が閾値未満」ならremoveClass - 最後に現在のスクロール位置およびウィンドウ幅を変数に代入しておく(次回チェックに使う) という感じじゃないでしょうか。 - 逆にスクロールした場合ヘッダを戻さなくていいのか? - ウィンドウ幅を広げた場合ヘッダを固定しなくていいのか? は考慮してませんがそこは仕様次第なので check_header()関数の中の判定を調整して下さい。
lingwood

2016/10/20 07:41

timy 様 お世話になります。ご教授ありがとうございます。 本日はまだ手がつけられておらず、申し訳ございません。 またご教授いただいた内容にて改めて挑戦してみたいと思います。 全くの初心者なため理解に乏しくご迷惑おかけいたしますが、 引き続きご厚情頂けますよう、何卒よろしくお願い申し上げます。
lingwood

2016/10/21 07:28

timy 様 お世話になります。 ご連絡が遅れてすみません。 昨日はあれから触っていたのですが、全然できませんで・・・ 自分なりの解釈とネットを見ながらコードをいろいろ 変更してみたのですが、やはり動きませんでした。 本当に解釈足らずすみませんが、 ************************************ - check_header() のような関数を定義(もちろん名前は任意) - window.addEventListner で resize, scroll イベントの両方から check_header() を呼ぶ。 ************************************ これをどのように書けばよいのかでずっと悩んでおります。 何度も変更した残骸になりますが、本当に理解力がなくすみません。 何とかしてできるようになりたいのですが、 もしまだお知恵を貸して頂けるようでしたら ご教示いただけましたら幸いです。 何卒よろしくお願い申し上げます。 function init() { var y = 300; var x = 768; var scroll = $(window).scrollTop(); var width = $(window).width(); var check = $(window).width() && $(window).scrollTop(); window.addEventListener('check', function(e){ if ( scroll > y && width > x) { //スクロール量がy(300)より大きくて、幅がx(768)より大きい時 $("header").addClass("smaller"); } else if ( $("header").hasClass("smaller") ) { //それ以外の時にheaderがsmallerを持っていたら外しましょう $("header").removeClass("smaller"); } }); window.addEventListener('resize', function(e){ if ( width < x ) { $("header").removeClass("smaller"); } }); } window.onload = init();
timy

2016/10/21 15:30

> window.addEventListener('check', function(e){ 最初の引数typeはイベントの種類ですから 'scroll' を変えてはダメです。 変数 scroll と width は初期化の時に値を入れてあとはずっとその同じ値のままですね。つまり( scroll > y && width > x) は何度イベントで判定しても同じ結果にしかなりません。 判定する時は最新の値で判定します。 その2点を修正すればひとまず動くはずです。 前回の値と比較するというのはこちらが言い出したことで最初の設計になかった話ですから余計でした。一度忘れてください。
退会済みユーザー

退会済みユーザー

2016/10/21 15:42

横レス失礼。 > timy さん > 指定するイベントタイプは一つです。 複数指定する方法はあります。 サンプルコード <!DOCTYPE HTML> <html lang="ja"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div> <a>ここをクリック・マウスオーバー</a> <p></p> </div> <script type="text/javascript" src="//code.jquery.com/jquery-2.2.4.min.js"></script> <script type="text/javascript"> $(function () { $("a").on('click mouseout', function (e) { $("p").text(e.type); }); }); </script> </body> </html>
lingwood

2016/10/24 03:31

timy 様 Kosuke_Shibuya 様 お世話になります。 ご回答、誠にありがとうございます。 今しがた拝見させて頂きまして、午後再度構成しなおしてみたいと思います。 また、timy様におかれましては初心者向けにイベントタイプは絞れというご配慮であると解釈しております。 というか、お二方ともすごくてついていけず大変お恥ずかしい限りです。 何とか少しでも理解を深めていきたいところ、 何卒おつきあい頂けますようよろしくお願い致します。
lingwood

2016/10/24 03:58

timy 様 お世話になります。 ご指摘の点を変更してやってみたのですが、 こういうことでしょうか? ただ、やはり動かなかったです。 こういうことだろうか・・・という形でもしかしたら少しでもヒントになる動きをするのではないだろうかと思いつつリロードしてみると全然動かなかったりで、 書き方が分からず混乱してしまって良くわかなくなってしまいました。 会社からもいろいろと言われてしまいまして、 一応、JavaScriptの基礎などはサイト見たりしているのですが、 そこに時間をかけたくてもかけられない現状もありまして、 本当にすみません。 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 ( width > x ) { // widthがx(768)より大きい時 $("header").addClass("smaller"); } else if ( $("header").hasClass("smaller") ) { //それ以外の時にheaderがsmallerを持っていたら外しましょう $("header").removeClass("smaller"); } }); window.addEventListener('resize', function(e){ if ( width < x ) { //widthがx(768)より小さい時 $("header").removeClass("smaller"); } else if ( scroll < y ) { // スクロール量がYよりも大きい時 $("header").removeClass("smaller"); } else if ( $("header").hasClass("smaller") ) { //それ以外の時にheaderがsmallerを持っていたら外しましょう $("header").removeClass("smaller"); } }); } window.onload = init(); 本当にありがたく頑張ってついていきたいのですが・・・ 本当にすみません...
timy

2016/10/25 03:16

どう「動かなかった」んでしょうか。Developer Tools などは見てますか?
lingwood

2016/10/25 10:34

timy 様 お世話になります。 先ほどはありがとうございます。 デベロッパーツールは見ながらやっています。 ご指摘の通り全く「動かない」というわけではなく、 期待通りに動かないということで非常にあせってしまっています。 今回、一旦落ち着いて改めてデベロッパーツールをみながら改修してみたのですが、 最終的に追記3のところまで来たのですが、 正しい文法でもない気もしておりまして、、、 この後はどのようにしたら良いのでしょうか・・・ 何が悪いのでしょうか? 恐れ入りますがご教授頂けませんでしょうか。 何卒よろしくお願い申し上げます。
timy

2016/10/26 07: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は要らないはずです。「両方を満たす場合」がないように条件式を書くべきです。
lingwood

2016/10/26 07:45

timy 様 お世話になります。 ご返信ありがとうございます。 つまり、scrollイベントとresizeイベントはやっぱり両方が必要ということですね。 ありがとうございます。すぐやってみます。
lingwood

2016/10/27 01:40

timy 様 おはようございます。お世話になります。 すみません、やはりできませんでした。 何度も何度も書き直したりして試してみたのですが、 コンソールログの使い方も良くわからなかったです。 >そもそも最初の if 文にscroll 変数が使われたままの時点でGOOD①の動作にはならない>と思うんですが、不可解ですね。 ただ、追記4の書き方に変更したらスクロールに値が出たのですが、 イベントリスナーでは値がずっと0のままでした。 これは、条件式の問題なのでしょうか? 書き方?文法?は正しいのでしょうか? いろいろな書き方があるみたいでどれが正しいのでしょうか? scrollイベントとresizeイベントは別々に書いてもちゃんと判定するのでしょうか? if文一つだけでやったのですが、結局smallerが戻らなかったり、 ウィンドウサイズを狭めた際にもsmallerがついてしまったりしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問