2016-08-06 6 views
1

Ich möchte Abschnitte in einem Div fangen, aber ich möchte dies ohne das Fenster Scrollen tun. Ich möchte in der Lage sein, innerhalb dieses div zu scrollen.Fangen an Abschnitte ohne Fenster Scrollen

Ich glaube nicht, dass ich mich gut genug erkläre. Wenn ich scrolle, scrollt das Fenster, dann wird der Artikel an Ort und Stelle eingerastet, und so weiter. Ich möchte, dass es so ist, dass, wenn ich innerhalb von #content blättern werde, der Artikel in Position gerastet wird.

Irgendwelche Vorschläge?

$(document).ready(function() { 
    $("article").css("height", $(window).height() + "px"); 
    $("#content").sectionsnap({ 
    delay : 100 
    , selector : 'article' 
    , reference : 1 
    , animationTime : 600 
    }); 
}); 


(function($) { 
$.fn.sectionsnap = function(options) { 

    var $wrapper = this 
    , direction = 'down' 
    , currentScrollTop = $("section").scrollTop() 
    , scrollTimer 
    , animating = false; 

    // check the direction 
    var updateDirection = function() { 
     if ($("section").scrollTop() >= currentScrollTop) 
      direction = 'down'; 
     else 
      direction = 'up'; 
     currentScrollTop = $("section").scrollTop(); 
    } 

    // return the closest element (depending on direction) 
    var getClosestElement = function() { 
     var $list = $wrapper.find(settings.selector) 
     , wt = $("section").scrollTop() 
     , wh = $("section").height() 
     , refY = wh * settings.reference 
     , wtd = wt + refY - 1 
     , $target; 

     if (direction == 'down') { 
      $list.each(function() { 
       var st = $(this).position().top; 
       if ((st > wt) && (st <= wtd)) { 
        $target = $(this); 
        return false; // just to break the each loop 
       } 
      }); 
     } else { 
      wtd = wt - refY + 1; 
      $list.each(function() { 
       var st = $(this).position().top; 
       if ((st < wt) && (st >= wtd)) { 
        $target = $(this); 
        return false; // just to break the each loop 
       } 
      }); 
     } 
     return $target; 
    } 

    // snap 
    var snap = function() { 
     var $target = getClosestElement(); 
     if ($target) { 
      animating = true; 
      $('html, body').animate({ 
        scrollTop: ($target.offset().top) 
       }, settings.animationTime, function() { 
        window.clearTimeout(scrollTimer); 
        animating = false; 
       }); 
     } 
    } 
    // on window scroll 
    $("section").scroll(windowScroll); 
    return this; 
}; 
})(jQuery); 

irgendwelche Vorschläge sind sehr geschätzt

+0

Ich bin damit einverstanden, dass Sie diese gut genug – sheriffderek

+0

http nicht zu erklären sind: // kuhl.pl/github/sectionsnap/Wenn das Fenster scrollt, wird sofort das nächste Element angezeigt. Ich möchte es so machen, dass, wenn der Abschnitt (nicht das Fenster) scrollt, das nächste Element in Sicht kommt. Klärt das? – user1377298

Antwort

2
  1. Verwenden animate() Funktion statt scrollTop() die Animation statt sofort Schnappen Abschnitt von Abschnitt zu haben.

  2. Betrachten wir für einen reibungslosen und nicht-lineare Animation mit Lockerung, wenn Sie jQuery zu tun Animation verwenden werden Sie diese jQuery easing plugin verwenden - [CDN]

  3. Für eine noch flüssigere Animation Sie anderen Bibliotheken verwenden können, wie GSAP oder Velocityjs, beide verfügen über eine integrierte Beschleunigungsfunktion, sodass Sie keine externen Pakete dafür verwenden müssen.

  4. Es ist wichtig, eine Flagge zu machen, meinen Code genannt isScrolling in, zu prüfen, ob zur Zeit die Seite wir uns nicht vergleichen tun wird Scrollen sollte den .scrollTop() Wert auf den aktuellen Abschnitt .offset().topbis Animation endet Scrollen, wir über dann starten .


Beispiel 1: mit jQuery .animate() Funktion mit Lockerung

jsFiddle - editor

jsFiddle - fullscreen

var sections = $('.sections'), 
 
    win = $(window), 
 
    index = 0, 
 
    isScrolling = false; // will be used to check whether the page is scrolling or not 
 

 

 
