Detailed explanation of scroll bar scrolling control of DOM elements in HTML

Detailed explanation of scroll bar scrolling control of DOM elements in HTML

I don't know if you have ever encountered such a requirement, adding a new child element to a dom element, and then requiring that if the newly added new element exceeds the scope of the container, then we need to automatically scroll to the position of the newly added child element, as shown in the following figure:

Next, we will learn some knowledge points related to dom element scrolling while realizing the effect shown in the above picture and some other scrolling-related functions.

DOM properties and methods that need to be understood: scrollTop, clientHeight, and scrollHeight

scrollTop attribute is a value that describes the difference between the top value of the container element content and top value of the container element ( viewport ), that is, the part of the container that exceeds the container viewport after the content in the container slides up. You can control the scroll state by modifying this property.

clientHeight is a dom property that describes the height of the container.

scrollHeight is a dom property that describes the height of the container content.

The relationship between the three attributes is shown in the following figure:

getBoundingClientRect()

This method is used to obtain some geometric properties required for element layout, such as left , right , top , bottom , height , width , etc.

srollBy(x,y)

The scrollTo method of dom container can be used to directly control the scroll bar to scroll a specified distance. This method is convenient when you need to scroll to a specific element.

srollTo(x,y)

The scrollTo method of dom container can be used to directly control the scroll bar to scroll to the specified position. It is convenient to use this method when controlling the scroll bar to scroll to the top or bottom.

Implementing rolling control preparation

Let's prepare an html first

<!DOCTYPE html>
<html>
    <head>
       <title>Detailed explanation of scroll bar settings</title>
       <style>
          #scroll_container{
              height: 500px;
              width: 500px;
              overflow-y: scroll;
              padding: 50px;
              box-sizing: border-box;
          }
          .scroll_item{
              height: 200px;
              width: 500px;
              margin-top: 20px;
              background-color: aquamarine;
              display: flex;
              align-items: center;
              justify-content: center;
          }
       </style>
    </head>
    <body>
       <div id="scroll_container">
           <div id="scroll_container">
               <div id="item1" class="scroll_item">
                   <span>1</span>
               </div>
               <div id="item2" class="scroll_item">
                    <span>2</span>
                </div>
                <div id="item3" class="scroll_item">
                    <span>3</span>
                </div>
                <div id="item4" class="scroll_item">
                    <span>4</span>
                </div>
                <div id="item5" class="scroll_item">
                    <span>5</span>
                </div> 
           </div>
           <button onclick="addItem()">Add an element</button>
       </div>
    </body>
    <script>
        let container = document.getElementById("scroll_container");
        let index=5;
        //Add an element function addItem(){
            index+=1;
            let item=`<div id="${'item'+index}" class="scroll_item">
                            <span>${index}</span>
                        </div>`;
            container.innerHTML+=item;  
            setTimeout(()=>{
                scrollToIndex();
            })
         }
    </script>
</html>

The above code contains a scrollable area, and you can add elements to the scrolling area, or scroll to the specified element position. The general effect is as shown in the figure below.

Use scrollTop to achieve

Basic Implementation

The meaning of scrollTop has been explained before. We can control the scrolling of the scroll bar by modifying the scrollTop value of the container element. The larger the scrollTop value, the greater the scroll distance of the scroll bar relative to its original state (when scrollTop is 0).

Knowing the meaning of scrollTop , we can use scrollTop to control the scroll bar. Then we first implement a scroll to the bottom implementation and add a scrollToBottom() method to the above code:

function scrollToBottom(){
    let y = container.scrollHeight - container.clientHeight;
    container.scrollTop=y;
}

Correspondingly, if we want to scroll to the top, we only need to set scrollTop to 0:

function scrollToTop(){
    container.scrollTop=0;
} 

Combined with the getBoundingClientRect() method, we can also easily scroll to the specified element, where getBoundingClientRect().top represents the distance between the top of the child element and the top of the parent element's viewport:

function scrollToElement(el){
     container.scrollTop+=el.getBoundingClientRect().top;
}

Add animation

Scroll to bottom

But the scrolling of the above code is too stiff. We can add some animation effect to it, which can be achieved with the help of setInterval() . Let's analyze the process of realizing the animation effect. The realization of animation is nothing more than completing the change of a variable within a certain period of time. Therefore, we first need to know two variables, the offset of the variable ( scrollTop ) and the time required for the change. The offset is the final value of scrollTop minus the original value, and the change duration is generally set as a modifiable parameter. Understanding the above process, let's take scrolling to the bottom as an example:

