JavaScript implements page scrolling animation

JavaScript implements page scrolling animation

When creating front-end UI effects, it is a very popular design to animate elements according to the scroll position. Usually, we use third-party plugins or libraries to achieve this. In this tutorial, I will teach you how to do this using pure JavaScript and CSS.

First preview the effect:

We use CSS to implement the animation and JavaScript to handle triggering the required styles. Let's create the layout first.

Create a layout

We first use HTML to create the page layout, and then assign a common class name to the elements that need to be animated. The subsequent JavaScript locates these elements through this class name. Here we assign the class name js-scroll to the element that needs to be animated based on scrolling. The HTML code is as follows:

<section class="scroll-container">
  <div class="scroll-element js-scroll"></div>
  <div class="scroll-caption">This animation fades in from the top.</div>
</section>

Add CSS styles

Let's start with a simple fade-in animation effect:

.js-scroll {
  opacity: 0;
  transition: opacity 500ms;
}

.js-scroll.scrolled {
  opacity: 1;
}

All js-scroll elements on the page will be hidden and have an opacity of 0. When you scroll to this element area, add the .scrolled class name to it to make it visible.

Manipulating elements with JavaScript

With the layout and styles in place, we now need to write a JavaScript function that assigns the class names to elements as they scroll into view.

Let's simply break down the logic:

  1. Get all js-scroll elements on the page
  2. Make these elements fade out by default
  3. Check if an element is within the viewport
  4. If the element is within the viewport, it is assigned the scrolled class name

Get the target element

To get all js-scroll elements on the page, use document.querySelectorAll():

const scrollElements = document.querySelectorAll('.js-scroll')

By default, fade out all target elements

Iterate over these elements and fade them all out of view:

scrollElements.forEach((el) => {
  el.style.opacity = 0
})

Check if an element is within the viewport

We can detect whether an element is in the user's viewport by determining whether the distance from the element to the top of the page is less than the height of the visible part of the page.

In JavaScript, we use getBoundingClientRect().top method to get the distance between the element and the top of the page, and use window.innerHeight or document.documentElement.clientHeight to get the height of the window.

We will create an elementInView function with the above logic:

const elementInView = (el) => {
  const elementTop = el.getBoundingClientRect().top

  return (
    elementTop <= (window.innerHeight || document.documentElement.clientHeight)
  )
}

We could modify this function to detect if the element has scrolled x pixels into the page, or to detect the percentage of the page scrolled.

const elementInView = (el, scrollOffset = 0) => {
  const elementTop = el.getBoundingClientRect().top

  return (
    elementTop <=
    (window.innerHeight || document.documentElement.clientHeight) - scrollOffset
  )
}

In this case, the function returns true if the element has been scrolled into the page by the amount of scrollOffset. Let's make a slight modification and change the scrollOffset parameter to a percentage:

const elementInView = (el, percentageScroll = 100) => {
  const elementTop = el.getBoundingClientRect().top

  return (
    elementTop <=
    (window.innerHeight || document.documentElement.clientHeight) *
      (percentageScroll / 100)
  )
}

This part can define the logic according to your specific needs.

Note: You can use the Intersection Observer API[2] to achieve the same effect, but it does not support IE.

Adding class names to elements

Now that we can detect whether an element has been scrolled into the page, we need to define a function to handle the display of the element - in this case we display the element by assigning the scrolled class name.

const displayScrollElement = (element) => {
  element.classList.add('scrolled')
}

We then combine our previous logic with the displayScrollElement function and call it on all js-scroll elements using the forEach method.

const handleScrollAnimation = () => {
  scrollElements.forEach((el) => {
    if (elementInView(el, 100)) {
      displayScrollElement(el)
    }
  })
}

Additionally, when the element is no longer in view, it needs to be reset to its default state, which we can do by defining a hideScrollElement:

const hideScrollElement = (element) => {
  element.classList.remove("scrolled");
};