// on window scroll, we capture the scroll top and the current section's top 
 
win.on('scroll', function() { 
 
    var winTop = win.scrollTop(), 
 
    secTop = $(sections[index]).offset().top; 
 

 
    // if page is currently scrolling, we do nothing and wait until scrolling ends 
 
    if (!isScrolling) { 
 

 
    // if is scrolling is false, and window ".scrollTop()" is more than current 
 
    // section ".offset().top" value, we set the "isScrolling" to true so that 
 
    // we make any scrolling decisions until the animation ends, call the animation 
 
    // function passing the value of the next next section's ".offset().top", also 
 
    // increase the "index" value. 
 
    if (winTop > secTop) { 
 
     isScrolling = true; 
 
     animateScrolling($(sections[index + 1]).offset().top); 
 
     index += 1; 
 
    } 
 

 
    // same as above except we check if the window ".scrollTop()" is *less* than 
 
    // the current section's "scrollTop()", set "isScrolling = false" and animate the 
 
    // scroll to the previous section's "offset().top", and decrease the index value. 
 
    if (winTop < secTop) { 
 
     isScrolling = 1; 
 
     animateScrolling($(sections[index - 1]).offset().top); 
 
     index -= 1; 
 
    } 
 
    } 
 
}); 
 

 

 
// instead of "win.scrollTop()" we use ".animate()" function for smooth scrolling and 
 
// making use of a the callback function, which get executed *after* the animation 
 
// ends, we set our scrolling flag "isScrolling" to false for further animations. 
 
    // we use easing too, "easeInOutCubic" here, for smooth animation 
 

 
function animateScrolling(secTop) { 
 
    $('html, body').animate({ scrollTop: secTop }, 500, 'easeInOutCubic', function() { 
 
    isScrolling = false; 
 
    }); 
 
}
body { margin: 0; padding: 0; } 
 
.sections { width: 100%; height: 100vh; background-color: orange; display: block; } 
 
.two { background-color: tomato; } 
 
.three { background-color: skyblue; }
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js"> 
 
</script> 
 
<div class="sections"></div> 
 
<div class="sections two"></div> 
 
<div class="sections three"></div>


Beispiel 2: mit GSAP TweenMax Funktion mit builtin Lockerung Obwohl GSAP sehr gut mit jQuery arbeitet, unter ich reine Javascript verwenden für Elemente anstelle von jQuery auswählen.

CodePen - editor

CodePen - fullscreen

var sections = document.querySelectorAll('.sections'), 
    HTMLbody = document.querySelectorAll('html, body'), 
    index = 0, 
    isScrolling = false; 

window.addEventListener('scroll', function() { 
    // Get the window scrollTop value, from: 
    // stackoverflow.com/questions/3464876/javascript-get-window-x-y-position-for-scroll 
    var winTop = (window.pageYOffset || document.scrollTop) - (document.clientTop || 0), 
    // --------------------------------------------------------------------------------- 
    secTop = sections[index].offsetTop; 

    if (!isScrolling) { 
    if (winTop > secTop) { 
     isScrolling = true; 
     animateScrolling(sections[index + 1].offsetTop); 
     index += 1; 
    } 
    if (winTop < secTop) { 
     isScrolling = 1; 
     animateScrolling(sections[index - 1].offsetTop); 
     index -= 1; 
    } 
    } 
}); 

function animateScrolling(secTop) { 
    TweenMax.to(HTMLbody, 0.5, { 
    scrollTop: secTop, 
    ease: Power3.easeInOut, 
    onComplete: setFlagToFalse 
    }); 
} 

function setFlagToFalse() { 
    isScrolling = false; 
} 
+0

danke für den Vorschlag, aber das Scrollen ist nicht sehr glatt, und es wird nicht reibungslos zum nächsten Abschnitt. Vielen Dank, obwohl – user1377298

+0

@ user1377298, tut mir leid, dass nicht wirklich versucht, die Bibliothek nachzuahmen, die Sie seinen Link zur Verfügung gestellt, es war eher wie Richtlinien, die ich sogar nicht erleichtert. –

+0

Wie auch immer, schauen Sie sich meine aktualisierte Antwort, reibungslose Scrolling und mit Easing, Suche nach Fenster scrollen, auch ich eine andere Lösung mit GSAP-Animation statt jQuery-Animation. –