everybody. I've a problem probably well-know, but I can't find a solution also looking for it in the WEB. I'm working on a progressive bar that shows the parts included in a 'title section' during screen scrolling. Everything works fine except when I try to add a class (and remove it), because I'm not able to fire the event only once in the for-next loop. Here is a part of the HTLM:
<body>
<div class="container">
<section class="onTop">
<nav>
<div class="scroll-title">MENU</div>
<div id="scroll-total">
<div id="scroll-part"></div>
</div>
</nav>
</section>
<div class="wrapper">
<div class="title">FIRST TITLE</div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorum, aut quo blanditiis hic numquam, sapiente maiores id,
[etc.]
here is the CSS parts those apply:
.scroll-title{
text-align: right;
font-size: 10px;
width: 15.5vh;
position: absolute;
top: 14%;
left: 50%;
transform: translateX(-50%) rotate(90deg);
border: 1px solid red;
transition: font-size .25s ease-out;
}
.scroll-title.action{
font-size: 20px;
}
The JS code put titles' heigths refecences in an array, then check if the scroll position is inside a part an move the bar. In that time the code changes the single title's DIV containing "scroll-title" class. My idea is to add a CSS class to animate (with a transition) the title. So, I'm using a addEventListener to add and remove the class, but I'd like to fire this event only once, and I can't find a way to do it. Thisi a part of the code:
let titleScroll = document.querySelector('.scroll-title');
let band = document.getElementById('scroll-total');
let scroll = document.getElementById('scroll-part');
let pageTitlesRif =[], pageTitlesText =[];
let pageTitles = document.querySelectorAll('.wrapper .title');
pageTitlesRif = [0];
pageTitlesText =['MENU'];
let rect;
let tot = band.offsetWidth;
let totSide = bandSide.offsetHeight;
for (var i = 0; i < pageTitles.length; i ) {
rect = pageTitles[i].getBoundingClientRect();
pageTitlesText.push(pageTitles[i].innerText);
pageTitlesRif.push(rect.bottom document.documentElement.scrollTop);
}
let scrollHeight = Math.max(
document.body.scrollHeight, document.documentElement.scrollHeight,
document.body.offsetHeight, document.documentElement.offsetHeight,
document.body.clientHeight, document.documentElement.clientHeight
);
pageTitlesRif.push(scrollHeight);
console.log(scrollHeight);
window.onscroll = function() {
for (var i = 1; i < pageTitlesRif.length; i ) {
if (window.pageYOffset > pageTitlesRif[i - 1] && window.pageYOffset < pageTitlesRif[i]) {
titleScroll.classList.add('action');
let transitionEnd = whichTransitionEvent();
titleScroll.addEventListener(transitionEnd, putClass, false);
titleScroll.innerText = pageTitlesText[i - 1];
scroll.style.left = (pageTitlesRif[i-1] * tot / scrollHeight).toString() 'px';
scroll.style.width = ((pageTitlesRif[i] - pageTitlesRif[i - 1]) * tot /
scrollHeight).toString() 'px';
}
}
}
let putClass = function(){
this.classList.remove('action');
}
function whichTransitionEvent(){
var t;
var el = document.createElement('fakeelement');
var transitions = {
'transition':'transitionend',
'OTransition':'oTransitionEnd',
'MozTransition':'transitionend',
'WebkitTransition':'webkitTransitionEnd'
}
for(t in transitions){
if( el.style[t] !== undefined ){
return transitions[t];
}
}
}
Has somebody a suggestion to fix this?
CodePudding user response:
Well, I had the solution under my eyes, and I made a mountain out of a molehill... It's enuogh to control if the existing title is different from the one that comes in the loop, like this:
window.onscroll = function() {
for (var i = 1; i < pageTitlesRif.length; i ) {
if (window.pageYOffset > pageTitlesRif[i - 1] && window.pageYOffset < pageTitlesRif[i]) {
if (titleScroll.innerText != pageTitlesText[i - 1]){
titleScroll.innerText = pageTitlesText[i - 1];
titleScroll.classList.add('action');
let transitionEnd = whichTransitionEvent();
titleScroll.addEventListener(transitionEnd, putClass, false);
scroll.style.left = (pageTitlesRif[i-1] * tot / scrollHeight).toString() 'px';
scroll.style.width = ((pageTitlesRif[i] - pageTitlesRif[i - 1]) * tot /
scrollHeight).toString() 'px';
}
}
}
}
In this way, the code on the title (and on the other tag elements) in executed once.