2017-11-18 6 views
1

jQueryの「スクロール」イベントから正しいスクロール方向を取得しようとしています。このためjQuery scrollTop()スクロール方向の変更で間違ったオフセットを返します

、私はここで解決策を使用しています:私は、スクロールの方向を変更した場合https://stackoverflow.com/a/4326907/8407840

をしかし、scrollTopスプライトによって返されたオフセットは、最初の時間に誤りがあります。これは、次の動作が発生:

  1. ホイールダウン - >ダウン
  2. ホイールダウン - >ダウン
  3. ホイールアップ - >ダウン
  4. ホイールアップ - >アップ
  5. ホイールダウン - >アップ
  6. ホイールダウン - >ダウン
  7. ...など、私はあなたがそれを得ると思います。

var ACTIVE_SECTION = null; 
 
var ANIMATION_DURATION = 700; 
 

 
$(document).ready(function() { 
 
    ACTIVE_SECTION = $("section:first-of-type").get(0); 
 
    var prevPosition = $(window).scrollTop(); 
 
    
 
    $(window).on("scroll", function() { 
 
    doScrollingStuff(prevPosition); 
 
    }); 
 

 
}); 
 

 
function doScrollingStuff(prevPosition) { 
 
    var ctPosition = $(window).scrollTop(); 
 
    var nextSection = ACTIVE_SECTION; 
 
    
 
    // Remove and re-append event, to prevent it from firing too often. 
 
    $(window).off("scroll"); 
 
    setTimeout(function() { 
 
    $(window).on("scroll", function() { 
 
     doScrollingStuff(prevPosition); 
 
    }); 
 
    }, ANIMATION_DURATION + 100); 
 

 
    // Determine scroll direction and target the next section 
 
    if(ctPosition < prevPosition) { 
 
    console.log("up"); 
 
    nextSection = $(ACTIVE_SECTION).prev("section").get(0); 
 
    } else if(ctPosition > prevPosition) { 
 
    console.log("down"); 
 
    nextSection = $(ACTIVE_SECTION).next("section").get(0); 
 
    } 
 
    
 
    // If a next section exists: Scroll to it! 
 
    if(typeof nextSection != 'undefined') { 
 
    var offset = $(nextSection).offset(); 
 
    $("body, html").animate({ 
 
     scrollTop: offset.top 
 
    }, ANIMATION_DURATION); 
 
    ACTIVE_SECTION = nextSection; 
 
    } else { 
 
    nextSection = ACTIVE_SECTION; 
 
    } 
 

 
    console.log(ACTIVE_SECTION); 
 
    prevPosition = ctPosition; 
 
}
section { 
 
    width:100%; 
 
    height:100vh; 
 
    padding:60px; 
 
    box-sizing:border-box; 
 
} 
 

 
section:nth-child(1) { background:#13F399; } 
 
section:nth-child(2) { background:#14FD43; } 
 
section:nth-child(3) { background:#4EE61E; } 
 
section:nth-child(4) { background:#BEFD14; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<section id="sect1">Section 1</section> 
 
<section id="sect2">Section 2</section> 
 
<section id="sect3">Section 3</section> 
 
<section id="sect4">Section 4</section>

ここにあなたが私の実装を見ることができるペン、です:https://codepen.io/EigenDerArtige/pen/aVEyxd

いつでもユーザーがスクロール私は、次または前のセクションに自動スクロールを達成しようとしていますかスワイプアップ/ダウン...したがって、私は一度に複数のスクロールジャックがすべて起こるのを防ぐために、1秒に1回、「スクロール」イベントを発生させます...しかし、上記の動作はユーザが間違ったセクションにスクロールされるように思われます。

私はこれを稼働させるために数時間働いていますが、役に立たないものです。ヘルプは大歓迎です!

答えて

0

問題は割り当てprevPosition = ctPositionにあります。

スクロールハンドラを実行するたびに、var ctPosition = $(window).scrollTop();は、しかし、それはないprevPositionとしてrememberadれるべき値をだ、スクロール方向を決定するために良いです。

prevPositionは、アニメーションが完了した後にと測定された$(window).scrollTop()である必要があります。

はこれを試してみてください:

$(document).ready(function() { 
    var ANIMATION_DURATION = 700; 
    var ACTIVE_SECTION = $("section:first-of-type").eq(0); 
    var prevPosition = $(window).scrollTop(); 
    $(window).on("scroll", doScrollingStuff); 

    function doScrollingStuff(e) { 
     $(window).off("scroll"); 

     var ctPosition = $(window).scrollTop(); 
     var nextSection = (ctPosition < prevPosition) ? ACTIVE_SECTION.prev("section") : (ctPosition > prevPosition) ? ACTIVE_SECTION.next("section") : ACTIVE_SECTION; // Determine scroll direction and target the next section 

     // If next section exists and is not current section: Scroll to it! 
     if(nextSection.length > 0 && nextSection !== ACTIVE_SECTION) { 
      $("body, html").animate({ 
       'scrollTop': nextSection.offset().top 
      }, ANIMATION_DURATION).promise().then(function() { 
       // when animation is complete 
       prevPosition = $(window).scrollTop(); // remember remeasured .scrollTop() 
       ACTIVE_SECTION = nextSection; // remember active section 
       $(window).on("scroll", doScrollingStuff); // no need for additional delay after animation 
      }); 
     } else { 
      setTimeout(function() { 
       $(window).on("scroll", doScrollingStuff); 
      }, 100); // Debounce 
     } 
    } 
}); 
+0

は、スクロールホイールを魔法のように動作し、ありがとうございました! ただし、スワイプするとスクロールが途切れます。または、スクロールがアクティブになると、複数のセクションが一度にスクロールされます。 これをどのように修正できますか? 私はタイムアウトの遅延を増やしてみましたが、これは何の効果もありませんでした:/ – Eigen

+0

申し訳ありませんが、私は本当にスワイピングについてよく知らないし、それをテストする手段がありません。 –

+1

Np。これまでのところ、あなたは私をたくさん助けてくれました。 スワイプで動作するようにしようとします:) – Eigen

関連する問題