CSS scroll-snap scroll event stop and element position detection implementation

CSS scroll-snap scroll event stop and element position detection implementation

1. Scroll Snap is a must-have skill for front-end developers

CSS Scroll Snap is a very useful feature that allows the browser to automatically and smoothly locate to the specified position of the specified element when the web page container stops scrolling without the involvement of any JS code. Effects similar to slideshow advertising can be achieved with pure CSS.

Moreover, CSS Scroll Snap has excellent compatibility and can be used almost safely on mobile devices.

2. Scroll-snap scenarios from actual projects

This afternoon, when I was implementing a functional requirement, I happened to encounter a scenario that was very suitable for using Scroll Snap to implement it, sliding to display the characters in sequence. So I used it boldly, wow, it’s great, no need for any js to do boundary judgment, it will automatically position to the desired position when sliding stops.

The key CSS codes are as follows:

ul {
    width: 375px; height: 667px;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
    overflow-y: hidden;    
}
li {
    display: inline-block;
    width: 100%; height: 100%;
    scroll-snap-align: center;
}

Set scroll-snap-type:x mandatory the scrolling parent container element, scroll horizontally, and force positioning. Set scroll-snap-align:center for the child list element to make the list appear in the middle of the scrolling container, so the effect is achieved.

However, after the scrolling positioning is completed, it is still necessary to highlight the currently positioned character material. I found this a bit difficult!

In the past, this sliding effect was implemented using JS. Whether the JS animation ended or the CSS animation ended, there was a callback function that could be used. But here it is rolling, and after rolling it will position itself for a while. The time of self-positioning varies. Who knows when it will stop? Sometimes you slide multiple elements at once and you're not sure which element to stop on.

In fact, standard setters and browser manufacturers are actively promoting the implementation of Scroll Snap related callback events, so that we can know exactly when the scrolling stops and which element the scrolling is positioned on. However, the standard is still under development and browsers do not support it yet. The project needs to be used now, what should I do?

right! JS assistance must be used.

In fact, even if it is not the usage scenario of Scroll Snap, even if it is ordinary scrolling, due to the inertia of scrolling, detecting whether the scrolling has stopped is also a common requirement. Therefore, it is necessary to come up with a method to detect when the scrolling stops.

3. My scrolling suspension detection method

To detect whether the scrolling of an element has stopped, my implementation idea is to run a timer in the scrolling event to record whether the scrolling distance at the current time is equal to the distance of the previous scrolling. If they are equal, it is considered that the scrolling has stopped. If they are not equal, it is considered that the scrolling is still in progress.

The JavaScript representation is ( this implementation is deprecated ):

// Timer, used to detect whether horizontal scrolling has ended var timer = null;
// The last scroll distance var scrollLeft = 0, scrollTop = 0;
// Scroll event starts container.addEventListener('scroll', function () {
    clearInterval(timer);
    // Reset the timer timer = setInterval(function () {
        if (container.scrollLeft == scrollLeft && container.scrollTop == scrollTop) {
            // When the scrolling distance is equal, it is considered that the scrolling has stopped clearInterval(timer);
            // ... do whatever you want, such as callback processing } else {
            // Otherwise, still remember the last scroll position scrollLeft = container.scrollLeft;
            scrollTop = container.scrollTop;
        }
    }, 100);
});

If you are interested, you can further encapsulate the above code.

Updated on the next day

Scroll termination detection does not need to determine whether the previous and next scrolling distances are equal, because both inertial and Snap positioning scroll events are continuously triggered. Therefore, it is possible to directly:

// Timer, used to detect whether horizontal scrolling has ended var timer = null;
// Scroll event starts container.addEventListener('scroll', function () {
    clearTimeout(timer);
    // Reset the timer timer = setTimeout(function () {
        // No scroll event is triggered, so scrolling is considered stopped // ... do what you want to do, such as callback processing }, 100);
});

Of course, the method provided above is not a very accurate termination detection, because the browser itself has a detection for the final repositioning of Scroll Snap. According to my repeated research and tests, this detection event should be 350ms (the actual operation may be slightly larger by a few milliseconds), which is much larger than 100ms set above. Therefore, there will be an erroneous redundant judgment that occurs before the Snap positioning starts.

I thought about it and realized that this problem is unavoidable, but it is not a big problem. It is impossible to set the detection time to 400ms . The delay is too high and the experience may not be good.

4. Current scroll target element detection method

The principle is as follows, iterate over all list elements and detect the position of the left edge of the list element relative to the left edge of the scroll container (if it is left-aligned - scroll-snap-align:left ) or the center (center alignment) or the right edge (right alignment). Of course, if the list element size is consistent with the scroll container size, left, center, and right edge detection are both acceptable.

JS indicates:

[].slice.call(container.children).forEach(function (ele, index) {
    if (Math.abs(ele.getBoundingClientRect().left - container.getBoundingClientRect().left) < 10) {
        // The ele element at this moment is the currently positioned element // ... you can do what you want with ele } else {
        // The ele element at this moment is not the currently positioned element}
});

Strictly speaking, we should calculate whether it is equal to 0 , not less than 10 Here, we add a tolerance interval.

After solving the above two requirements that require JS assistance, the final effect is achieved.

The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM.

<<:  How to connect Navicat to the docker database on the server

>>:  How to implement CSS to display ellipsis when single-line or multi-line text overflows

Recommend

Introduction to Javascript DOM, nodes and element acquisition

Table of contents DOM node Element node: Text nod...

The principle and direction of JavaScript this

How to determine what this points to? ①When calle...

How to set up vscode remote connection to server docker container

Table of contents Pull the image Run the image (g...

Example of converting spark rdd to dataframe and writing it into mysql

Dataframe is a new API introduced in Spark 1.3.0,...

Sample code for automatic web page refresh and automatic jump

Automatic web page refresh: Add the following code...

Detailed explanation of how to adjust Linux command history

The bash history command in Linux system helps to...

Summary of Linux command methods to view used commands

There are many commands used in the system, so ho...

Basic introductory tutorial on MySQL partition tables

Preface In a recent project, we need to save a la...

Element table header row height problem solution

Table of contents Preface 1. Cause of the problem...

How to use mysqladmin to get the current TPS and QPS of a MySQL instance

mysqladmin is an official mysql client program th...

Solutions to browser interpretation differences in size and width and height in CSS

Let’s look at an example first Copy code The code ...

How to install nginx in centos7

Install the required environment 1. gcc installat...

Detailed explanation of how to create an array in JavaScript

Table of contents Creating Arrays in JavaScript U...

A detailed guide to custom directives in Vue

Table of contents 1. What is a custom instruction...