The initial spacing glitch on the text rotator in javascript

I am uncertain whether this falls under a CSS issue or a JavaScript problem. Currently, I have a JavaScript text rotator that cycles through various words in a sentence, replacing individual words to alter the message.

While it operates flawlessly, there is an issue when it first loads, where it retains space for other word options even though they are not visible. Once it changes the initial word, the spacing corrects itself.

To better illustrate this, please observe how the spacing is off initially when the script loads and then corrects itself after 5 seconds.

/**
 * The new fancy VanillaJS rotaterator
 * @param {string} selector 
 * @param {object} options 
 */
function rotaterator(selector, options) {
    var defaults = {
        fadeSpeed: 500,
        pauseSpeed: 500,
        child: null
    };

    var options = Object.assign(defaults, options);
    var items = document.querySelectorAll(selector);
    var allSpans = [];

    /**
     * Fade all elements of the given array in by setting display and opacity
     * @param {array} arrElements 
     */
    function fadeElementsIn(arrElements) {
        arrElements.forEach(function (e) {
            if (e.style.display === 'none') {
                // if we are setting from none directly to inline, we need a small delay
                e.style.display = 'inline';
                window.setTimeout(function () {
                    e.style.opacity = 1;
                }, 10);
            } else
                e.style.opacity = 1;
        });
    }

    /**
     * Hide all previously cached span elements by setting display to none
     */
    function hideAll() {
        allSpans.forEach(function (e) {
            e.style.display = 'none';
        });
    }

    /**
     * Set initial styles and transition and fade first elements in
     */
    function initialize(onInitialized) {
        var initialFadeIn = [];
        items.forEach(function (item) {
            var spans = item.querySelectorAll('span');
            spans.forEach(function (span) {
                allSpans.push(span);
                span.style.opacity = 0;
                span.style.transition = (options.fadeSpeed / 1000) + 's linear';
            });

            initialFadeIn.push(spans[0]);
        });

        // finally fade the first set of elements in and call the callback
        window.setTimeout(function () {
            fadeElementsIn(initialFadeIn);
            onInitialized();
        }, 10);
    }

    /**
     * Fade the current items out and fade the next items in
     */
    function next() {
        window.setTimeout(function () {
            var toFadeIn = [];

            items.forEach(function (item) {
                var nextIndex;
                for (var i = 0; i < item.children.length; i++) {
                    if (item.children[i].style.opacity == 1) {
                        // fade current item out
                        item.children[i].style.opacity = 0;

                        // set next index to fadeIn
                        nextIndex = (i + 1 > item.children.length - 1 ? 0 : i + 1);
                    }
                }

                // save the next element to array
                toFadeIn.push(item.children[nextIndex]);
            });

            // wait for fade out transition effect to complete and then fade all new elements in
            window.setTimeout(function () {
                hideAll();
                fadeElementsIn(toFadeIn);

                // after fadeIn transition effect call this method recursive.
                window.setTimeout(function () {
                    next();
                }, options.fadeSpeed);
            }, options.fadeSpeed);
        }, options.pauseSpeed);
    }

    initialize(next);
}

ready(function () {
    rotaterator('.rotate', { fadeSpeed: 500, pauseSpeed: 6000 });
});

/**
 * Polyfill for Object.assign
 */
if (typeof Object.assign != 'function') {
    Object.assign = function (target) {
        'use strict';
        if (target == null) {
            throw new TypeError('Cannot convert undefined or null to object');
        }

        target = Object(target);
        for (var index = 1; index < arguments.length; index++) {
            var source = arguments[index];
            if (source != null) {
                for (var key in source) {
                    if (Object.prototype.hasOwnProperty.call(source, key)) {
                        target[key] = source[key];
                    }
                }
            }
        }
        return target;
    };
}

/**
 * document.ready function without jQuery
 * @param {function} fn 
 */
function ready(fn) {
    if (document.attachEvent ? document.readyState === "complete" : document.readyState !== "loading") {
        fn();
    } else {
        document.addEventListener('DOMContentLoaded', fn);
    }
}
.rotate {display: inline-block;}
<h2 class="light content-medium center text-center soft-top--quad">
Join us for a
<div class="rotate"> 
<span>relaxed</span>
<span>wonderful</span>
<span>crazy</span>
</div> 
weekend of
<div class="rotate"> 
<span>fun</span>
<span>games</span>
<span>laughter</span>
<span>dancing</span>
<span>love</span>
</div> resulting in your
<div class="rotate"> 
<span>best</span>
<span>worst</span>
<span>most disgusting</span>
</div>
 <div class="rotate"> 
<span>memories</span>
<span>hangover</span>
</div>
</h2>

I have attempted to initially set the other word options to display none but unfortunately, that did not resolve the issue. Can someone assist me in identifying why my text rotator is leaving space for words that are not displayed upon initialization?

Answer №1

Initially, all your span elements appear visible but are actually transparent. To correct this, ensure they are hidden properly using the display none property.

An effective way to achieve this is through CSS:

.rotate span + span { display: none; }

Answer №2

When setting opacity to 0, the element will not collapse and will still occupy space as intended. To achieve this in your initialization function, simply replace the following line:

span.style.opacity = 0;     

with

span.style.display="none";

Answer №3

The problem lies in the loading of JavaScript for Java script. To solve this, it is recommended to use inline or CSS to hide all rotating div elements instead of setting the hide property initially in Java script.

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

