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?