Search code examples
javascripthtmljquerywebweb-deployment

Uncaught TypeError: Cannot read property 'addEventListener' of null for smooth scroll effect using JS


I'm creating a smooth scroll effect using JS but on the execution of the code I'm facing an error

Uncaught TypeError: Cannot read property 'addEventListener' of null

what the actual problem is?

function smooothScroll(target,duration){
    var target = document.querySelector(target);
    var targetPosition = target.getBoundingClientReact().top;
    var startingPositon = window.pageyOffset;
    var distance = targetPosition - startingPositon;
    var startTime = null;

    function animation(currentTime){
        if (startTime === null) startTime = currentTime;
        var timeElapesd = currentTime - startTime;
        var run = ease(timeElapesd,startingPositon,distance,duration);
        window.scrollTo(0,run); 
    if (timeElapesd < duration) requestAnimationFrame(animation);
    }   

    function ease(t, b, c, d) {
        t /= d/2;
        if (t < 1) return c/2*t*t*t*t + b;
        t -= 2;
        return -c/2 * (t*t*t*t - 2) + b;
    }

    requestAnimationFrame(animation);
    
}
var section1 = document.querySelector('.section1');

section1.addEventListener('click', function() {

   smooothScroll('.section1',3000);

});

<body>
    <div class="box1">
        <a href="#" class="section1">Click Me</a>
    </div>
    <div class="box2">
        <a href="#" class="section2">Thanks for Clicking Me</a>
        <img src="cat.jpg" alt="" class="img">
    </div>
    
</body>
</html>

Solution

  • You have some syntax error inside smooothScroll function:

    • you have target parameter and then also declare the same variable inside function which is confusing and not recommended
    • getBoundingClientRect instead of getBoundingClientReact

    Recommended: try to use block scope variable (let, const) instead of global scope variable var.

    function smooothScroll(selector,duration){
        const targetEle = document.querySelector(selector);
        console.log(targetEle.getBoundingClientRect());
        const targetPosition = targetEle.getBoundingClientRect().top;
        const startingPositon = window.pageyOffset;
        const distance = targetPosition - startingPositon;
        let startTime = null;
    
        function animation(currentTime){
            if (startTime === null) startTime = currentTime;
            var timeElapesd = currentTime - startTime;
            var run = ease(timeElapesd,startingPositon,distance,duration);
            window.scrollTo(0,run); 
        if (timeElapesd < duration) requestAnimationFrame(animation);
        }   
    
        function ease(t, b, c, d) {
            t /= d/2;
            if (t < 1) return c/2*t*t*t*t + b;
            t -= 2;
            return -c/2 * (t*t*t*t - 2) + b;
        }
    
        requestAnimationFrame(animation);
        
    }
    
    var section1 = document.querySelector('.section1');
    
    section1.addEventListener('click', function() {
    
       smooothScroll('.section1',3000);
    
    });
    <html>
    <body>
        <div class="box1">
            <a href="#" class="section1">Click Me</a>
        </div>
        <div class="box2">
            <a href="#" class="section2">Thanks for Clicking Me</a>
            <img src="cat.jpg" alt="" class="img">
        </div>
        
    </body>
    </html>