Uncaught TypeError: Failed to execute 'observe' on 'IntersectionObserver': parameter 1 is not of type 'Element'

Viewed 30066

I'm watching a video on Intersection Observer and I've copied his script word for word and I'm somehow getting this error. Someone had the same error but solved their problem by changing querySelectorAll to querySelector. Even when I copied their code and changed it to querySelector it still didn't work on my end. The code below is mine. I'm using vs code live server.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel='stylesheet' href='style.css'>
    <script src='script.js'></script>
</head>
<body>
    <section class = 'section1'></section>
    <section></section>
    <section></section>
    <section></section>
    <section></section>
    <section></section>
</body>
</html>
const sectionOne = document.querySelector('.section1');

const options = {};

const observer = new IntersectionObserver(function
(entries, observer){
    entries.forEach(entry => {
        console.log(entry);
    });
}, options);

observer.observe(sectionOne);
body{
    padding: 0;
    margin: 0;
}

section{
    height: 100vh;
    width:100%;
}
section:nth-child(odd){
    background: lightcoral
}
6 Answers

The element returns as null because the script runs before the HTML is parsed. I used defer in my script tag to avoid this problem.

<script src='script.js' defer></script>

Actually it looks like the example you posted works fine, you can check it in this JSFiddle I made: https://jsfiddle.net/sandro_paganotti/pomtng6f/3/

const sectionOne = document.querySelector('.section1');
const options = {};

const observer = new IntersectionObserver(function
 (entries, observer){
    entries.forEach(entry => {
       console.log(entry);
 });
}, options);

observer.observe(sectionOne);

Of course being the observer only attached to the first section it'll only fire when the first section enters or leaves the viewport.

Add

$(document).ready(function () { // your code }

document = your div.

You have to be sure that the DOM has loaded, and when it is "ready" then it starts :).

your selection is for the first element as querySelector take the first one if you want to select all then use querySelectorAll, and loop through them so the observer can observe them one by one, it should be as follow:

const sections = document.querySelectorAll('section');

const options = {};

const observer = new IntersectionObserver(function
(entries, observer){
entries.forEach(entry => {
    console.log(entry);
});
}, options);

// loop 
sections.forEach( section => {
observer.observe(section);
});

I believe intersectionObserver.observe can only observe one element. I've noticed that when there are multiple div elements with same class names, observe returns uncaught typeError.

Others who got it working by changing from querySelectorAll to querySelector might be because they had a several div with same class names.

You need to make sure the IntersectionObserver script will run after the DOM is completely loaded.

document.addEventListener("DOMContentLoaded", function(){
    
      // your instersectionobserver code here
    
    
    });
Related