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

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

ただいまの
回答率

88.77%

スマートフォンでslideDownとslideUpが2回効いてしまうのを直したいです。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,336

MNZ

score 30

JS初心者のものです。
スマートフォンでのslideDownとslideUpに関して質問させてください。

現在スクロールすると途中からナビゲーションがslideDownで出てくるサイトを作っています。 ( minedenim.jp のようなサイトです。 )
基本的に1ページで、ナビゲーションにアンカーリンクをつけてその指定場所にスムーススクロールするといったよくあるサイトです。

一部下層ページがあり、下層ページのナビゲーションをTOPトップページのアンカーリンクを指定したところにすると、
PCだとアンカーリンクも効いてナビゲーションがきちんとslideDownで表示されるのですが、
SPから確認するとナビゲーションがslideDownで表示され、slideUpでナビゲーションが戻り、それから再度slideDownでナビゲーションが表示されることが結構あります。(ならないときもあります。)

ここで詰まってしまい解決できないため質問させていただきました。
おそらく書き方が悪いと思いますので、皆様のお力を貸していただきたく思います。

JSは</body>直前で読み込ませております。

ソースコード一式を下記に記載させていただきますので、お力添えをいただけますと非常に助かります。
何卒宜しくお願い致します。

// =====================================================================
// ============================== PC/SP 共通 ==============================
// =====================================================================

$(function(){

    // biggerlink
    $('#projects .article').biggerlink();

    // matchHeight
    $('.js-matchHeight').matchHeight();

    // smooth scroll
    $('a[href^=#]').click(function(){
    var speed = 1000;
    var href= $(this).attr("href");
    var target = $(href == "#" || href == "" ? 'html' : href);
    var position = target.offset().top;
    $("html, body").animate({scrollTop:position}, speed, "easeInOutQuad");
    return false;
    });

});

// PC/SP条件分岐
var windowWidth = $(window).width();
var windowSm = 824;
if (windowWidth <= windowSm) {

 // =========================================
 // ========== 横幅824px以下に行う処理を書く =========
 // =========================================

$(function(){

    // 途中ヘッダー出現
    $(window).on("load scroll", function () {
     if ($(this).scrollTop() > 35) {
       $(".cb-header").slideDown();
     } else {
       $(".cb-header").slideUp();
     }
    });

});

} else {

 // =============================================
 // ========== 横幅825px超のときに行う処理を書く ==========
 // =============================================

 $(function(){

     // 途中ヘッダー出現
     $(window).on("load scroll", function () {
      if ($(this).scrollTop() > 92) {
        $(".cb-header").slideDown();
      } else {
        $(".cb-header").slideUp();
      }
     });

     // firefox用 ヘッダー固定
     $(window).load(function (){
      if(top.location.href.match(/\#projects$/)){
       top.location.href = "index.html#projects",
       $(".cb-header").slideDown();
      } else if(top.location.href.match(/\#people$/)){
       top.location.href = "index.html#people"
      } else if(top.location.href.match(/\#company$/)){
       top.location.href = "index.html#company"
      }
     });

 });

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+2

ヘッダ出現の判定がよくないようです。
質問のコードでは、scrollイベントが呼び出されるたびにslideUpなどの処理がされています。
scrollイベントはちょっとスクロールされる間に何十回と呼び出されるものですので、何十回とslideUpを実行しようとして、結果的におかしくなるのです。
slideUp,slideDownを呼び出すのは、scrollTopの値が、ある閾値(しきいち)を超えた瞬間だけにすれば、おかしな挙動をしなくなります。
具体的にいうと、こんな感じのコードです。

var s_old = $(window).scrollTop();// ここに「前回のスクロール位置」を常に保存します
$(window).on("load scroll", function () {
    var t = 35;
    var s = $(this).scrollTop();// 今回のスクロール位置
    if ((s_old < t)&&(t <= s)){
        $(".cb-header").slideDown();
    } else if ((s < t)&&(t <= s_old)){
        $(".cb-header").slideUp();
    }
    s_old = s;
});

追記

iPhoneではscrollTopが前後することがあるのがわかりましたので、スライド中はスライドなうでフラグ管理して、過敏な反応をしないようにしておけば、うまく行くかと思います。

var slide_now = false;
var s_old = $(window).scrollTop();// ここに「前回のスクロール位置」を常に保存します
$(window).on("load scroll", function () {
    if (slide_now) return true;
    var t = 35;
    var s = $(this).scrollTop();// 今回のスクロール位置
    if ((s_old < t)&&(t <= s)){
        slide_now = true;
        $(".cb-header").slideDown("slow",function(){
            slide_now = false;
        });
    } else if ((s < t)&&(t <= s_old)){
        slide_now = true;
        $(".cb-header").slideUp("slow",function(){
            slide_now = false;
        });
    }
    s_old = s;
});

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/08/08 18:38

    確認しました。問題なさそうですね。

    キャンセル

  • 2017/08/08 19:04

    zohnamさま
    ご確認いただきましてありがとうございました!

    キャンセル

  • 2017/08/24 14:04

    @zohnamさま

    以前こちら解決したのですが、新たに作り直すことになりまた不具合が出てしまいました。
    解決したいので、どうかお力お貸しいただけないでしょうか。
    よろしくお願いいたします。
    https://teratail.com/questions/89586

    キャンセル

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

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

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