//First write a scrollToBottom function function scrollToBottom(el){
              if(!el){
                  el=container;
              }
              //Original value let startTop=el.scrollTop;
              //Final value let endTop=el.scrollHeight-el.clientHeight;
              //Generate an animation control function let scrollAnimationFn=doAnimation(startTop,endTop,300,el);
              //Execute the animation every 10ms let interval=setInterval(()=>{
                scrollAnimationFn(interval)
              },10)
 }
/**
 * @description: A factory function that generates animation control functions (using closures)
 * @param {
    startValue: variable original value endValue: variable final value duration: animation duration el: element that performs scrolling animation} 
 * @return: null
 */
function doAnimation(startValue,endValue,duration,el){
              //Use closure to save variables dy and step (the distance each animation scrolls)
              let dy=0;
              let step=(endValue-startValue)/(duration/10);
              //Return animation control function return function(interval){
                  dy+=step;
                  if(dy>=endValue-startValue){
                      clearInterval(interval);
                  }
                  el.scrollTop+=step;
              }
 }

Modify the addItem function to add a scroll to the bottom animation:

function addItem(){
            index+=1;
            let item=`<div id="${'item'+index}" class="scroll_item">
                            <span>${index}</span>
                        </div>`;
            container.innerHTML+=item;  
            setTimeout(()=>{
                // scrollToIndex();
                scrollToBottom(container);
            })
           
 }

Then add a scroll button to the bottom of the HTML:

<button onclick="scrollToBottom()">Scroll to the bottom</button> 

Scroll to top

According to the above method, you can also implement a common animation scrolling to the top:

//Write a scrollToTop function function scrollToTop(el){
              if(!el){
                  el=container;
              }
              //Original value let startTop=el.scrollTop;
              //Final value let endTop=0;
              //Generate an animation control function let scrollAnimationFn=doAnimation(startTop,endTop,300,el);
              //Execute the animation every 10ms let interval=setInterval(()=>{
                scrollAnimationFn(interval)
              },10)
 }

In order to adapt to scrolling to the bottom, we need to modify the timing of the animation stop. The modified doAnimation() function is as follows:

function doAnimation(startValue,endValue,duration,el){
              //Use closure to save variables dy and step (the distance each animation scrolls)
              let dy=0;
              let step=(endValue-startValue)/(duration/10);
              return function(interval){
                  dy+=step;
                  //Change to use absolute value judgment here if(Math.abs(dy)>=Math.abs(endValue-startValue)){
                      clearInterval(interval);
                  }
                  el.scrollTop+=step;
              }
 }

Finally, we add a scroll to bottom button html :

<button onclick="scrollToTop()">Scroll to top</button>

The effect is as follows:

Scroll to the specified element

First, add the required buttons and input boxes to the html element:

<input type="number" placeholder="Please enter the element index to scroll to" style="width: 200px;"/>
<button onclick="scrollToElement()">Scroll to the specified element</button>

Add an animation execution function to scroll the specified element:

function scrollToElement(containerEl,el){
            if(!containerEl){
                //Parent element containerEl=container;
            }
            if(!el){
                //Get the element to scroll to let input=document.getElementsByTagName('input')[0];
                let id='item'+input.value;
                if(!input.value){
                    id='item'+index;
                }
                el=document.getElementById(id);
            }
            let startTop=containerEl.scrollTop;
            let endTop=startTop+el.getBoundingClientRect().top;
            let scrollAnimationFn=doAnimation(startTop,endTop,300,containerEl);
            let interval = setInterval(()=>{
                scrollAnimationFn(interval)
            },10)
}

The effect is as follows:

Using scrollTo()

The usage of scrollTo(x,y) is basically the same as that of scrollTop attribute. scrollTo() method of the parent element can control the scroll bar to scroll to the specified position, which is actually equivalent to setting the value of scrollTop . Let me give you an example:

//Here we take y-axis scrolling as an example element.scrollTo(0,y);
element.scrollTop=y;
//The above two sentences have the same effect.

Therefore, using scrollTo() method to control the scroll bar is basically the same as using scrollTop. We only need to simply modify doAnimation() function. The code is as follows:

function doAnimation(startValue,endValue,duration,el){
              //Use closure to save variables dy and step (the distance each animation scrolls)
              let dy=0;
              let step=(endValue-startValue)/(duration/10);
              return function(interval){
                  dy+=step;
                  if (Math.abs(dy)>=Math.abs(endValue-startValue)){
                      clearInterval(interval);
                  }
                  //el.scrollTop+=step; //This line of code is modified as follows el.scrollTo(0,el.scrollTop+step);
              }
}

The execution effect is the same as that achieved using scrollTop .

Using scrollBy()

