My vanilla JavaScript code isn't running the smooth scroll function as expected

Struggling to incorporate smooth scroll on Safari using Vanilla js. Despite following the documentation to a tee, the implementation is still not functioning as expected.

Outlined below is the vanilla.js code:

(function() {
  scrollTo();
})();

function scrollTo() {
  const links = document.querySelectorAll('.scroll');
  links.forEach(each => (each.onclick = scrollAnchors));
}

function scrollAnchors(e, respond = null) {
  const distanceToTop = el => Math.floor(el.getBoundingClientRect().top);
  e.preventDefault();
  var targetID = (respond) ? respond.getAttribute('href') : this.getAttribute('href');
  const targetAnchor = document.querySelector(targetID);
  if (!targetAnchor) return;
  const originalTop = distanceToTop(targetAnchor);
  window.scrollBy({ top: originalTop, left: 0, behavior: 'smooth' });
  const checkIfDone = setInterval(function() {
    const atBottom = window.innerHeight + window.pageYOffset >= document.body.offsetHeight - 2;
    if (distanceToTop(targetAnchor) === 0 || atBottom) {
      targetAnchor.tabIndex = '-1';
      targetAnchor.focus();
      window.history.pushState('', '', targetID);
      clearInterval(checkIfDone);
    }
  }, 100);
}

Highlighted section from layout.html:

<head>
  <script src="static/vanilla.js"></script>
  <li class="nav-item">
      <a data-scroll class="scroll nav-link" href="#bazinga">¿Como funciona?</a>
  </li>
</head>

Snippet from index.html:

<section id="bazinga" align="left" class="features" id="features">
    <div class="container">
      <div class="section-heading text-center">
        <h2>Funciones ilimitadas, información ilimitada</h2>
        <p class="text-muted">Descubre la magia que hay detrás de una simple pulsera tyveck</p>
<hr width="15%">
</section>

Despite efforts, the scroll behavior remains abrupt on Safari. Any assistance would be greatly appreciated.

Edit: Please note that this template is solely for testing purposes and is not functional as is.

<!DOCTYPE html>
<html>
<head>
  <script src="/static/vanilla.js"></script>
</head>
<body>
  <a class="scroll" href="#bazinga">¿Como funciona?</a>
  <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
  <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<h1>My First Heading</h1>
<p>My first paragraph.</p>
<p>My first paragraph.</p>
<p>My first paragraph.</p>
<p>My first paragraph.</p>
<p>My first paragraph.</p>
<p>My first paragraph.</p>
<p>My first paragraph.</p>
<p>My first paragraph.</p>
<p>My first paragraph.</p>
<p>My first paragraph.</p>
<p>My first paragraph.</p>
<p>My first paragraph.</p>
<p>My first paragraph.</p>
<p>My first paragraph.</p>
<p>My first paragraph.</p>
<div id=bazinga class="container">
  <p>Bazinga</p>
</div>

</body>
</html>

Answer №1

Here's a recommended solution specifically for Safari browser

(function() {
  scrollTo();
})();

function scrollTo() {
  const links = document.querySelectorAll('.scroll');
  links.forEach(each => (each.onclick = scrollAnchors));
}

function scrollAnchors(e, respond = null) {
  e.preventDefault();
  const time = 1000; // feel free to adjust this value

  const distanceToTop = el => Math.floor(el.getBoundingClientRect().top);
  var targetID = (respond) ? respond.getAttribute('href') : this.getAttribute('href');
  const targetAnchor = document.querySelector(targetID);
  if (!targetAnchor) return;
  var eTop = distanceToTop(targetAnchor);
  var eAmt = eTop / 100;
  var curTime = 0;
  while (curTime <= time) {
    window.setTimeout(scrollSmoth, curTime, eAmt);
    curTime += time / 100;
  }
}

function scrollSmoth(eAmt) {
      window.scrollBy(0, eAmt);
}

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

What is the best way to add content to a TextArea generated by the html helper in MVC 3?

I am attempting to retrieve a List collection of comments from the View using Razor and Microsoft's HTML helper for TextArea (@Html.TextAreaFor). While I can populate individual comments easily, I am unsure how to add the ENTIRE list collection of com ...

The dual-file upload feature of the jQuery ajaxForm plugin

After extensive searching online, I have yet to find an answer to my problem. The issue at hand is that when using the ajaxForm malsup plugin, it submits my files twice. HTML: <form id="gallery" enctype="multipart/form-data" action="/upload-gallery.p ...

Utilizing ng-style with a ForEach loop on an Object

