Smoothly automate horizontal scrolling using JavaScript

My programming journey involved creating a code snippet that automatically scrolls paragraphs horizontally, giving it the appearance of "Breaking News" updates on popular websites.

The Javascript script I implemented performs automatic scrolling, but once it reaches the end, the scrolling stops abruptly. I experimented with fast scrolling back to the beginning, but found it to be a less elegant solution.

Is there a more graceful way to continuously loop these scrolling paragraphs without any interruptions?

const flavoursContainer = document.getElementById('flavoursContainer');
const flavoursScrollWidth = flavoursContainer.scrollWidth;

window.addEventListener('load', () => {
  self.setInterval(() => {
    if (flavoursContainer.scrollLeft !== flavoursScrollWidth) {
      flavoursContainer.scrollTo(flavoursContainer.scrollLeft + 1, 0);
    }
  }, 15);
});
.container {
  width: 100vw;
  overflow-x: scroll;
  white-space: nowrap;
  background-color: #fff;
  display: flex;
  -ms-overflow-style: none;
  scrollbar-width: none;
}

.scroll-disabler {
  width: 100vw;
  height: 34.4px;
  position: absolute;
  background-color: rgba(0,0,0 , 0.0001);
}

 ::-webkit-scrollbar {
  display: none;
}

p {
  padding: 8px;
}
<div class="container" id="flavoursContainer">
  <div class="scroll-disabler"></div>
  <p>Experiment with this looping text animation Experiment with this looping text animation</p>
  <p>Experiment with this looping text animation Experiment with this looping text animation</p>
</div>

Answer №1

Here is my approach:

  • Create a function called isElementInViewport(el) that will return false when an element has scrolled out of view.
  • Periodically check if the first paragraph is no longer visible. If it's not, move it to the end and adjust the scroll position accordingly.

Below is a live example:

const flavoursContainer = document.getElementById('flavoursContainer');
const flavoursScrollWidth = flavoursContainer.scrollWidth;

window.addEventListener('load', () => {
  self.setInterval(() => {
    const first = document.querySelector('#flavoursContainer p');

    if(!isElementInViewport(first)){
      flavoursContainer.appendChild(first);
      flavoursContainer.scrollTo(flavoursContainer.scrollLeft - first.offsetWidth, 0);
    }
    if (flavoursContainer.scrollLeft !== flavoursScrollWidth) {
      flavoursContainer.scrollTo(flavoursContainer.scrollLeft + 1, 0);
    }
  }, 15);
});

function isElementInViewport (el) {
    var rect = el.getBoundingClientRect();
    return rect.right > 0;
}
.container {
  width: 100vw;
  overflow-x: scroll;
  white-space: nowrap;
  background-color: #fff;
  display: flex;
  -ms-overflow-style: none;
  scrollbar-width: none;
}

.scroll-disabler {
  width: 100vw;
  height: 34.4px;
  position: absolute;
  background-color: rgba(0,0,0 , 0.0001);
}

 ::-webkit-scrollbar {
  display: none;
}

p {
  padding: 8px;
}
<div class="container" id="flavoursContainer">
  <div class="scroll-disabler"></div>
  <p>This is the first News: big news</p>
  <p>This is the second News: big news</p>
  <p>This is the third News: big news</p>
  <p>This is the fourth News: big news</p>
  <p>This is the fifth News: big news</p>
  <p>This is the last News: big news</p>
</div>

Answer №2

One way to achieve this is by utilizing the marquee tag in HTML along with some CSS. Although it may be considered deprecated, it is still supported by all major browsers.

.flex{
  display: flex;
  align-items: center;
  gap: 20px;
}
<marquee>
  <div class="flex">
     <p>This is the first News: big news</p>
     <p>This is the second News: big news</p>
     <p>This is the third News: big news</p>
     <p>This is the fourth News: big news</p>
     <p>This is the fifth News: big news</p>
     <p>This is the last News: big news</p>
  </div>
</marquee>

To learn more about the marquee element, you can visit the documentation here.

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

The contrastText property of the MUI React Theme palette is not functioning properly

