Ross Symonds
Ross Symonds

Reputation: 710

Animating multiple headers that have same class

Problem Solved

Thank you Nalin Ranjan for your help!

jsFiddle showing animation being applied to one header (the code is a modified version of this GitHub project).

jsFiddle showing animation being applied to all headers.

Problem

I want to apply the same animation to multiple headers. I have five headers with class fancy1, currently the animation is only being applied to the first header.

This jsFiddle contains the code I use to get one header animated, although the animation isn't seeming to work in jsFiddle.

You can see in the screenshot below, the animation is mid way through running for the Las Vegas header.

enter image description here

Old solution that animates one header

 const text1 = document.querySelector('.fancy1');
    const strText1 = text1.textContent;
    const splitText1 = strText1.split("");
    text1.textContent = "";

for(let i=0; i<splitText1.length; i++){
    text1.innerHTML += "<span>"+ splitText1[i] + "</span>";
}

let char1 = 0;
let timer1 = setInterval(onTick,150);

function onTick(){
    const span1 = text1.querySelectorAll('span')[char1];
    span1.classList.add('fade');
    char1++;
  

    if (char1 === splitText1.length){
       
        complete1();
        return;
    }
}

function complete1(){
   
    clearInterval(timer1);
    timer1 = null;
}

Failed solution 1

I tried giving the five headers seperate class names - fancy1, fancy2, fancy3, fancy 4 and fancy5.

const text = document.getElementsByClassName(".fancy1");
Split(text)
const text = document.getElementsByClassName(".fancy2");
Split(text)

function Split(text){
const strText = text.textContent;
const splitText = strText.split("");
text.textContent = "";

for(let i=0; i<splitText.length; i++){
   
    text.innerHTML += "<span>"+ splitText[i] + "</span>";
   
}

let char = 0;
let timer = setInterval(onTick,150);
}

function onTick(){
    
    const span = text.querySelectorAll('span')[char];
    span.classList.add('fade');
   
    char++;
  
    if (char === splitText.length){
    
        complete();
        return;
    }
}

function complete(){
   
    clearInterval(timer);
    timer = null;
}

Failed Solution 2

I tried using global variables

const window.text = document.getElementsByClassName(".fancy1");
Split()
const window.text = document.getElementsByClassName(".fancy2");
Split()
const window.text = document.getElementsByClassName(".fancy3");
Split()
const window.text = document.getElementsByClassName(".fancy4");
Split()

function Split(){
const strText = (window.text).textContent;
const splitText = strText.split("");
text.textContent = "";

for(let i=0; i<splitText.length; i++){
   
    text.innerHTML += "<span>"+ splitText[i] + "</span>";
   
}

let char = 0;
let timer = setInterval(onTick,150);
}

function onTick(){
    
    const span = text.querySelectorAll('span')[char];
    span.classList.add('fade');
    char++;
    if (char === splitText.length){
       
        complete();
        return;
    }
}
function complete(){
    clearInterval(timer);
    timer = null;
}

Failed solution 3 (based on Nalin Ranjan's reponse)

After making a number of tweaks to Nalin Ranjan's soltuion, I was no longer getting erorr messages in the console log. But none of the animations were happening.

const headers = document.querySelectorAll('.fancy1');

headers.forEach(text => Split(text));

function Split(text){

const strText = text.textContent;
const splitText = strText.split("");
text.textContent = "";

for(let i=0; i<splitText.length; i++){
   
    text.innerHTML += "<span>"+ splitText[i] + "</span>";
   
}

window.char = 0;
window.timer = setInterval(onTick,1500);
window.text = text
window.splitText = splitText
}

function onTick(){
    
    const span = window.text.querySelectorAll('span')[window.char];
    span.classList.add('fade');
   
    window.char++;
  
  console.log(window.char)
  console.log(window.splitText.length)
    if (window.char === window.splitText.length){

        console.log("is it working?")
    
        complete();
        return;
    }
}

function complete(){
   
    clearInterval(timer);
    window.timer = null;
}

Upvotes: 0

Views: 164

Answers (1)

Nalin Ranjan
Nalin Ranjan

Reputation: 1782

document.querySelector returns a single element as result, however you want to apply your function to multiple elements, so why not use document.querySelectorAll.

How about trying this...

const headers = document.querySelectorAll('.fancy1');

headers.forEach(header => Split(header));

function Split(text) {

  const strText = text.textContent;
  const splitText = strText.split("");
  text.innerHTML = "";

  for (let i = 0; i < splitText.length; i++) {

    text.innerHTML += "<span>" + splitText[i] + "</span>";

  }

  let char = 0;
  let timer = setInterval(onTick, 150);

  function onTick() {
    const spans = text.querySelectorAll('span');
    const currentSpan = spans[char];
    currentSpan.classList.add('fade');

    char++;

    if (char === splitText.length) {

      complete();
      return;
    }
  }

  function complete() {

    clearInterval(timer);
    timer = null;
  }
}

Upvotes: 1

Related Questions