Ich codiere eine Seite, auf der ich nur rohen JavaScript-Code für die Benutzeroberfläche verwenden möchte, ohne dass Plugins oder Frameworks gestört werden.
Und jetzt habe ich Probleme damit, einen Weg zu finden, wie ich ohne jQuery reibungslos über die Seite scrollen kann.
javascript
html
Paolo Forgia
quelle
quelle
Antworten:
Probieren Sie diese Demo mit reibungslosem Bildlauf oder einen Algorithmus wie den folgenden aus:
self.pageYOffset
element.offsetTop
window.scrollTo
Siehe auch die andere beliebte Antwort auf diese Frage.
Andrew Johnsons Originalcode:
function currentYPosition() { // Firefox, Chrome, Opera, Safari if (self.pageYOffset) return self.pageYOffset; // Internet Explorer 6 - standards mode if (document.documentElement && document.documentElement.scrollTop) return document.documentElement.scrollTop; // Internet Explorer 6, 7 and 8 if (document.body.scrollTop) return document.body.scrollTop; return 0; } function elmYPosition(eID) { var elm = document.getElementById(eID); var y = elm.offsetTop; var node = elm; while (node.offsetParent && node.offsetParent != document.body) { node = node.offsetParent; y += node.offsetTop; } return y; } function smoothScroll(eID) { var startY = currentYPosition(); var stopY = elmYPosition(eID); var distance = stopY > startY ? stopY - startY : startY - stopY; if (distance < 100) { scrollTo(0, stopY); return; } var speed = Math.round(distance / 100); if (speed >= 20) speed = 20; var step = Math.round(distance / 25); var leapY = stopY > startY ? startY + step : startY - step; var timer = 0; if (stopY > startY) { for ( var i=startY; i<stopY; i+=step ) { setTimeout("window.scrollTo(0, "+leapY+")", timer * speed); leapY += step; if (leapY > stopY) leapY = stopY; timer++; } return; } for ( var i=startY; i>stopY; i-=step ) { setTimeout("window.scrollTo(0, "+leapY+")", timer * speed); leapY -= step; if (leapY < stopY) leapY = stopY; timer++; } }
Ähnliche Links:
quelle
Das reibungslose Scrollen des nativen Browsers in JavaScript sieht folgendermaßen aus:
// scroll to specific values, // same as window.scroll() method. // for scrolling a particular distance, use window.scrollBy(). window.scroll({ top: 2500, left: 0, behavior: 'smooth' }); // scroll certain amounts from current position window.scrollBy({ top: 100, // negative value acceptable left: 0, behavior: 'smooth' }); // scroll to a certain element document.querySelector('.hello').scrollIntoView({ behavior: 'smooth' });
quelle
speed
Option. Die aktuelle Bildlaufgeschwindigkeit ist zu langsam für den Fluss.Bearbeiten: Diese Antwort wurde 2013 geschrieben. Bitte überprüfen Sie den Kommentar von Cristian Traìna unten zu requestAnimationFrame
Ich habe es gemacht. Der folgende Code hängt von keinem Framework ab.
Einschränkung: Der aktive Anker ist nicht in die URL geschrieben.
Version des Codes: 1.0 | Github: https://github.com/Yappli/smooth-scroll
(function() // Code in a function to create an isolate scope { var speed = 500; var moving_frequency = 15; // Affects performance ! var links = document.getElementsByTagName('a'); var href; for(var i=0; i<links.length; i++) { href = (links[i].attributes.href === undefined) ? null : links[i].attributes.href.nodeValue.toString(); if(href !== null && href.length > 1 && href.substr(0, 1) == '#') { links[i].onclick = function() { var element; var href = this.attributes.href.nodeValue.toString(); if(element = document.getElementById(href.substr(1))) { var hop_count = speed/moving_frequency var getScrollTopDocumentAtBegin = getScrollTopDocument(); var gap = (getScrollTopElement(element) - getScrollTopDocumentAtBegin) / hop_count; for(var i = 1; i <= hop_count; i++) { (function() { var hop_top_position = gap*i; setTimeout(function(){ window.scrollTo(0, hop_top_position + getScrollTopDocumentAtBegin); }, moving_frequency*i); })(); } } return false; }; } } var getScrollTopElement = function (e) { var top = 0; while (e.offsetParent != undefined && e.offsetParent != null) { top += e.offsetTop + (e.clientTop != null ? e.clientTop : 0); e = e.offsetParent; } return top; }; var getScrollTopDocument = function() { return document.documentElement.scrollTop + document.body.scrollTop; }; })();
quelle
var _updateURL = function ( anchor, url ) { if ( (url === true || url === 'true') && history.pushState ) { history.pushState( {pos:anchor.id}, '', anchor ); } };
( über Chris Fernandis Smooth Scroll js ) in den Verlaufsstapel verschieben , um den Anker in die URL zu schreiben. Schön zu sehen, dass Leute dies tun, anstatt nur "JQuery zu verwenden"! Für die Aufzeichnung sind:target
Selektoren auch eine ordentliche Lösung.Algorithmus
Das Scrollen eines Elements erfordert das Ändern seines
scrollTop
Werts im Laufe der Zeit. Berechnen Sie für einen bestimmten Zeitpunkt einen neuenscrollTop
Wert. Um reibungslos zu animieren, interpolieren Sie mit einem Smooth-Step-Algorithmus .Berechnen Sie
scrollTop
wie folgt:var point = smooth_step(start_time, end_time, now); var scrollTop = Math.round(start_top + (distance * point));
Wo:
start_time
ist die Zeit, zu der die Animation gestartet wurde;end_time
ist, wenn die Animation endet(start_time + duration)
;start_top
ist derscrollTop
Wert am Anfang; unddistance
ist die Differenz zwischen dem gewünschten Endwert und dem Startwert(target - start_top)
.Eine robuste Lösung sollte erkennen, wenn die Animation unterbrochen wird, und vieles mehr. Lesen Sie meinen Beitrag über Smooth Scrolling ohne jQuery für Details.
Demo
Siehe die JSFiddle .
Implementierung
Der Code:
/** Smoothly scroll element to the given target (element.scrollTop) for the given duration Returns a promise that's fulfilled when done, or rejected if interrupted */ var smooth_scroll_to = function(element, target, duration) { target = Math.round(target); duration = Math.round(duration); if (duration < 0) { return Promise.reject("bad duration"); } if (duration === 0) { element.scrollTop = target; return Promise.resolve(); } var start_time = Date.now(); var end_time = start_time + duration; var start_top = element.scrollTop; var distance = target - start_top; // based on http://en.wikipedia.org/wiki/Smoothstep var smooth_step = function(start, end, point) { if(point <= start) { return 0; } if(point >= end) { return 1; } var x = (point - start) / (end - start); // interpolation return x*x*(3 - 2*x); } return new Promise(function(resolve, reject) { // This is to keep track of where the element's scrollTop is // supposed to be, based on what we're doing var previous_top = element.scrollTop; // This is like a think function from a game loop var scroll_frame = function() { if(element.scrollTop != previous_top) { reject("interrupted"); return; } // set the scrollTop for this frame var now = Date.now(); var point = smooth_step(start_time, end_time, now); var frameTop = Math.round(start_top + (distance * point)); element.scrollTop = frameTop; // check if we're done! if(now >= end_time) { resolve(); return; } // If we were supposed to scroll but didn't, then we // probably hit the limit, so consider it done; not // interrupted. if(element.scrollTop === previous_top && element.scrollTop !== frameTop) { resolve(); return; } previous_top = element.scrollTop; // schedule next frame for execution setTimeout(scroll_frame, 0); } // boostrap the animation process setTimeout(scroll_frame, 0); }); }
quelle
pageYOffset
undscrollTo()
weiterelement
stattscrollTop
.Ich habe hier ein Beispiel ohne jQuery gemacht: http://codepen.io/sorinnn/pen/ovzdq
/** by Nemes Ioan Sorin - not an jQuery big fan therefore this script is for those who love the old clean coding style @id = the id of the element who need to bring into view Note : this demo scrolls about 12.700 pixels from Link1 to Link3 */ (function() { window.setTimeout = window.setTimeout; // })(); var smoothScr = { iterr : 30, // set timeout miliseconds ..decreased with 1ms for each iteration tm : null, //timeout local variable stopShow: function() { clearTimeout(this.tm); // stopp the timeout this.iterr = 30; // reset milisec iterator to original value }, getRealTop : function (el) // helper function instead of jQuery { var elm = el; var realTop = 0; do { realTop += elm.offsetTop; elm = elm.offsetParent; } while(elm); return realTop; }, getPageScroll : function() // helper function instead of jQuery { var pgYoff = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop; return pgYoff; }, anim : function (id) // the main func { this.stopShow(); // for click on another button or link var eOff, pOff, tOff, scrVal, pos, dir, step; eOff = document.getElementById(id).offsetTop; // element offsetTop tOff = this.getRealTop(document.getElementById(id).parentNode); // terminus point pOff = this.getPageScroll(); // page offsetTop if (pOff === null || isNaN(pOff) || pOff === 'undefined') pOff = 0; scrVal = eOff - pOff; // actual scroll value; if (scrVal > tOff) { pos = (eOff - tOff - pOff); dir = 1; } if (scrVal < tOff) { pos = (pOff + tOff) - eOff; dir = -1; } if(scrVal !== tOff) { step = ~~((pos / 4) +1) * dir; if(this.iterr > 1) this.iterr -= 1; else this.itter = 0; // decrease the timeout timer value but not below 0 window.scrollBy(0, step); this.tm = window.setTimeout(function() { smoothScr.anim(id); }, this.iterr); } if(scrVal === tOff) { this.stopShow(); // reset function values return; } } }
quelle
window.setTimeout = window.setTimeout;
Moderne Browser unterstützen die CSS-Eigenschaft "Bildlaufverhalten: glatt". Wir brauchen dafür also überhaupt kein Javascript. Fügen Sie dies einfach dem Körperelement hinzu und verwenden Sie die üblichen Anker und Verbindungen. MDN-Dokumente mit Bildlaufverhalten
quelle
Ich habe mich kürzlich vorgenommen, dieses Problem in einer Situation zu lösen, in der jQuery keine Option war. Deshalb protokolliere ich meine Lösung hier nur für die Nachwelt.
var scroll = (function() { var elementPosition = function(a) { return function() { return a.getBoundingClientRect().top; }; }; var scrolling = function( elementID ) { var el = document.getElementById( elementID ), elPos = elementPosition( el ), duration = 400, increment = Math.round( Math.abs( elPos() )/40 ), time = Math.round( duration/increment ), prev = 0, E; function scroller() { E = elPos(); if (E === prev) { return; } else { prev = E; } increment = (E > -20 && E < 20) ? ((E > - 5 && E < 5) ? 1 : 5) : increment; if (E > 1 || E < -1) { if (E < 0) { window.scrollBy( 0,-increment ); } else { window.scrollBy( 0,increment ); } setTimeout(scroller, time); } else { el.scrollTo( 0,0 ); } } scroller(); }; return { To: scrolling } })(); /* usage */ scroll.To('elementID');
Die
scroll()
Funktion verwendet das Revealing Module Pattern , um die ID des Zielelements an seinescrolling()
Funktion zu übergeben, überscroll.To('id')
die die von derscroller()
Funktion verwendeten Werte festgelegt werden .Nervenzusammenbruch
In
scrolling()
:el
: das Ziel-DOM-ObjektelPos
: gibt eine Funktion zurück, überelememtPosition()
die bei jedem Aufruf die Position des Zielelements relativ zum oberen Rand der Seite angegeben wird.duration
: Übergangszeit in Millisekunden.increment
: unterteilt die Startposition des Zielelements in 40 Schritte.time
: Legt das Timing für jeden Schritt fest.prev
: die vorherige Position des Zielelements inscroller()
.E
: hält die Position des Zielelements inscroller()
.Die eigentliche Arbeit erledigt die
scroller()
Funktion, die sich weiterhin (viasetTimeout()
) aufruft, bis sich das Zielelement oben auf der Seite befindet oder die Seite nicht mehr scrollen kann.Bei jedem
scroller()
Aufruf wird die aktuelle Position des Zielelements (in Variable gehaltenE
) überprüft. Wenn dies> 1
OR ist< -1
und die Seite noch scrollbar ist, wird das Fenster umincrement
Pixel verschoben - nach oben oder unten, je nachdem, obE
es sich um einen positiven oder einen negativen Wert handelt. WennE
weder> 1
ODER< -1
nochE
=== ist , stopptprev
die Funktion. Ich habe dieDOMElement.scrollTo()
Methode nach Abschluss hinzugefügt , um sicherzustellen, dass das Zielelement oben im Fenster angezeigt wird (nicht, dass Sie bemerken würden, dass es um einen Bruchteil eines Pixels entfernt ist!).Die
if
Anweisung in Zeile 2 vonscroller()
prüft, ob die Seite gescrollt wird (in Fällen, in denen sich das Ziel möglicherweise am unteren Rand der Seite befindet und die Seite nicht weiter scrollen kann), indem sie mitE
ihrer vorherigen Position verglichen wird (prev
).Die darunter liegende ternäre Bedingung verringert den
increment
Wert, wenn erE
sich Null nähert. Dies verhindert, dass die Seite in eine Richtung überschießt und dann zurückspringt, um die andere zu überschießen, und dann zurückspringt, um die andere wieder zu überschießen, im Ping-Pong-Stil, bis ins Unendliche und darüber hinaus.Wenn Ihre Seite mehr als ca. 4000 Pixel hoch ist, möchten Sie möglicherweise die Werte in der ersten Bedingung des ternären Ausdrucks (hier bei +/- 20) und / oder im Divisor, der den
increment
Wert festlegt (hier bei 40) , erhöhen .Wenn Sie mit
duration
dem Divisor spielen, der festgelegt wirdincrement
, und den Werten im ternären Zustand vonscroller()
sollten Sie die Funktion an Ihre Seite anpassen können .JSFiddle
NBTest in aktuellen Versionen von Firefox und Chrome unter Lubuntu sowie Firefox, Chrome und IE unter Windows8.
quelle
Sie können auch die Scroll Behaviour- Eigenschaft verwenden. Fügen Sie beispielsweise die folgende Zeile zu Ihrem CSS hinzu
html{ scroll-behavior:smooth; }
Dies führt zu einer nativen Funktion zum reibungslosen Scrollen. Lesen Sie mehr über das Bildlaufverhalten
quelle
Ich habe so etwas gemacht. Ich habe keine Ahnung, ob es in IE8 funktioniert. Getestet in IE9, Mozilla, Chrome, Edge.
function scroll(toElement, speed) { var windowObject = window; var windowPos = windowObject.pageYOffset; var pointer = toElement.getAttribute('href').slice(1); var elem = document.getElementById(pointer); var elemOffset = elem.offsetTop; var counter = setInterval(function() { windowPos; if (windowPos > elemOffset) { // from bottom to top windowObject.scrollTo(0, windowPos); windowPos -= speed; if (windowPos <= elemOffset) { // scrolling until elemOffset is higher than scrollbar position, cancel interval and set scrollbar to element position clearInterval(counter); windowObject.scrollTo(0, elemOffset); } } else { // from top to bottom windowObject.scrollTo(0, windowPos); windowPos += speed; if (windowPos >= elemOffset) { // scroll until scrollbar is lower than element, cancel interval and set scrollbar to element position clearInterval(counter); windowObject.scrollTo(0, elemOffset); } } }, 1); } //call example var navPointer = document.getElementsByClassName('nav__anchor'); for (i = 0; i < navPointer.length; i++) { navPointer[i].addEventListener('click', function(e) { scroll(this, 18); e.preventDefault(); }); }
Beschreibung
pointer
- Element und chceck abrufen, wenn es das Attribut "href" hat. Wenn ja, "#" entfernenelem
- Zeigervariable ohne "#"elemOffset
- Versatz des Elements "Scrollen zu" oben auf der Seitequelle
Sie können verwenden
document.querySelector('your-element').scrollIntoView({behavior: 'smooth'});
Wenn Sie oben auf der Seite scrollen möchten, können Sie einfach ein leeres Element oben platzieren und sanft zu diesem Element scrollen.
quelle
Sie können eine for-Schleife mit window.scrollTo und setTimeout verwenden, um mit einfachem Javascript reibungslos zu scrollen. So scrollen Sie mit meiner
scrollToSmoothly
Funktion zu einem Element :scrollToSmoothly(elem.offsetTop)
(vorausgesetzt, eselem
handelt sich um ein DOM-Element). Sie können dies verwenden, um reibungslos zu einer beliebigen y-Position im Dokument zu scrollen.function scrollToSmoothly(pos, time){ /*Time is only applicable for scrolling upwards*/ /*Code written by hev1*/ /*pos is the y-position to scroll to (in pixels)*/ if(isNaN(pos)){ throw "Position must be a number"; } if(pos<0){ throw "Position can not be negative"; } var currentPos = window.scrollY||window.screenTop; if(currentPos<pos){ var t = 10; for(let i = currentPos; i <= pos; i+=10){ t+=10; setTimeout(function(){ window.scrollTo(0, i); }, t/2); } } else { time = time || 2; var i = currentPos; var x; x = setInterval(function(){ window.scrollTo(0, i); i -= 10; if(i<=pos){ clearInterval(x); } }, time); } }
Demo:
Code-Snippet anzeigen
<button onClick="scrollToDiv()">Scroll To Element</button> <div style="margin: 1000px 0px; text-align: center;">Div element<p/> <button onClick="scrollToSmoothly(Number(0))">Scroll back to top</button> </div> <script> function scrollToSmoothly(pos, time){ /*Time is only applicable for scrolling upwards*/ /*Code written by hev1*/ /*pos is the y-position to scroll to (in pixels)*/ if(isNaN(pos)){ throw "Position must be a number"; } if(pos<0){ throw "Position can not be negative"; } var currentPos = window.scrollY||window.screenTop; if(currentPos<pos){ var t = 10; for(let i = currentPos; i <= pos; i+=10){ t+=10; setTimeout(function(){ window.scrollTo(0, i); }, t/2); } } else { time = time || 2; var i = currentPos; var x; x = setInterval(function(){ window.scrollTo(0, i); i -= 10; if(i<=pos){ clearInterval(x); } }, time); } } function scrollToDiv(){ var elem = document.querySelector("div"); scrollToSmoothly(elem.offsetTop); } </script>
quelle
<script> var set = 0; function animatescroll(x, y) { if (set == 0) { var val72 = 0; var val73 = 0; var setin = 0; set = 1; var interval = setInterval(function() { if (setin == 0) { val72++; val73 += x / 1000; if (val72 == 1000) { val73 = 0; interval = clearInterval(interval); } document.getElementById(y).scrollTop = val73; } }, 1); } } </script>
x = scrollTop
y = ID des Div, mit dem gescrollt wird
Hinweis: Geben Sie dem Body eine ID, damit der Körper gescrollt wird .
quelle
Hier ist meine Lösung. Funktioniert in den meisten Browsern
document.getElementById("scrollHere").scrollIntoView({behavior: "smooth"});
Docs
document.getElementById("end").scrollIntoView({behavior: "smooth"});
body {margin: 0px; display: block; height: 100%; background-image: linear-gradient(red, yellow);} .start {display: block; margin: 100px 10px 1000px 0px;} .end {display: block; margin: 0px 0px 100px 0px;}
<div class="start">Start</div> <div class="end" id="end">End</div>
quelle
Mit der folgenden Funktion funktioniert das reibungslose Scrollen einwandfrei:
quelle
Hier ist der Code, der für mich funktioniert hat.
`$('a[href*="#"]') .not('[href="#"]') .not('[href="#0"]') .click(function(event) { if ( location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname ) { var target = $(this.hash); target = target.length ? target : $('[name=' + this.hash.slice(1) + ']'); if (target.length) { event.preventDefault(); $('html, body').animate({ scrollTop: target.offset().top }, 1000, function() { var $target = $(target); $target.focus(); if ($target.is(":focus")) { return false; } else { $target.attr('tabindex','-1'); $target.focus(); }; }); } } });
`
quelle