I am working with MUI React to design a menu and I have utilized the AppBar component. I would like to customize it in the following way: brown.myBrown = '#544846'; const brownTheme = createTheme({ palette: { primary: { ma ...

"Customize the appearance of a List Element in Material UI by changing

How can I modify the color of a specific material ui list item? <ListItemText primary={mspvar} secondary="buy"> ...

Identifying the length of a division element following its addition

I'm facing difficulties in detecting the length and index of the dynamically appended div. I have researched extensively and found a solution involving MutationObservers, but I am unsure if it is necessary for this particular issue. Let's focus ...

Send a query to Express as a parameter

Currently, I have implemented an ejs file that contains a table element with clickable rows defined as follows: <tr onclick="myFunction(this)"> To pass a query parameter in an http request using javascript, I have the following code snippe ...

Is there a method to imitate the background-size "cover" attribute specifically for a div nested within another div using CSS?

Is there a way to have a div inside a div behave like an image with the CSS property background-size:cover? I can't use the image as a background, so I'm looking for a solution that mimics the same behavior. ...

React - Image Uploader exclusively accepts images with transparent backgrounds

I need to verify if an image has a transparent background and reject it if it does, but accept it if it doesn't. However, I am facing an issue where the hasAlpha function is not triggering an 'error' alert when the image contains a backgroun ...

Elements floating in space, stretching across the entire width

In my design, I have a fixed size layout with a centered content container. My goal is to have the menu (home, about, contact, login) span 100% of the screen width. You can view the current setup in this jsfiddle: http://jsfiddle.net/Hxhc5/1/ I am aimin ...

Running pug directly from the local node_modules directory

I'm currently attempting to run pug (/jade) from my node_modules directory, however I am unable to locate the executable within the node_modules/.bin folder. I am running MacOS 10.12.5 and installed pug using the "npm install --save pug" command. Is ...

Leverage the power of the General Sibling Selector to easily traverse through deeply nested elements in your

Hi there, I have a query regarding the General Sibling Selector. Let's start by looking at the HTML: <div id="layout-middle"> <div id="Center"> <a class="col Picture1">Title1</a> <a class="col Picture2">Title2< ...

Having trouble with clicking on an icon link within a list

Seeking assistance with creating a social media icon/link list for the first time on this platform. Any help is appreciated! <div class="social-links"> <ul> <li class="m-link"> <a href="&q ...

What is the best way to eliminate the gap above a block element using CSS?

Currently in the process of designing a website, I am faced with a challenging issue that seems to have me stumped. The structure of my page consists entirely of HTML DIVs, with certain elements nested within their parent DIVs. My main dilemma lies in tryi ...

Having success loading JSON with AJAX in a local browser, however encountering issues when attempting to do so within the PhoneGap

When I try to load external JSON-data locally in my browser, it displays the data successfully. However, when using a cloud-based build service like PhoneGap for iOS and Android apps, the page loads but without the JSON-data appearing. Can anyone provide a ...

ClickEvent (or element selector) is experiencing functionality issues

I'm currently working on creating a small calculator using HTML, CSS, and JS. However, I'm facing an issue with selecting buttons of the calculator from the HTML script and adding EventListeners to them. Here is a snippet of my HTML code: `< ...

Add the item and increase its value within an array using AngularJS

http://plnkr.co/edit/NDTgTaTO1xT7bLS1FALN?p=preview <button ng-click="addRow()">add row</button> <div ng-repeat="row in rows"> <input type="text" placeholder="name"><input type="tel" placeholder="tel"> </div> I am cur ...

The issue with grunt-contrib-compass not functioning properly within npm

I recently installed npm and grunt, followed by installing grunt-contrib-compass. However, when I try to run grunt, I encounter the following error: Running “compass:dist” (compass) task Warning: not found: compass Use –force to continue. Aborted du ...

The form submits automatically upon loading the page with empty input fields

I recently created a form on my website located at . Initially, the form functioned correctly and the PHP script executed as expected. However, I am now encountering an issue where every time I load the page, a popup message appears indicating that the for ...

Issue encountered: difficulty with vertical alignment in table cell containing both text input and image

I am facing an issue with aligning two items (an input text and an image) within a cell of a table. Despite trying various methods like using vertical-align:middle, margin top, padding, and setting height to 100%, I haven't been able to achieve the de ...

Create fluidly changing pictures within varying div elements

Hello there! I have a form consisting of four divs, each representing a full page to be printed like the one shown here: I've successfully created all the controls using AJAX without any issues. Then, I load the images with another AJAX call, and bel ...

Modifying Copyright Feature in Footer

I am attempting to implement this function within my dark-colored footer: import Typography from '@material-ui/core/Typography'; function Copyright() { return ( <Typography variant="body2" color="textSecondary" align="center"> ...

I'm puzzled as to why my Contact Form is failing to send out emails

Looking to create an email send function in a pop-up on my website that can be accessed via the following link: The issue I'm facing is that while it redirects perfectly to the thank you message, the PHP implementation does not seem to work after the ...