preface
In practical applications, scrolling to the top of the page or a location is often used. Generally, simply use anchor points or js to set document.body.scrollTop to 0. The result is that the page flashes and rolls to the specified location. What we want is a little bit of buffering.
Modern browsers are increasingly aware of this need. ScrollIntoView means to scroll to the visual, CSS provides the scroll behavior property, and JS has the element.scrollintoView () method.
scroll-behavior
Scroll – behaviors attribute value for auto | smooth | inherit | unset
scroll-behavior: smooth; It’s the cushioning we want. On PC browsers, the default page scroll is on the < HTML > tag, and on mobile most scroll on the tag. If we want to smooth “back to the top”, simply add:
html.body {
scroll-behavior: smooth;
}
Copy the code
Specifically, writing on the container element smoothen the scrolling of the container (not triggered by mouse gestures) beyond the < HTML >, tags.
Using this CSS property, you can switch the original pure CSS tags in one step to a smooth transition effect.
.tab label {
padding: 10px;
border: 1px solid #ccc;
margin-right: -1px;
text-align: center;
float: left;
overflow: hidden;
}
.tab::after {
content: "";
display: table;
clear: both;
}
.box {
height: 200px;
border: 1px solid #ccc;
scroll-behavior: smooth;
overflow: hidden;
margin-top: 10px;
}
.item {
height: 100%;
position: relative;
overflow: hidden;
}
.item input {
position: absolute;
top: 0;
height: 100%;
width: 1px;
border: 0;
padding: 0;
margin: 0;
clip: rect(0 0 0 0);
}
Copy the code
<h1>Pure CSS TAB</h1>
<div class="tab">
<label for="tab1">TAB 1</label>
<label for="tab2">TAB 2</label>
<label for="tab3">TAB. 3</label>
</div>
<div class="box">
<div class="item">
<input type="text" id="tab1">
<p>TAB 1 content</p>
</div>
<div class="item">
<input type="text" id="tab2">
<p>TAB 2 content</p>
</div>
<div class="item">
<input type="text" id="tab3">
<p>TAB 3 content</p>
</div>
</div>
Copy the code
Implementation effect
You can also poke here
Let’s take a look at the CSS property Scroll behavior support in major browsers
The support is not very good, so a line of CSS code can be applied to the best of course, not degenerate into a flash effect. Now take a look at the API provided by JS.
Element.scrollIntoView()
The element.scrollintoView () method scrolls the current Element into the viewable area of the browser window.
element.scrollIntoView(); // Equivalent to element.scrollinToView (true)
element.scrollIntoView(alignToTop); // Boolean element. ScrollIntoView (scrollIntoViewOptions); // Object parameters
Parameter alignToTop
A Boolean value:
- If it is
true
The top of the element will be aligned with the top of the visible area of the scroll area in which it is located. The correspondingscrollIntoViewOptions: {block: "start", inline: "nearest"}
. This is the default value for this parameter. - If it is
false
The bottom of the element will be aligned with the bottom of the visible area of the scroll area in which it is located. The correspondingscrollIntoViewOptions: {block: "end", inline: "nearest"}
.
Parameter scrollIntoViewOptions
An object with options:
{
behavior: "auto" | "instant" | "smooth".block: "start" | "end",}Copy the code
-
Behavior optionally defines one of the slow animations, “auto”, “instant”, or “smooth”. The default is “auto”.
-
Block can be one of “start”, “Center “, “end”, or “nearest”. The default is “Center”.
-
Inline can be one of “start”, “Center “, “end”, or “nearest”. The default is “nearest”.
Browser support
We can also use CSS to set scroll behavior: smooth; Scroll effect, use target.scrollintoView () when performing the scroll to achieve the “perfect scroll” (not so perfect) effect.
Backwards compatible
In order to achieve the same (similar) effect for all browsers, it is necessary to find out the remaining browsers that do not support the Scroll behavior property and use JS to complete the mission.
Determine whether support is supportedscroll-behavior
attribute
Very simple, with the following line of code
if(typeof window.getComputedStyle(document.body).scrollBehavior === 'undefined') {
// Compatible with js code
} else {
// Native scroll API
// Element.scrollIntoView()
}
Copy the code
Check whether the scroll behavior property is supported and use the native element.scrollintoView () to scroll directly; otherwise, it is processed backwards.
Buffer algorithm
The intuitive effect of buffering is to go slower and slower until you stop, that is, moving less and less distance in the same amount of time. This allows you to set a timer that moves to the buffer rate of the distance from the current point to the target point (e.g. 1/2, 1/3…). For example, if the buffer rate is set to 2, the current distance from the target point is 64px, the next second is 32px, then 16px, then 8px… , reaches a certain threshold, namely:
var position = position + (destination - position) / n;
Copy the code
Here’s a simple demo where you click the “back to top” button in the lower right and scroll to the top.
<div class="content">
<p>A lot of content...</p>.</div>
<section class="back-to-top">Back to the top</section>
Copy the code
.content {
height: 3000px;
border: 1px solid #ccc;
box-shadow: 0 0 2px solid;
}
.back-to-top {
width: 18px;
padding: 10px;
border: 1px solid #ccc;
box-shadow: 0 0 2px # 333;
position: fixed;
right: 20px;
bottom: 40px;
}
.back-to-top:hover {
cursor: pointer;
}
Copy the code
var scrollTopSmooth = function (position) {
// There is no native 'requestAnimationFrame', use 'setTimeout' simulation instead
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function (cb) {
return setTimeout(cb, 17);
};
}
// The current scrolling height
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
// step
var step = function () {
var distance = position - scrollTop;
scrollTop = scrollTop + distance / 5;
if (Math.abs(distance) < 1) {
window.scrollTo(0, position);
} else {
window.scrollTo(0, scrollTop); requestAnimationFrame(step); }}; step(); } $backToTop =document.querySelector('.back-to-top')
$backToTop.addEventListener('click'.function () {
scrollTopSmooth(0);
}, false);
</script>
Copy the code
rendering
Or poke here
Simple packaging
In the small demo above, the buffering algorithm is coupled with the current rolling business code, so let’s separate out a single function.
/** * buffer function *@param {Number} Position Current scroll position *@param {Number} Destination Indicates the destination location *@param {Number} Rate Slow rate *@param {Function} The current position of the callback function and whether to end */
var easeout = function (position, destination, rate, callback) {
if (position === destination || typeofdestination ! = ='number') {
return false;
}
destination = destination || 0;
rate = rate || 2;
// There is no native 'requestAnimationFrame', use 'setTimeout' simulation instead
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function (fn) {
return setTimeout(fn, 17); }}var step = function () {
position = position + (destination - position) / rate;
if (position < 1) {
callback(destination, true);
return;
}
callback(position, false);
requestAnimationFrame(step);
};
step();
}
Copy the code
After splitting, the small buffer algorithm can be called repeatedly, and is applicable to scrolling to the specified position (not just to the top) and buffer rate (to control scrolling speed).
var scrollTopSmooth = function (position) {
// The current scrolling height
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
easeout(scrollTop, 0.5.function (val) {
window.scrollTo(0, val);
});
}
$backToTop = document.querySelector('.back-to-top')
$backToTop.addEventListener('click'.function () {
scrollTopSmooth(0);
}, false);
Copy the code
conclusion
In summary, a simple implementation of a perfect scroll can be noted below
<html>
.<body>
Tag along withscroll-behavior: smooth;
Properties;- Check whether the current browser supports it
scrollBehavior
Properties; - Use the native scroll API directly if supported
Element.scrollIntoView()
; - If not, use JS small buffer algorithm for compatibility processing.
The ~