Javascript onload isn't working ("Uncaught TypeError: Cannot set property 'document.body' of null ")

17,655

Solution 1

Just to clarify @laruiss and explain what is going on, lets start with your code:

/* body.onload is not recommended, window.onload is. But thats not the main issue*/
window.onload = function() {
    /* You are declaring a function here. Very important: 
     * its a declaration, NOT a function call 
     */
    function UP() {
        if(window.pageYOffset > window.innerHeight)
            document.getElementById('UP').style.display = "block";
    }
    /* So if you want to execute ('call') your function, you have two options:
     * - Remove the declaration around your function aka `function UP(){` and the ending `}`
     * - Call the function here. To make your code work instantly, lets do that.
     */
    UP();
}

When using the onload event, you are actually doing the right thing. True, it's not recommended to actually do that in your DOM, but it should work. The biggest issue that DOM load is subjective. Some browsers will consider the body loaded as soon as the content is in, others will wait for images, and older IE versions won't fire it all! So if you use the recommended window.onload, you should be fine, as it will fire as soon as the DOM is ready. There is another great event for this you might want to consider, which is DOMContentLoaded, but its not as widely supported. Theres a bit more (by clicking through as well) here: https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers.onload

I would also like to add that even though you put your button to display, its has no content so it could appear either empty or if you are resetting your button styles, not at all. Something to keep in mind.

Solution 2

There are a few problems with your code:

  • document.body.onload should be replaced by window.onload, as said in the comments
  • in the onload function, you define a function, but you don't invoke it...

So

document.body.onload = function() {
    function UP() {//Ẩn hiện nút UP
        if(window.pageYOffset > window.innerHeight)
            document.getElementById('UP').style.display = "block";
    }
}

Should be replaced by:

window.onload = function up() { // Could be anonymous, of course, but should not
    if(window.pageYOffset > window.innerHeight)
        document.getElementById('UP').style.display = "block";
}
Share:
17,655
Star Light
Author by

Star Light

I'm just a learner. Learn how to live, learn how to happy, learn what I want to learn. By the way, I'm learning coding...

Updated on June 04, 2022

Comments

  • Star Light
    Star Light about 2 years

    Here is my codes:

    Javascript:

    document.body.onload = function() {
        function UP() {//Ẩn hiện nút UP
            if(window.pageYOffset > window.innerHeight)
                document.getElementById('UP').style.display = "block";
        }
    }
    

    HTML tag:

    <button id="UP" onclick="toTop(350);"></button>
    

    CSS style:

    #UP {display: none;}
    

    My idea is when I scroll down, then UP button will appear. But don't know why, it won't, it even return the error: "Uncaught TypeError: Cannot set property 'document.body' of null". Of couse, I did change other script like this:

    function getReady() {
        UP();
    }
    function UP() {//Ẩn hiện nút UP
        if(window.pageYOffset > window.innerHeight)
            document.getElementById('UP').style.display = "block";
    }
    

    HTML tag:

    <body onload="getReady();">
        <button id="UP" onclick="toTop(350);"></button>
    </body>
    

    It is even more terrible. When I load site, I didn't see onload attr of body tag and the browser didn't return any error for me.

    Some other infomation: I develop on both side, Cr & FF, it all says a same problem. And I'm working on Wordpress source.

  • somethinghere
    somethinghere over 9 years
    Uhm, it does not have to be a defined function. Actually, it should be window.onload = up; or window.onload = function(){}, either anonimous or defined, but not using window.onload as a function definition as it won't be invoked...
  • laruiss
    laruiss over 9 years
    @somethinghere I am not sure what you are saying, but in deed, I forgot to change document.body to window. I Edited my answer to change it.
  • somethinghere
    somethinghere over 9 years
    What Im saying is that defining the event requires you to either pass it a named function or pass it an anonymous function, but not a 'named anonymous function'. (aka calling window.event = function(){} or doing function doEvent(){}; window.event = doEvent; both work. Doing window.event = function doEvent(){} is not good practise if it works, and it shouldn't work because you are technically naming the function twice. You will never be able to call doEvent after that anyway...) Also, you dont need to invoke the function, as the browser automatically invokes window.onload
  • laruiss
    laruiss over 9 years
    Yes, much better explained... Though I disagree ;-) First I don't think it is bad practice, but there I could be wrong. Second, I am not naming the function twice, rather naming the function "UP" and assigning the function (which has a name property whose value is now "UP") to the window property named "onload", which is quite different. And therefore third: it works, and I don't see why it should not.
  • somethinghere
    somethinghere over 9 years
    The thing is, there is no need to name the function as you have declared it as window.onload. You can call it by invoking window.onload(). You can't invoke the function later in your script by calling UP(), so its a bit useless. I posted a little more in my own answer, but essentially you have the right idea, so +1 for you!
  • laruiss
    laruiss over 9 years
    You say "there is no need to name the function", no need to make it work, no, but it is better for debugging to name all the functions (event though the newer and to come JS engines will guess the function names for anonymous functions), and you could choose to call the function recursively within the UP function (which I should have renamed up in lowercase, BTW... there, done). But your answer is a correct answer, of course (even though more versbose ;-)). Nice chatting with you.
  • somethinghere
    somethinghere over 9 years
    I'm quite the talker, yeah. I hadn't thought about recursive (although you could use window.onload() to call recursive as what I meant is that you are doing window.onload = up = function(){}, but yeah it a good idea in that case!). Nice chatting too!
  • Star Light
    Star Light over 9 years
    It works like miracle. Thank you all of you. I will choose the answer of you 'cause even the fool English like me could understand then I think everyone could understand it well.