Search code examples
javascriptfor-loopselectors-apionscrollgetboundingclientrect

querySelectorAll && getBoundingClientRect


I am having a problem with the JavaScript querySelectorAll () method.

I want to have a fade effect on two paragraph (p) tags, they both have opacity set to 0 initially and a transform: translateY of 15vh to move them down a little bit, and I want when paragraphs appear at the bottom of the screen, return to an opacity of 1 and transform:translateY to 0, during the user scroll down.

I create an function called scrollAppear(), and inside it I have many things..

function scrollAppear()

Firstly I have one variable paragraphsToFade that contain the two paragraphs with the class "paragraphs_to_fade"; I used the querySelectorAll method to grab the two (p) tags that have the class (.paragraphs_to_fade).

This return me an array (nodeList)..

    var paragraphsToFade=document.querySelectorAll(".paragraphs_to_fade");

Then I want to have access to the coordinate Y of the paragraphs, and to achieve this I used the method getBoundingClientRect().top, that return the top of the specified elements relative to the top of the window in this case.

I stored the value in a variables called paragraphsPosition;

But to have the coordinate Y of the two (p) element I have to loop into the for loop and specify the [i] variable that gonna a put the two value ever loop iteration like this:

   for (let i = 0; i < paragraphsToFade.length; i++) {
        var paragraphsPosition=paragraphsToFade[i].getBoundingClientRect().top;
    }

After that I create a variable called screenSize that have access to the window Height :

var screenSize=window.innerHeight;

Then I check one condition with an if/else statement, to check if the top value of the element is less than the height of the window, and if is true, add the class fadeInAnimation, which will reset the opacity to 1 and the transform: translateY to 0 with a transition of 1s, as specified at the start of my explanation.

   var screenSize=window.innerHeight;
    if(paragraphsPosition < screenSize){
        paragraphsToFade.classList.add("fadeInAnimation");
    }    

Finally I just call the function scroll appear, when the user scroll the window :

window.addEventListener("scroll",scrollAppear);

I don't know why but when I used the querySelector and I have just one paragraph the fade effect works, but when I use the querySelectorAll and I want to grab multiple paragraph, it's doesn't work, maybe I don't loop great or something else , I used console.log in different place to try to know what is going on, but I didn't understand why?

I see this fade effect in a tutorial: https://www.youtube.com/watch?v=C_JKlr4WKKs


Solution

  • See this fiddle, you are appending the class to an object of multiple elements and not each element itself.

    When you iterate over the array, include the class to the element which is in the for loop

    function scrollAppear(){
      var paragraphsToFade = document.querySelectorAll(".paragraphs_to_fade");
      var paragraphsPosition;
      for (let i = 0; i < paragraphsToFade.length; i++) {
        paragraphsPosition=paragraphsToFade[i].getBoundingClientRect().top;
        var screenSize=window.innerHeight;
        if(paragraphsPosition < screenSize && !paragraphsToFade[i].classList.contains("fadeInAnimation") ){
    
          paragraphsToFade[i].classList.add("fadeInAnimation");
              console.log('added class');
        }    
      }
    }
    window.addEventListener("scroll",scrollAppear);
    

    Working demo: https://jsfiddle.net/k5ubsecf/1/