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

Adding and deleting MPEG-DASH segments from a media source buffer in a dynamic manner

I have been developing a custom MPEG-DASH streaming player using the HTML5 video element. Essentially, I am setting up a MediaSource and attaching a SourceBuffer to it. After that, I am appending DASH fragments into this sourcebuffer and everything is func ...

Can you explain the difference between CDN and ESM builds in vue.js?

According to the Vue.js documentation, there are differences in syntax depending on whether you are using the CDN or ESM build of Vue.js. What is the significance of having two different builds and how does it result in a difference in usage syntax? Infor ...

jQuery UI dynamically adjusting content layout based on browser size changes

Having an issue with my custom accordion script where resizing the browser causes formatting problems in one of the sections. I want the content to remain intact and to utilize a scrollbar if necessary to view the content. The problem is visible in section ...

Creating Header Images for Websites, like the way Facebook does

Exploring how to properly configure the header image on my website has been intriguing. The main issue is that when I view it on my laptop, which has a width resolution of around 1280px, the header image's width measures about 2000px. My goal is to h ...

Utilizing Google Maps to display an infowindow upon clicking a location from a geojson file

I want to implement info windows that pop up when markers on a map are clicked. I used the sample code provided by Google (below) to create a marker map from geojson files dragged and dropped into the window. My goal is for the info windows to show text ta ...

Prevent automatic scrolling of a div in jQuery while it is being hovered over

After addressing a previous question, I have further refined the script but encountered an issue at the final step. The current functionality involves a div automatically scrolling 50px at a time until it reaches the bottom, then it scrolls back to the to ...

When working with React and trying to update data using the useEffect hook, I encountered an issue with an Array data. Unfortunately, using map or Object.keys(data).map did not produce the desired results. Can anyone provide guidance on

After using the useEffect hook to update the data, I noticed that the data is an array when inspected in the DEV tools. However, when attempting to traverse the data using the map function, an error stating 'data.map is not a function' is returne ...

Move the text to the following line if a horizontal scroll bar is visible using JavaScript/JQuery and CSS styling

I have a section with multiple div elements...how can I ensure that when there is horizontal scrolling in the section, the hidden divs shift to the next line? HTML <section id="a"> <div class="num"> <div class="num"> <div class="num" ...

What is the best way to add a class to the initial HTML element in my specific scenario?

Currently utilizing the angular framework in my application. Desire to assign a specific class to only the initial element within my ng-repeat iteration. <div class='initialOnly' ng-repeat = 'task in tasks'>{{task.chore}}</di ...

Error: Attempting to access the 'url' property of an undefined variable, despite specifically checking for its undefined status

Within my React application, I am utilizing the following state: const [functions, setFunctions] = useState([{}]); I have created a test to check if a specific property is undefined: if (typeof functions[functionCount].url !== "undefined") { ...

Loader successfully resolving deep array references

My schema is structured as follows: type User{ id: String! name: String posts: [Post] } type Post { id: String! userId: String body: String } I'm utilizing Facebook's dataloader to batch the request. query { GetAllUser { id ...

Event bubbling does not occur in elements outside of the DOM

I am facing an issue with a DOM element that has not been added to the DOM yet, but I want to trigger a DOM event on it. The event is not supposed to bubble up, however, when using jQuery, it does. This behavior seems odd to me. This strange phenomenon c ...

I am looking to implement an animation that automatically scrolls to the bottom of a scrollable DIV when the page is loaded

My DIV is configured with overflow-y set to scroll. .scrolling-div { width: 85%; height: 200px; overflow-y: scroll; } If I have an abundance of content within this div, my goal is for it to automatically scroll to the bottom upon loading the page. I am ...

After reaching a total of 20 entries, req.body will automatically convert the array into an

I have the ability to dynamically add properties to my form: <form action=""> <div class="property"> <label>Name : <input type="text" name="properties[1][name]"></label> <label>Order : <input type="text" na ...

Struggling with making react-hook-form correctly validate an email address

I've been struggling for a long time to make this validation work correctly, but it seems impossible. I even added some text at the bottom to display an error message related to the email, but it always shows no error, regardless of the situation. Ed ...

Exploring the Efficiency Enhancements in the next/image Optimization Process within Next.js

I've been delving into Next.js and using the next/image component for image rendering. While leveraging it to enhance image loading in my project, I've become intrigued by the intricate workings behind the scenes. I'm particularly interested ...

Send data from the URL to PHP and then to Javascript in order to showcase the value within an input field

I need to pre-fill an email subscriber form with an email address from the URL. The specific email address is included in the following URL: http://www.domain.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="dcacbdbbb9e3b9b ...

Encountering an issue with Material-UI and Next.js: "TypeError: theme.spacing is not a function

Encountering an issue after modifying _app.js to dynamically generate a material UI theme. I've been following the implementation example provided by the material-ui team at: https://github.com/mui-org/material-ui/tree/master/examples/nextjs. To summ ...

Effortless JavaScript function for retrieving the chosen value from a dropdown menu/select element

I've figured out how to retrieve the value or text of a selected item in a dropdown menu: document.getElementById('selNames').options[document.getElementById('selNames').selectedIndex].value In order to simplify this code, I&apos ...

Tips for editing events in the "react-big-calendars" component

I am looking to implement a feature where users can click on events in a calendar and then edit either the dates or event titles. Can this functionality be achieved using "react-big-calendar"? If not, are there any other packages you can recommend? <Cal ...