Basic Implementation

We can also use scrollBy(x,y) to control the scroll bar. As mentioned above, scrollBy() method controls the scroll bar to scroll a specified distance (note that it is not the position). Using scrollBy(), you can easily scroll to the specified element. The code is as follows:

function scrollToElement(containerEl,el){
    //Because getBoundingClientRect().top is the distance between the top of the child element and the top of the parent element, this value is the offset of the child element relative to the parent element. We pass this value into scrollBy, that is, scroll to the specified element containerEl.scrollBy(0,el.getBoundingClientRect().top);
}

Scroll to the bottom:

function scrollToBottom(containerEl){
    let dy=containerEl.scrollHeight-containerEl.clientHeight;
    containerEl.scrollBy(0,dy);
}

Scroll to top

function scrollToTop(containerEl){
    let dy = -(containerEl.scrollHeight - containerEl.clientHeight);
    containerEl.scrollBy(0,dy);
}

Add animation

Here we modify the animation generation function, because the parameter of our scrollBy() is the offset of the variable, so make the following changes:

function scrollToBottom(containerEl){
              if(!containerEl){
                containerEl=container;
              }
              //dy is the offset let dy=containerEl.scrollHeight-containerEl.clientHeight;
              let scrollAnimationFn=doAnimation(dy,300,containerEl);
              let interval = setInterval(()=>{
                scrollAnimationFn(interval)
              },10)
         }
         function scrollToTop(containerEl){
              if(!containerEl){
                containerEl=container;
              }
              //dy is the offset let dy=-(containerEl.scrollHeight-containerEl.clientHeight);
              let scrollAnimationFn=doAnimation(dy,300,containerEl);
              let interval = setInterval(()=>{
                scrollAnimationFn(interval)
              },10)
         }
         function scrollToElement(containerEl,el){
            if(!containerEl){
                containerEl=container;
            }
            if(!el){
                let input = document.getElementsByTagName('input')[0];
                let id='item'+input.value;
                if(!input.value){
                    id='item'+index;
                }
                el=document.getElementById(id);
            }
           //dy is the offset let dy=el.getBoundingClientRect().top;
            let scrollAnimationFn = doAnimation(dy, 300, containerEl);
            let interval = setInterval(()=>{
                scrollAnimationFn(interval)
            },10)
         }
         /**
          * @description: 
          * @param {type} 
          * @return: 
          */
         function doAnimation(dy,duration,el){
              //Use closure to save variables such as exe_dy and step (the distance each animation scrolls)
              let exe_dy=0; //Offset already executed let step=dy/(duration/10);
              return function(interval){
                  exe_dy+=step;
                  if (Math.abs(exe_dy)>=Math.abs(dy)){
                      clearInterval(interval);
                  }
                  el.scrollBy(0,step);
              }
         }

The execution effect is the same as that achieved using scrollTop .

at last

The above: point_up_2: is my detailed summary and explanation of DOM scroll bar control, as well as some basic usage methods.

This concludes this article about the detailed summary of scrolling control of DOM element scroll bars in HTML. For more relevant DOM element scroll bar scrolling content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope that everyone will support 123WORDPRESS.COM in the future!

<<:  Detailed explanation of Vue project packaging

>>:  Image hover toggle button implemented with CSS3

Recommend

Introduction to MySQL <> and <=> operators

<> Operator Function: Indicates not equal t...

Common problems in implementing the progress bar function of vue Nprogress

NProgress is the progress bar that appears at the...

The implementation principle of Mysql master-slave synchronization

1. What is MySQL master-slave synchronization? Wh...

What is Nginx load balancing and how to configure it

What is Load Balancing Load balancing is mainly a...

Implementation of dynamic particle background plugin for Vue login page

Table of contents The dynamic particle effects ar...

Understanding the Lazy Loading Attribute Pattern in JavaScript

Traditionally, developers create properties in Ja...

How to use filters to implement monitoring in Zabbix

Recently, when I was working on monitoring equipm...

Teach you how to use Portainer to manage multiple Docker container environments

Table of contents Portainer manages multiple Dock...

Why is there this in JS?

Table of contents 1. Demand 2. Solution 3. The fi...

JavaScript css3 to implement simple video barrage function

This article attempts to write a demo to simulate...

Detailed explanation of when javascript scripts will be executed

JavaScript scripts can be embedded anywhere in HT...

JavaScript macrotasks and microtasks

Macrotasks and Microtasks JavaScript is a single-...

IE8 compatibility notes I encountered

1. IE8's getElementById only supports id, not ...

A quick guide to Docker

Docker provides a way to automatically deploy sof...