Issue with the back-to-top button arises when smooth-scrolling feature is activated

This Back To Top Button code that I discovered online is quite effective on my website.

// Defining a variable for the button element.
const scrollToTopButton = document.getElementById('js-top');

// Creating a function to display our scroll-to-top button when scrolling beyond the initial window height.
const scrollFunc = () => {
  // Getting the current scroll value
  let y = window.scrollY;

  // Adding a class to the scroll-to-top button based on scroll location
  if (y > 100) {
    scrollToTopButton.className = "top-link show";
  } else {
    scrollToTopButton.className = "top-link hide";
  }
};

window.addEventListener("scroll", scrollFunc);

const scrollToTop = () => {
  // Setting up a variable for the distance from top of document.
  const c = document.documentElement.scrollTop || document.body.scrollTop;

  // Scrolling back to top with animation using requestAnimationFrame
  if (c > 0) {
    window.requestAnimationFrame(scrollToTop);
    // ScrollTo takes x and y coordinates. Adjust speed by changing '10' value.
    window.scrollTo(0, c - c / 10);
  }
};

// Running ScrolltoTop function on button click
scrollToTopButton.onclick = function(e) {
  e.preventDefault();
  scrollToTop();
}

However, whenever I try to add smooth scrolling for better user experience:

html {
   scroll-behavior: smooth;
}

The back-to-top button starts glitching.

I wish to have the back-to-top button also smoothly scroll along with the rest of the content on the page, including anchor links in the navigation linking to sections on the same page.

Answer №1

If you want a smooth back-to-top experience, this code will help you achieve that.

// Define the variable for the button element.
const scrollToTopButton = document.getElementById('js-top');
smoothScrollCapture = (x) => {
  event.preventDefault();
  var id = event.target.getAttribute('href').split("#")[1]
  var el = document.getElementById(id);
  var x = el.getBoundingClientRect().left
  var y = el.getBoundingClientRect().top
  smoothScrollFunc(x, y)
}

smoothScrollFunc = (x, y) => {
  event.preventDefault()
  window.scrollTo({
    top: y,
    left: x,
    behavior: 'smooth'
  });
}

window.addEventListener('DOMContentLoaded', () => {
  scrollToTopButton.addEventListener('click', () => {
    smoothScrollFunc(0, 0)
  })

  var aTags = document.getElementsByTagName('A')
  var myTags = []
  for (var i = 0; i < aTags.length; i++) {
    if (aTags[i].getAttribute("href").indexOf('#') === 0) {
      aTags[i].addEventListener('click', smoothScrollCapture);
    }
  }
})

window.addEventListener('scroll', () => {
  // Get the current scroll value
  let y = window.scrollY;
  if (y > 100) {
    scrollToTopButton.style.display = 'block'
  } else {
    scrollToTopButton.style.display = 'none'
  }
})
#js-top {
  position: fixed;
  /*OR WHATEVER YOU PREFER*/
  bottom: 10px;
  /*OR WHEREVER YOU PREFER*/
  left: 50%;
  /*OR WHEREVER YOU PREFER*/
  display: none;
}
<div style="height: 1000px;">
  <div class="nav-items">
    <a href="#paragraph1">Paragraph One</a>
    <a href="#paragraph2">Paragraph Two</a>
    <a href="#paragraph3">Paragraph Three</a>
    <a href="#paragraph4">Paragraph Four</a>
  </div>

  <div style="height: 100px;"></div>
  <p id="paragraph1">Here is the first paragraph!</p>
  <div style="height: 100px;"></div>
  <p id="paragraph2">Here is the second paragraph!</p>
  <div style="height: 100px;"></div>
  <p id="paragraph3">Here is the third paragraph!</p>
  <div style="height: 100px;"></div>
  <p id="paragraph4">Here is the fourth paragraph!</p>
</div>

<button id='js-top'>Scroll To Top</button>

EDIT I have made some changes to the code snippet. While there may be a CSS-only solution, I have used JavaScript to enhance the smooth scroll functionality for navigation links on your page. The JavaScript code captures anchor tags with href attributes referencing specific IDs and applies the smooth scrolling effect through functions like smoothScrollCapture and smoothScrollFunc.

This approach saves you from modifying your HTML by individually assigning classes to every navigation item on your page.

In the smoothScrollCapture function, when you click a navigation link (e.g. paragraph3), the script extracts the ID from the href attribute of the clicked element and retrieves the top and left positions using getBoundingClientRect(). These values are then passed to the smoothScrollFunc which smoothly scrolls the page to the specified coordinates.

All initialization tasks are wrapped in a DOMContentLoaded event listener for proper execution. This includes attaching smoothScrollCapture to anchor tags, setting up the click event for scrollToTopButton, and specifying the coordinates as 0 while navigating to the top of the page.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Can you clarify the concept of closures and how they bind the loop counter to the function scope?