How can I dynamically add a new style property to objects in an array in Angular, and then use that property inside ng-style? CommentService.GetComments(12535372).then(function () { $scope.comments = CommentService.data(); angular.forEac ...

Sending information from a text area to a PHP script and receiving a response

While it may seem simple, I am still in the process of learning. I have a textarea where I input data that I want to send to a PHP script for decryption. Below is my HTML: <html> <form action="php.php" method="post"> ...

Is the order of SCSS (SASS) selectors important when dealing with nested classes?

Exploring SCSS Styles for List Items In this code snippet, I am investigating the order of selection for classes and pseudo-selectors in SCSS. Specifically, I am questioning whether &:before.active is equivalent to &.active:before. Here is an exa ...

Once chosen, zoom in on the map to view the results

I am facing an issue with multiple selects in my code, where one select depends on the result of another. The ultimate goal is to zoom in on the area that has been searched and found, but unfortunately, it is not functioning as expected. If you'd lik ...

The functionality of selecting all items in v-select does not result in saving all of them

I'm currently working on integrating a select all button into the v-select component of Vuetify. The issue I am facing is that even though I can use the button to select all options, when I attempt to save, not all items are saved. However, if I manua ...

Alignment of button within bootstrap column is skewed when screen size is reduced

My button is perfectly centered in one of my bootstrap columns, but things start to get messy when the screen size shrinks and the button overlaps with another column containing text. Adjusting the margins only seems to make things weirder. .center-btn- ...

Switching up the colors of toggle arrow icons using jQuery

https://i.sstatic.net/Id0XP.png I am currently working on sorting a table and I want to use arrows to indicate which column is being sorted. I have the functionality to sort with arrows in place, but I would like to customize the color of the arrow in the ...

Using TypeScript to dynamically assign types to object properties

As a newcomer to TypeScript, I am in the process of migrating some of my custom components/plugins to TS. One of the challenges I'm facing is setting object properties dynamically when the property name is a variable. I would greatly appreciate a be ...

The incorrect CSS styling was applied to the custom input background with the attribute "text"

Is there any way to remove the white border and background that appears around a form input field with type "text"? Looking for some help on this issue! .my-form-login input[type="text"] { background-image: url('../images/text-input.png') ...

Enhance your webpage's body by zooming in using jQuery on Mozilla Firefox

I have a webpage and I would like to zoom its body when it loads using jQuery. However, the CSS zoom feature is not working in Mozilla Firefox. This is what I currently am using: $("body").css("zoom", "1.05"); It worked in Chrome, Opera, and Edge, but un ...

Deciding between Bull queue and Database Triggers

My current project requires creating records in the database for users on a recurring basis, such as every Monday weekly or biweekly. I have identified two potential solutions to achieve this goal. One option is to utilize Database Triggers to generate ...

What steps can I take to ensure that the information in my Cart remains consistent over time?

I recently built a NextJS application integrating the ShopifyBuy SDK. My implementation successfully fetches products from the store and displays them to users. Users can navigate to product pages and add items to their cart. However, I encountered an iss ...

Electron's start script leads to project failure

Despite extensively searching the internet for a solution, I have yet to find a definitive answer that actually works. My last resort was downloading the example from Electron's website and directly inserting the scripts into my project. However, whe ...

Enlarge image when clicked

I need help creating a gallery page where users can click on an image to enlarge it, then navigate through the images using arrows on either side. I am not familiar with JavaScript, so could someone guide me on how to achieve this? Also, I would apprecia ...

HTML5 Boilerplate and optimizing the critical rendering path by deferring scripts and styles

Previously, I constructed my website layouts using the HTML5 Boilerplate method: incorporating styles and Modernizr in the head section, jQuery (either from Google CDN or as a hosted file) along with scripts just before the closing body tag. This is an exa ...

The <nav> and <section> elements are not appearing on the page

Website: CSS: Hello there! I am experiencing an issue where the nav and section elements are not displaying on my website. They seem to only show the height and background-color attributes. Interestingly, they appear correctly on my old Firefox version ( ...

Vue 2 checkbox form array data

Creating a checkbox list with a dynamic id and name: Data: yards[{id:1,name:'test'}] etc HTML: <ul class="checkbox-list"> <template v-for="(yard, index) in yards"> <li> ...

Is it possible to animate multiple SVGs on a webpage with just the click of a button?

Is there a way to trigger the animation in the SVG each time a next/prev button is clicked while navigating through a carousel where the same SVG is repeated multiple times? The carousel is built using PHP and a while loop. jQuery(document).ready(function ...