const handleScrollAnimation = () => {
  scrollElements.forEach((el) => {
    if (elementInView(el, 100)) {
      displayScrollElement(el);
    } else {
      hideScrollElement(el);
    }
  }

Finally, we'll pass the above method into the window's scroll event listener so that it runs whenever the user scrolls.

window.addEventListener('scroll', () => {
  handleScrollAnimation()
})

We have implemented all the functions of scroll animation.

Complete example

Please go back to the beginning of the article and look at the renderings. See, these elements appear with different animations. This is achieved by assigning different CSS animations to class names. The HTML for this example is:

<section class="scroll-container">
  <div class="scroll-element js-scroll fade-in"></div>
  <div class="scroll-caption">Fade-in effect</div>
</section>
<section class="scroll-container">
  <div class="scroll-element js-scroll fade-in-bottom"></div>
  <div class="scroll-caption">Cut to top effect</div>
</section>
<section class="scroll-container">
  <div class="scroll-element js-scroll slide-left"></div>
  <div class="scroll-caption">Cut in from the left</div>
</section>
<section class="scroll-container">
  <div class="scroll-element js-scroll slide-right"></div>
  <div class="scroll-caption">Cut in from the right</div>
</section>

Here we assign different CSS class names to elements with different animation effects. Here are the CSS codes corresponding to these classes:

.scrolled.fade-in {
  animation: fade-in 1s ease-in-out both;
}

.scrolled.fade-in-bottom {
  animation: fade-in-bottom 1s ease-in-out both;
}

.scrolled.slide-left {
  animation: slide-in-left 1s ease-in-out both;
}

.scrolled.slide-right {
  animation: slide-in-right 1s ease-in-out both;
}

@keyframes slide-in-left {
  0% {
    transform: translateX(-100px);
    opacity: 0;
  }
  100% {
    transform: translateX(0);
    opacity: 1;
  }
}

@keyframes slide-in-right {
  0% {
    transform: translateX(100px);
    opacity: 0;
  }
  100% {
    transform: translateX(0);
    opacity: 1;
  }
}

@keyframes fade-in-bottom {
  0% {
    transform: translateY(50px);
    opacity: 0;
  }
  100% {
    transform: translateY(0);
    opacity: 1;
  }
}

@keyframes fade-in {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

Although different animation elements have been added, we do not need to modify the JavaScript code because the logic remains the same. This means we can add any number of different animations to our page without having to write new functions.

Improving performance with throttle valves

Whenever we bind a function in the scroll listener, every time the user scrolls the page, that function will be called. Scrolling a page 500px will cause a function to be called at least 50 times. If we try to include a lot of elements on a page, this can cause our page to slow down noticeably.

We can reduce the number of function calls by using the "Throttle Function". A throttling function is a higher-order function that calls the function passed in only once within a specified interval.

It is especially useful for scroll events, since we don't need to detect every pixel the user scrolls. For example, if we have a throttle function with a timer of 100ms, then the function will only be called once for every 100ms the user scrolls.

The throttling function can be implemented in JavaScript like this:

let throttleTimer = false

const throttle = (callback, time) => {
  if (throttleTimer) return

  // Mark here so that the function will not be executed repeatedly throttleTimer = true

  setTimeout(() => {
    // When the specified time comes, call the passed callback function callback()
    throttleTimer = false
  }, time)
}

Then we can modify the scroll event listener on the window object:

window.addEventListener('scroll', () => {
  throttle(handleScrollAnimation, 250)
})

Now our handleScrollAnimation function will be called every 250ms when the user scrolls:

The above is the details of how to implement page scrolling animation with JavaScript. For more information about JavaScript page scrolling, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • JavaScript gets the scroll bar position and slides the page to the anchor point
  • JavaScript to achieve masking and prohibit page scrolling
  • Vue uses native js to implement scrolling page tracking navigation highlighting sample code
  • js monitors the scrolling event method of HTML page
  • How to use JS to determine whether the page has a scroll bar
  • Javascript implements smart navigation positioning when the page scrolls
  • js/jquery control page dynamic loading data sliding scroll bar automatic loading event method
  • js implements refreshing the page and returning to the position of the scroll bar when recording [two options are available]
  • js implements page refresh with unchanged scroll bar position

<<:  MySQL reports an error: Can't find file: './mysql/plugin.frm' solution

>>:  How to enter directory/folder in Linux without using CD command

Recommend

MySQL query_cache_type parameter and usage details

The purpose of setting up MySQL query cache is: C...

Vue custom v-has instruction, steps for button permission judgment

Table of contents Application Scenario Simply put...

A brief analysis of event bubbling and event capture in js

Table of contents 01-Event Bubbling 1.1- Introduc...

Solutions to MySQL batch insert and unique index problems

MySQL batch insert problem When developing a proj...

Mac+IDEA+Tomcat configuration steps

Table of contents 1. Download 2. Installation and...

MySQL users and permissions and examples of how to crack the root password

MySQL Users and Privileges In MySQL, there is a d...

MySQL database table partitioning considerations [recommended]

Table partitioning is different from database par...

How to import js configuration file on Vue server

Table of contents background accomplish Supplemen...

How to manage multiple projects on CentOS SVN server

One demand Generally speaking, a company has mult...

Learn more about using regular expressions in JavaScript

Table of contents 1. What is a regular expression...

Three ways to avoid duplicate insertion of data in MySql

Preface In the case of primary key conflict or un...

js memory leak scenarios, how to monitor and analyze them in detail

Table of contents Preface What situations can cau...

ReactJs Basics Tutorial - Essential Edition

Table of contents 1. Introduction to ReactJS 2. U...

MySQL trigger simple usage example

This article uses examples to illustrate the simp...

An example of installing MySQL on Linux and configuring external network access

Configuration steps 1. Check whether DNS is confi...