I have observed programmers setting up event listeners inside loops, utilizing the counter. The syntax that I have come across is as follows: for(var i=0; i < someArray.length; i++){ someArray[i].onclick = (function(i){/* Some code using i */})(i); ...

transfer an image file to a php script using ajax

Having just started, my goal is to upload an image and send it to a server for insertion into a database. Initially, all I want to do is echo the file name that I will be sending. However, I am encountering issues with this process, as I keep receiving noi ...

Integrating Livefyre npm with Meteor

Currently, I am in the process of creating a custom package to integrate the livefyre npm module into Meteor after receiving a request from a client. Despite following the instructions provided here, I keep encountering errors that state Errors while scann ...

Scrolling horizontally to display dynamic columns based on a search query in AngularJS

I am facing a challenge with implementing search functionality in a table that has multiple dynamic columns with a horizontal scrollbar. The goal is for users to be able to search for a specific column name or data, and if a match is found, the scrollbar s ...

Combining plugin setups and functionalities into a unified script

When it comes to grouping plugin initializations and scripts in a website, I often have a "tools.js" file that contains various functions, click events, and more. I prefer keeping all these script calls centralized in one file for simplicity, organization, ...

can you explain the concept of a backing instance in react?

Although the concept of a "backing instance" is frequently mentioned in React documentation, I found it difficult to grasp its meaning. According to the React docs: In order to interact with the browser, you need a reference to a DOM node. By attaching ...

Converting JSON data from a PHP variable into a jQuery array: What you need to know

I attempted to retrieve addresses using the postcode and applied the getaddress.io site API with PHP. This resulted in a JSON dataset stored in the PHP variable $file. Now, I am tasked with converting this JSON result into a jQuery array. { "Latitude":-0. ...

Div that scrolls independently without affecting the position of other elements

Visit this link for reference <div class="col-10 content" id="content"> <ul> <li>News</li> <li>News</li> <li>News</li> <li>News</li> < ...

Exporting Data and Utilizing a Steady Data Table

I have incorporated the Fixed Data Grid into my latest project. https://facebook.github.io/fixed-data-table/example-sort.html My goal is to generate csv and pdf reports from the data displayed on the grid. Could you please advise me on how to export gri ...

Attempting to include a standard VAT rate of 5% on the invoice

/* The code format is correct and I don't see any issues on my end, I hope it works well for you. */ I need assistance in adding a fixed VAT (tax) rate of 5%. The tax amount should be displayed on the row, while the total tax should reflect the sum o ...

Modify HTML text using conditional CSS without JavaScript

Apologies for asking such a beginner question, but I've searched high and low for a similar post, to no avail. Here's my query: I have a paragraph text in my HTML code that I want to automatically replace with new text when I click a specific B ...

How to create a responsive image that appears over a button when hovering in Bootstrap?

My goal is to display an image over a button when hovering. I've tried adding the .img-responsive class in Bootstrap while including the image in the HTML, but it's not working as expected with my current method of loading images. The buttons the ...

How long does it take to delete and recreate a cloudfront distribution using AWS CDK?

I am currently undergoing the process of migrating from the AWS CDK CloudfrontWebDistribution construct to the Distribution Construct. According to the documentation, the CDK will delete and recreate the distribution. I am curious about the total duration ...

Creating a Timeout Function for Mobile Browsers in JavaScript/PHP

Currently, I am developing a mobile-based web application that heavily relies on AJAX and Javascript. The process involves users logging in through a login page, sending the data via post to the main page where it undergoes a mySQL query for validation. If ...

Using Javascript outside of the AngularJS environment

I am trying to utilize Javascript functions outside the controller in Angular JS instead of using a service within a module. Is this allowed? For instance: var UrlPath="http://www.w3schools.com//angular//customers.php" //this section will store all the f ...

Using AngularJS controller to implement filtering functionality

I am a beginner at using Angular and have successfully implemented a filter to translate text for localization in my HTML view: <input type="button" class="btn btn-link" value="{{'weeklyOrdersPage.reposting' | translate}}" ng-click="sortBy(&a ...

Utilizing d3.js to filter a dataset based on dropdown selection

I am working with a data set that contains country names as key attributes. When I select a country from a dropdown menu, I want to subset the dataset to display only values related to the selected country. However, my current code is only outputting [obje ...

A beginner's guide to integrating Socket.io with Express.JS using the Express application generator

Currently, I am attempting to utilize Socket.io alongside Express.JS by using the Express application generator. While searching for solutions, I came across some helpful advice on how to achieve this (check out Using socket.io in Express 4 and express-gen ...

Capture data from ajax effectively by extracting and executing manipulations seamlessly

I have a project where I need to retrieve images from a database using Ajax and display them using a carousel plugin. This is the process: An image URL is saved to the database by an admin The frontend script makes an Ajax call to a PHP file and retrieve ...

Tips for removing special characters from HTML?

I'm currently grappling with the concept of the filter My situation is as follows: $htmlData includes a user-entered html string formatted like this $htmlData = array('<em>test</em>', 'text here','\n') ...