I have the code for a horizontal timeline with javascript. This code works fine, but there is one problem in scrolling. Sometimes when I get to the last timeline item, the scrolling is not complete and the NEXT button disappears.
can you please tell me how to fix this? thanks!
problem screenshot:
code:
(function () {
// VARIABLES
const timeline = document.querySelector(".timeline ol"),
elH = document.querySelectorAll(".timeline li > div"),
arrows = document.querySelectorAll(".timeline .arrows .arrow"),
arrowPrev = document.querySelector(".timeline .arrows .arrow__prev"),
arrowNext = document.querySelector(".timeline .arrows .arrow__next"),
firstItem = document.querySelector(".timeline li:first-child"),
lastItem = document.querySelector(".timeline li:last-child"),
xScrolling = 280,
disabledClass = "disabled";
// START
window.addEventListener("load", init);
function init() {
setEqualHeights(elH);
animateTl(xScrolling, arrows, timeline);
}
// SET EQUAL HEIGHTS
function setEqualHeights(el) {
let counter = 0;
for (let i = 0; i < el.length; i++) {
const singleHeight = el[i].offsetHeight;
if (counter < singleHeight) {
counter = singleHeight;
}
}
for (let i = 0; i < el.length; i++) {
el[i].style.height = `${counter}px`;
}
}
// CHECK IF AN ELEMENT IS IN VIEWPORT
// http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
function isElementInViewport(el) {
const rect = el.getBoundingClientRect();
return rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth);
}
// SET STATE OF PREV/NEXT ARROWS
function setBtnState(el, flag = true) {
if (flag) {
el.classList.add(disabledClass);
} else {
if (el.classList.contains(disabledClass)) {
el.classList.remove(disabledClass);
}
el.disabled = false;
}
}
// ANIMATE TIMELINE
function animateTl(scrolling, el, tl) {
let counter = 0;
for (let i = 0; i < el.length; i++) {
el[i].addEventListener("click", function () {
if (!arrowPrev.disabled) {
arrowPrev.disabled = true;
}
if (!arrowNext.disabled) {
arrowNext.disabled = true;
}
const sign = this.classList.contains("arrow__prev") ? "" : "-";
if (counter === 0) {
tl.style.transform = `translateX(-${scrolling}px)`;
} else {
const tlStyle = getComputedStyle(tl);
// add more browser prefixes if needed here
const tlTransform = tlStyle.getPropertyValue("-webkit-transform") || tlStyle.getPropertyValue("transform");
const values = parseInt(tlTransform.split(",")[4]) + parseInt(`${sign}${scrolling}`);
tl.style.transform = `translateX(${values}px)`;
}
setTimeout(() => {
isElementInViewport(firstItem) ? setBtnState(arrowPrev) : setBtnState(arrowPrev, false);
isElementInViewport(lastItem) ? setBtnState(arrowNext) : setBtnState(arrowNext, false);
}, 1100);
counter++;
});
}
}
})();
.timeline {
white-space: nowrap;
overflow-x: hidden;
}
.timeline ol {
font-size: 0;
width: 100vw;
padding: 250px 0;
transition: all 1s;
}
.timeline ol li {
position: relative;
display: inline-block;
list-style-type: none;
width: 160px;
height: 3px;
background: #fff;
}
.timeline ol li:last-child {
width: 280px;
}
.timeline ol li:not(:first-child) {
margin-left: 14px;
}
.timeline ol li:not(:last-child)::after {
content: "";
position: absolute;
top: 50%;
left: calc(100% + 1px);
bottom: 0;
width: 12px;
height: 12px;
transform: translateY(-50%);
border-radius: 50%;
background: #f45b69;
}
.timeline ol li div {
position: absolute;
left: calc(100% + 7px);
width: 280px;
padding: 15px;
font-size: 1rem;
white-space: normal;
color: black;
background: white;
}
.timeline ol li div::before {
content: "";
position: absolute;
top: 100%;
left: 0;
width: 0;
height: 0;
border-style: solid;
}
.timeline ol li:nth-child(odd) div {
top: -16px;
transform: translateY(-100%);
}
.timeline ol li:nth-child(odd) div::before {
top: 100%;
border-width: 8px 8px 0 0;
border-color: white transparent transparent transparent;
}
.timeline ol li:nth-child(even) div {
top: calc(100% + 16px);
}
.timeline ol li:nth-child(even) div::before {
top: -8px;
border-width: 8px 0 0 8px;
border-color: transparent transparent transparent white;
}
.timeline time {
display: block;
font-size: 1.2rem;
font-weight: bold;
margin-bottom: 8px;
}
.timeline .arrows {
display: flex;
justify-content: center;
margin-bottom: 20px;
}
.timeline .arrows .arrow__prev {
margin-right: 20px;
}
.timeline .disabled {
opacity: 0.5;
}
.timeline .arrows img {
width: 45px;
height: 45px;
}
<section class="timeline">
<ol>
<li>
<div><time>1934</time> At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium</div>
</li>
<li>
<div><time>1937</time> Proin quam velit, efficitur vel neque vitae, rhoncus commodo mi. Suspendisse finibus mauris et bibendum molestie. Aenean ex augue, varius et pulvinar in, pretium non nisi.</div>
</li>
<li>
<div><time>1940</time> Proin iaculis, nibh eget efficitur varius, libero tellus porta dolor, at pulvinar tortor ex eget ligula. Integer eu dapibus arcu, sit amet sollicitudin eros.</div>
</li>
<li>
<div><time>1943</time> In mattis elit vitae odio posuere, nec maximus massa varius. Suspendisse varius volutpat mattis. Vestibulum id magna est.</div>
</li>
<li>
<div><time>1946</time> In mattis elit vitae odio posuere, nec maximus massa varius. Suspendisse varius volutpat mattis. Vestibulum id magna est.</div>
</li>
<li>
<div><time>1956</time> In mattis elit vitae odio posuere, nec maximus massa varius. Suspendisse varius volutpat mattis. Vestibulum id magna est.</div>
</li>
<li>
<div><time>1957</time> In mattis elit vitae odio posuere, nec maximus massa varius. Suspendisse varius volutpat mattis. Vestibulum id magna est.</div>
</li>
<li>
<div><time>1967</time> Aenean condimentum odio a bibendum rhoncus. Ut mauris felis, volutpat eget porta faucibus, euismod quis ante.</div>
</li>
<li>
<div><time>1977</time> Vestibulum porttitor lorem sed pharetra dignissim. Nulla maximus, dui a tristique iaculis, quam dolor convallis enim, non dignissim ligula ipsum a turpis.</div>
</li>
<li>
<div><time>1985</time> In mattis elit vitae odio posuere, nec maximus massa varius. Suspendisse varius volutpat mattis. Vestibulum id magna est.</div>
</li>
<li>
<div><time>2000</time> In mattis elit vitae odio posuere, nec maximus massa varius. Suspendisse varius volutpat mattis. Vestibulum id magna est.</div>
</li>
<li>
<div><time>2005</time> In mattis elit vitae odio posuere, nec maximus massa varius. Suspendisse varius volutpat mattis. Vestibulum id magna est.</div>
</li>
<li></li>
</ol>
<div class="arrows">
<button class="arrow arrow__prev disabled" disabled>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/162656/arrow_prev.svg" alt="prev timeline arrow" />
</button>
<button class="arrow arrow__next">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/162656/arrow_next.svg" alt="next timeline arrow" />
</button>
</div>
</section>