Content on the website that adjusts to different screen sizes horizontally, while maintaining a

Currently, I am working on developing a responsive website using Bootstrap. While the layout works well when resizing the window horizontally, there is an issue with vertical resizing. I do not want the height of the elements (such as Bootstrap columns, im ...

Simple CSS positioning questions - where could I be going astray?

Hi there! I'm a newbie to the world of CSS/HTML and struggling to figure out what's going wrong. I'd like the three navigation links on the right side to appear at the top of the page, but currently they are showing up below the navigation ...

A guide to implementing a For-Each Loop on Argument Array within Functions using Java Script

My code is not functioning properly. I am trying to calculate the sum of numbers provided by the user as arguments. I have attempted to use the Argument Object, but I can't seem to figure out what mistake I've made. // The Argument Object funct ...

The shadow effect in three.js differs from that in Unity 3D

When I import a 3D model in .fbx format to my scene using three.js, I noticed that the shadow effect is not as sharp as when using Unity. The shadows appear too blurry. Is there a way to adjust the shadowMap setting in three.js to match the shadow quality ...

Mastering the art of reading rows in ASP.NET using Java Script

Within the code snippet below, you'll find an image located in the second column. Clicking on this second column should allow me to access the data stored in the first column. Let's say we have a table with 10 rows. If the user clicks on the ico ...

Saving JSON data as a file on server

Currently, I am running a localhost website on my Raspberry Pi using Apache and I am seeking advice on how to export a JSON string to a file on the Raspberry Pi itself. While I do know how to export a file, I am unsure of how to send it to the Raspberry Pi ...

Transmitting client-side Javascript data to backend server using Express

I am trying to fetch data from my frontend using the DOM and send it to the backend through Express but I'm unsure of how to proceed. I have used a POST method to console.log the data, but now I need help retrieving it in my Express backend. (The cons ...

Incorporate meta tags containing images and titles into your Angular 6 project

I am currently exploring ways to include an image and title when sharing the URL of a specific page in my project. I have attempted the following method: createMetaTag() { const meta = document.createElement('meta'); meta.setAttribute(&a ...

Guide to connecting to various controllers in Angular

To streamline the process of fetching data from the server and paginating it for all resources, I developed a custom ListCtrl. However, before setting it up, this controller needs to receive certain configurations such as the path to the resource and defau ...

Tips for integrating Node/Express into a local application to seamlessly stream local video files on an HTML5 player

I am currently working on developing an HTML5 video player specifically designed for local use, rather than online streaming. My approach involves utilizing Node.js and Express, although I do consider myself a novice when it comes to Node. So far, I have m ...

What is the best way to retrieve an object instead of an array?

When attempting to retrieve a JSON Object, I unexpectedly received an array instead. My query is based on the primary key, so I anticipate only one result. This is my current method : router.get("/student_info/:id", (req, res, next) => { connecti ...

Mocking a React component with Jest's MockImplementation

Currently, I am in the process of testing a react component that renders another component. This secondary component makes an API call to fetch data which is then displayed on the screen. My goal is to understand how I can mock this particular component&ap ...

Can someone explain how to store multiple files in the state using useState in React (Next.js)?

Before we proceed, I would appreciate it if you could take a look at my code. There may be some spelling mistakes! (I have rewritten my code) const test = () => { const [files, setFiles] = useState([]); const handleFile = (e) => { for(let ...

Enhancing navbar with a dropdown menu in CSS

Is there a way to add a dropdown menu to my navigation bar and make it visible when hovered over? Any help or support would be greatly appreciated. Here is the code I have on JSFiddle: http://jsfiddle.net/nbh2e15y/2/ The CSS: #nav { background: none ...

Exploring the Unpredictable Results of Recursive Functions in JavaScript

Take a look at this recursive code snippet. function calculateFactorial(n) { if (n === 0 || n === 1) { return 1; } else { console.log(calculateFactorial( (n - 1) )); return n * calculateFactorial(n - 1); } } const num = ...

Is there a way to set up ESLint for VSCode without relying on node or any

We have recently transitioned from the Atom editor to VSCode for teaching beginner JavaScript concepts. One challenge we are facing is that VSCode requires installation of node and then running npm install eslint, whereas in Atom, we could easily use the a ...

Streaming data from a third-party API using WebSockets to distribute it to various subclients

In our data-driven application, the backend continuously pulls data from a third-party server and sends it to the frontend clients via websockets. The problem arises when multiple clients connect, resulting in the same data being fetched multiple times unn ...

Generating Unique IDs in PHP with AJAX Without Form Submission

When I fill up the Name, Phone, Course, and Batch fields in my form, I want the Roll Number field to automatically generate a value without submitting the form. However, even after filling up the first 4 fields, no value appears in the Roll Number field. B ...

Trouble encountered when attempting to send a variable from JavaScript to PHP using Ajax

I am currently developing a calculator web application using PHP. The front end is created with HTML, CSS, and JS. Within my JS file, I am attempting to send a variable to PHP using ajax. Here is a snippet of my progress: // Retrieving all keys from the d ...

Is it possible to insert a variable into a span or v-tooltip tag?

I am currently using vue 2 along with vuetify 2, and I seem to be encountering an issue when attempting to display data from a table. Whenever I insert curly braces between the v-tooltip tags, it results in a blank page. Below is an example of the code: &l ...