Why does jQuery or a DOM method such as getElementById not find the element?










402















What are the possible reasons for document.getElementById, $("#id") or any other DOM method / jQuery selector not finding the elements?



Example problems include:



  • jQuery silently failing to bind an event handler

  • jQuery "getter" methods (.val(), .html(), .text()) returning undefined


  • A standard DOM method returning null resulting in any of several errors:




    Uncaught TypeError: Cannot set property '...' of null
    Uncaught TypeError: Cannot read property '...' of null




    the most common forms are:




    Uncaught TypeError: Cannot set property 'onclick' of null



    Uncaught TypeError: Cannot read property 'addEventListener' of null



    Uncaught TypeError: Cannot read property 'style' of null












share|improve this question



















  • 27





    Many questions are asked about why a certain DOM element is not found and the reason is often because the JavaScript code is placed before the DOM element. This is intended to be a canonical answer for these type of questions. It's community wiki, so please feel free to improve it.

    – Felix Kling
    Dec 25 '12 at 8:28















402















What are the possible reasons for document.getElementById, $("#id") or any other DOM method / jQuery selector not finding the elements?



Example problems include:



  • jQuery silently failing to bind an event handler

  • jQuery "getter" methods (.val(), .html(), .text()) returning undefined


  • A standard DOM method returning null resulting in any of several errors:




    Uncaught TypeError: Cannot set property '...' of null
    Uncaught TypeError: Cannot read property '...' of null




    the most common forms are:




    Uncaught TypeError: Cannot set property 'onclick' of null



    Uncaught TypeError: Cannot read property 'addEventListener' of null



    Uncaught TypeError: Cannot read property 'style' of null












share|improve this question



















  • 27





    Many questions are asked about why a certain DOM element is not found and the reason is often because the JavaScript code is placed before the DOM element. This is intended to be a canonical answer for these type of questions. It's community wiki, so please feel free to improve it.

    – Felix Kling
    Dec 25 '12 at 8:28













402












402








402


103






What are the possible reasons for document.getElementById, $("#id") or any other DOM method / jQuery selector not finding the elements?



Example problems include:



  • jQuery silently failing to bind an event handler

  • jQuery "getter" methods (.val(), .html(), .text()) returning undefined


  • A standard DOM method returning null resulting in any of several errors:




    Uncaught TypeError: Cannot set property '...' of null
    Uncaught TypeError: Cannot read property '...' of null




    the most common forms are:




    Uncaught TypeError: Cannot set property 'onclick' of null



    Uncaught TypeError: Cannot read property 'addEventListener' of null



    Uncaught TypeError: Cannot read property 'style' of null












share|improve this question
















What are the possible reasons for document.getElementById, $("#id") or any other DOM method / jQuery selector not finding the elements?



Example problems include:



  • jQuery silently failing to bind an event handler

  • jQuery "getter" methods (.val(), .html(), .text()) returning undefined


  • A standard DOM method returning null resulting in any of several errors:




    Uncaught TypeError: Cannot set property '...' of null
    Uncaught TypeError: Cannot read property '...' of null




    the most common forms are:




    Uncaught TypeError: Cannot set property 'onclick' of null



    Uncaught TypeError: Cannot read property 'addEventListener' of null



    Uncaught TypeError: Cannot read property 'style' of null









javascript jquery dom






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 10 '18 at 8:24









T.J. Crowder

690k12112251319




690k12112251319










asked Dec 25 '12 at 8:26









Felix KlingFelix Kling

556k130863920




556k130863920







  • 27





    Many questions are asked about why a certain DOM element is not found and the reason is often because the JavaScript code is placed before the DOM element. This is intended to be a canonical answer for these type of questions. It's community wiki, so please feel free to improve it.

    – Felix Kling
    Dec 25 '12 at 8:28












  • 27





    Many questions are asked about why a certain DOM element is not found and the reason is often because the JavaScript code is placed before the DOM element. This is intended to be a canonical answer for these type of questions. It's community wiki, so please feel free to improve it.

    – Felix Kling
    Dec 25 '12 at 8:28







27




27





Many questions are asked about why a certain DOM element is not found and the reason is often because the JavaScript code is placed before the DOM element. This is intended to be a canonical answer for these type of questions. It's community wiki, so please feel free to improve it.

– Felix Kling
Dec 25 '12 at 8:28





Many questions are asked about why a certain DOM element is not found and the reason is often because the JavaScript code is placed before the DOM element. This is intended to be a canonical answer for these type of questions. It's community wiki, so please feel free to improve it.

– Felix Kling
Dec 25 '12 at 8:28












6 Answers
6






active

oldest

votes


















413





+500









The element you were trying to find wasn’t in the DOM when your script ran.



The position of your DOM-reliant script can have a profound effect upon its behavior. Browsers parse HTML documents from top to bottom. Elements are added to the DOM and scripts are (generally) executed as they're encountered. This means that order matters. Typically, scripts can't find elements which appear later in the markup because those elements have yet to be added to the DOM.



Consider the following markup; script #1 fails to find the <div> while script #2 succeeds:






<script>
console.log("script #1: %o", document.getElementById("test")); // null
</script>
<div id="test">test div</div>
<script>
console.log("script #2: %o", document.getElementById("test")); // <div id="test" ...
</script>





So, what should you do? You've got a few options:




Option 1: Move your script



Move your script further down the page, just before the closing body tag. Organized in this fashion, the rest of the document is parsed before your script is executed:






<body>
<button id="test">click me</button>
<script>
document.getElementById("test").addEventListener("click", function()
console.log("clicked: %o", this);
);
</script>
</body><!-- closing body tag -->





Note: Placing scripts at the bottom is generally considered a best practice.




Option 2: jQuery's ready()



Defer your script until the DOM has been completely parsed, using ready():






<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$(document).ready(function()
$("#test").click(function()
console.log("clicked: %o", this);
);
);
</script>
<button id="test">click me</button>





Note: You could simply bind to DOMContentLoaded or window.onload but each has its caveats. jQuery's ready() delivers a hybrid solution.




Option 3: Event Delegation




Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time.




When an element raises an event (provided that it's a bubbling event and nothing stops its propagation), each parent in that element's ancestry receives the event as well. That allows us to attach a handler to an existing element and sample events as they bubble up from its descendants... even those added after the handler is attached. All we have to do is check the event to see whether it was raised by the desired element and, if so, run our code.



jQuery's on() performs that logic for us. We simply provide an event name, a selector for the desired descendant, and an event handler:






<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$(document).on("click", "#test", function(e)
console.log("clicked: %o", this);
);
</script>
<button id="test">click me</button>





Note: Typically, this pattern is reserved for elements which didn't exist at load-time or to avoid attaching a large amount of handlers. It's also worth pointing out that while I've attached a handler to document (for demonstrative purposes), you should select the nearest reliable ancestor.




Option 4: The defer attribute



Use the defer attribute of <script>.




[defer, a Boolean attribute,] is set to indicate to a browser that the script is meant to be executed after the document has been parsed.







<script src="https://gh-canon.github.io/misc-demos/log-test-click.js" defer></script>
<button id="test">click me</button>





For reference, here's the code from that external script:



document.getElementById("test").addEventListener("click", function(e)
console.log("clicked: %o", this);
);


Note: The defer attribute certainly seems like a magic bullet but it's important to be aware of the caveats...

1. defer can only be used for external scripts, i.e.: those having a src attribute.

2. be aware of browser support, i.e.: buggy implementation in IE < 10






share|improve this answer

























  • Ooh, I missed that as it was in fine print under a jQuery heading :)

    – Quentin
    Nov 6 '18 at 17:11


















131





+100









Short and simple: Because the elements you are looking for do not exist in the document (yet).




For the remainder of this answer I will use getElementById as example, but the same applies to getElementsByTagName, querySelector and any other DOM method that selects elements.



Possible Reasons



There are two reasons why an element might not exist:




  1. An element with the passed ID really does not exist in the document. You should double check that the ID you pass to getElementById really matches an ID of an existing element in the (generated) HTML and that you have not misspelled the ID (IDs are case-sensitive!).



    Incidentally, in the majority of contemporary browsers, which implement querySelector() and querySelectorAll() methods, CSS-style notation is used to retrieve an element by its id, for example: document.querySelector('#elementID'), as opposed to the method by which an element is retrieved by its id under document.getElementById('elementID'); in the first the # character is essential, in the second it would lead to the element not being retrieved.



  2. The element does not exist at the moment you call getElementById.


The latter case is quite common. Browsers parse and process the HTML from top to bottom. That means that any call to a DOM element which occurs before that DOM element appears in the HTML, will fail.



Consider the following example:



<script>
var element = document.getElementById('my_element');
</script>

<div id="my_element"></div>


The div appears after the script. At the moment the script is executed, the element does not exist yet and getElementById will return null.



jQuery



The same applies to all selectors with jQuery. jQuery won't find elements if you misspelled your selector or you are trying to select them before they actually exist.



An added twist is when jQuery is not found because you have loaded the script without protocol and are running from file system:



<script src="//somecdn.somewhere.com/jquery.min.js"></script>


this syntax is used to allow the script to load via HTTPS on a page with protocol https:// and to load the HTTP version on a page with protocol http://



It has the unfortunate side effect of attempting and failing to load file://somecdn.somewhere.com...




Solutions



Before you make a call to getElementById (or any DOM method for that matter), make sure the elements you want to access exist, i.e. the DOM is loaded.



This can be ensured by simply putting your JavaScript after the corresponding DOM element



<div id="my_element"></div>

<script>
var element = document.getElementById('my_element');
</script>


in which case you can also put the code just before the closing body tag (</body>) (all DOM elements will be available at the time the script is executed).



Other solutions include listening to the load [MDN] or DOMContentLoaded [MDN] events. In these cases it does not matter where in the document you place the JavaScript code, you just have to remember to put all DOM processing code in the event handlers.



Example:



window.onload = function() 
// process DOM elements here
;

// or

// does not work IE 8 and below
document.addEventListener('DOMContentLoaded', function()
// process DOM elements here
);


Please see the articles at quirksmode.org for more information regarding event handling and browser differences.



jQuery



First make sure that jQuery is loaded properly. Use the browser's developer tools to find out whether the jQuery file was found and correct the URL if it wasn't (e.g. add the http: or https: scheme at the beginning, adjust the path, etc.)



Listening to the load/DOMContentLoaded events is exactly what jQuery is doing with .ready() [docs]. All your jQuery code that affects DOM element should be inside that event handler.



In fact, the jQuery tutorial explicitly states:




As almost everything we do when using jQuery reads or manipulates the document object model (DOM), we need to make sure that we start adding events etc. as soon as the DOM is ready.



To do this, we register a ready event for the document.



$(document).ready(function() 
// do stuff when DOM is ready
);



Alternatively you can also use the shorthand syntax:



$(function() 
// do stuff when DOM is ready
);


Both are equivalent.






share|improve this answer




















  • 1





    Would it be worth amending the last bit about the ready event to reflect the "newer" preferred syntax, or is it better to leave it as-is so that it works across older versions?

    – Tieson T.
    Dec 25 '12 at 8:56







  • 1





    For jQuery, is it worth also adding in the alternative $(window).load() (and possibly syntactic alternatives to the $(document).ready(), $(function())? It seems related, but it feels slightly tangential to the point you're making.

    – David Thomas
    Dec 25 '12 at 8:58











  • @David: Good point with .load. Regarding syntax alternatives, they could be looked up in the documentation but since answers should be self contained, it might actually be worth adding them. Then again, I'm pretty sure this specific bit about jQuery was answered already and is probably covered in another answers and linking to it might suffice.

    – Felix Kling
    Dec 25 '12 at 9:00







  • 1





    @David: I have to revise: Apparently .load is deprecated: api.jquery.com/load-event. I don't know if it's for images only or window as well.

    – Felix Kling
    Dec 25 '12 at 9:03







  • 1





    @David: No worries :) Even if you are not sure, it's good that you mentioned it. I will probably add just some simple code snippets to show the usage. Thanks for your input!

    – Felix Kling
    Dec 25 '12 at 9:05


















12














Reasons why id based selectors don't work



  1. The element/DOM with id specified doesn't exist yet.

  2. The element exists, but it is not registered in DOM [in case of HTML nodes appended dynamically from Ajax responses].

  3. More than one element with the same id is present which is causing a conflict.

Solutions



  1. Try to access the element after its declaration or alternatively use stuff like $(document).ready();


  2. For elements coming from Ajax responses, use the .bind() method of jQuery. Older versions of jQuery had .live() for the same.


  3. Use tools [for example, webdeveloper plugin for browsers] to find duplicate ids and remove them.






share|improve this answer
































    10














    As @FelixKling pointed out, the most likely scenario is that the nodes you are looking for do not exist (yet).



    However, modern development practices can often manipulate document elements outside of the document tree either with DocumentFragments or simply detaching/reattaching current elements directly. Such techniques may be used as part of JavaScript templating or to avoid excessive repaint/reflow operations while the elements in question are being heavily altered.



    Similarly, the new "Shadow DOM" functionality being rolled out across modern browsers allows elements to be part of the document, but not query-able by document.getElementById and all of its sibling methods (querySelector, etc.). This is done to encapsulate functionality and specifically hide it.



    Again, though, it is most likely that the element you are looking for simply is not (yet) in the document, and you should do as Felix suggests. However, you should also be aware that that is increasingly not the only reason that an element might be unfindable (either temporarily or permanently).






    share|improve this answer






























      10














      If the element you are trying to access is inside an iframe and you try to access it outside the context of the iframe this will also cause it to fail.



      If you want to get an element in an iframe you can find out how here.






      share|improve this answer
































        -2














        Try putting document.getElementById in setTimeout()



        E.g.



        setTimeout(function()
        console.log(document.getElementById('whatever'));
        , 100);


        If this works, then it's just a timing problem.






        share|improve this answer


















        • 1





          This is unreliable. It’s not a “timing problem”. See the other answers here for real solutions and explanations.

          – Xufox
          Aug 10 '18 at 14:05









        protected by VisioN Jan 27 '13 at 12:11



        Thank you for your interest in this question.
        Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



        Would you like to answer one of these unanswered questions instead?














        6 Answers
        6






        active

        oldest

        votes








        6 Answers
        6






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        413





        +500









        The element you were trying to find wasn’t in the DOM when your script ran.



        The position of your DOM-reliant script can have a profound effect upon its behavior. Browsers parse HTML documents from top to bottom. Elements are added to the DOM and scripts are (generally) executed as they're encountered. This means that order matters. Typically, scripts can't find elements which appear later in the markup because those elements have yet to be added to the DOM.



        Consider the following markup; script #1 fails to find the <div> while script #2 succeeds:






        <script>
        console.log("script #1: %o", document.getElementById("test")); // null
        </script>
        <div id="test">test div</div>
        <script>
        console.log("script #2: %o", document.getElementById("test")); // <div id="test" ...
        </script>





        So, what should you do? You've got a few options:




        Option 1: Move your script



        Move your script further down the page, just before the closing body tag. Organized in this fashion, the rest of the document is parsed before your script is executed:






        <body>
        <button id="test">click me</button>
        <script>
        document.getElementById("test").addEventListener("click", function()
        console.log("clicked: %o", this);
        );
        </script>
        </body><!-- closing body tag -->





        Note: Placing scripts at the bottom is generally considered a best practice.




        Option 2: jQuery's ready()



        Defer your script until the DOM has been completely parsed, using ready():






        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <script>
        $(document).ready(function()
        $("#test").click(function()
        console.log("clicked: %o", this);
        );
        );
        </script>
        <button id="test">click me</button>





        Note: You could simply bind to DOMContentLoaded or window.onload but each has its caveats. jQuery's ready() delivers a hybrid solution.




        Option 3: Event Delegation




        Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time.




        When an element raises an event (provided that it's a bubbling event and nothing stops its propagation), each parent in that element's ancestry receives the event as well. That allows us to attach a handler to an existing element and sample events as they bubble up from its descendants... even those added after the handler is attached. All we have to do is check the event to see whether it was raised by the desired element and, if so, run our code.



        jQuery's on() performs that logic for us. We simply provide an event name, a selector for the desired descendant, and an event handler:






        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <script>
        $(document).on("click", "#test", function(e)
        console.log("clicked: %o", this);
        );
        </script>
        <button id="test">click me</button>





        Note: Typically, this pattern is reserved for elements which didn't exist at load-time or to avoid attaching a large amount of handlers. It's also worth pointing out that while I've attached a handler to document (for demonstrative purposes), you should select the nearest reliable ancestor.




        Option 4: The defer attribute



        Use the defer attribute of <script>.




        [defer, a Boolean attribute,] is set to indicate to a browser that the script is meant to be executed after the document has been parsed.







        <script src="https://gh-canon.github.io/misc-demos/log-test-click.js" defer></script>
        <button id="test">click me</button>





        For reference, here's the code from that external script:



        document.getElementById("test").addEventListener("click", function(e)
        console.log("clicked: %o", this);
        );


        Note: The defer attribute certainly seems like a magic bullet but it's important to be aware of the caveats...

        1. defer can only be used for external scripts, i.e.: those having a src attribute.

        2. be aware of browser support, i.e.: buggy implementation in IE < 10






        share|improve this answer

























        • Ooh, I missed that as it was in fine print under a jQuery heading :)

          – Quentin
          Nov 6 '18 at 17:11















        413





        +500









        The element you were trying to find wasn’t in the DOM when your script ran.



        The position of your DOM-reliant script can have a profound effect upon its behavior. Browsers parse HTML documents from top to bottom. Elements are added to the DOM and scripts are (generally) executed as they're encountered. This means that order matters. Typically, scripts can't find elements which appear later in the markup because those elements have yet to be added to the DOM.



        Consider the following markup; script #1 fails to find the <div> while script #2 succeeds:






        <script>
        console.log("script #1: %o", document.getElementById("test")); // null
        </script>
        <div id="test">test div</div>
        <script>
        console.log("script #2: %o", document.getElementById("test")); // <div id="test" ...
        </script>





        So, what should you do? You've got a few options:




        Option 1: Move your script



        Move your script further down the page, just before the closing body tag. Organized in this fashion, the rest of the document is parsed before your script is executed:






        <body>
        <button id="test">click me</button>
        <script>
        document.getElementById("test").addEventListener("click", function()
        console.log("clicked: %o", this);
        );
        </script>
        </body><!-- closing body tag -->





        Note: Placing scripts at the bottom is generally considered a best practice.




        Option 2: jQuery's ready()



        Defer your script until the DOM has been completely parsed, using ready():






        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <script>
        $(document).ready(function()
        $("#test").click(function()
        console.log("clicked: %o", this);
        );
        );
        </script>
        <button id="test">click me</button>





        Note: You could simply bind to DOMContentLoaded or window.onload but each has its caveats. jQuery's ready() delivers a hybrid solution.




        Option 3: Event Delegation




        Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time.




        When an element raises an event (provided that it's a bubbling event and nothing stops its propagation), each parent in that element's ancestry receives the event as well. That allows us to attach a handler to an existing element and sample events as they bubble up from its descendants... even those added after the handler is attached. All we have to do is check the event to see whether it was raised by the desired element and, if so, run our code.



        jQuery's on() performs that logic for us. We simply provide an event name, a selector for the desired descendant, and an event handler:






        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <script>
        $(document).on("click", "#test", function(e)
        console.log("clicked: %o", this);
        );
        </script>
        <button id="test">click me</button>





        Note: Typically, this pattern is reserved for elements which didn't exist at load-time or to avoid attaching a large amount of handlers. It's also worth pointing out that while I've attached a handler to document (for demonstrative purposes), you should select the nearest reliable ancestor.




        Option 4: The defer attribute



        Use the defer attribute of <script>.




        [defer, a Boolean attribute,] is set to indicate to a browser that the script is meant to be executed after the document has been parsed.







        <script src="https://gh-canon.github.io/misc-demos/log-test-click.js" defer></script>
        <button id="test">click me</button>





        For reference, here's the code from that external script:



        document.getElementById("test").addEventListener("click", function(e)
        console.log("clicked: %o", this);
        );


        Note: The defer attribute certainly seems like a magic bullet but it's important to be aware of the caveats...

        1. defer can only be used for external scripts, i.e.: those having a src attribute.

        2. be aware of browser support, i.e.: buggy implementation in IE < 10






        share|improve this answer

























        • Ooh, I missed that as it was in fine print under a jQuery heading :)

          – Quentin
          Nov 6 '18 at 17:11













        413





        +500







        413





        +500



        413




        +500





        The element you were trying to find wasn’t in the DOM when your script ran.



        The position of your DOM-reliant script can have a profound effect upon its behavior. Browsers parse HTML documents from top to bottom. Elements are added to the DOM and scripts are (generally) executed as they're encountered. This means that order matters. Typically, scripts can't find elements which appear later in the markup because those elements have yet to be added to the DOM.



        Consider the following markup; script #1 fails to find the <div> while script #2 succeeds:






        <script>
        console.log("script #1: %o", document.getElementById("test")); // null
        </script>
        <div id="test">test div</div>
        <script>
        console.log("script #2: %o", document.getElementById("test")); // <div id="test" ...
        </script>





        So, what should you do? You've got a few options:




        Option 1: Move your script



        Move your script further down the page, just before the closing body tag. Organized in this fashion, the rest of the document is parsed before your script is executed:






        <body>
        <button id="test">click me</button>
        <script>
        document.getElementById("test").addEventListener("click", function()
        console.log("clicked: %o", this);
        );
        </script>
        </body><!-- closing body tag -->





        Note: Placing scripts at the bottom is generally considered a best practice.




        Option 2: jQuery's ready()



        Defer your script until the DOM has been completely parsed, using ready():






        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <script>
        $(document).ready(function()
        $("#test").click(function()
        console.log("clicked: %o", this);
        );
        );
        </script>
        <button id="test">click me</button>





        Note: You could simply bind to DOMContentLoaded or window.onload but each has its caveats. jQuery's ready() delivers a hybrid solution.




        Option 3: Event Delegation




        Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time.




        When an element raises an event (provided that it's a bubbling event and nothing stops its propagation), each parent in that element's ancestry receives the event as well. That allows us to attach a handler to an existing element and sample events as they bubble up from its descendants... even those added after the handler is attached. All we have to do is check the event to see whether it was raised by the desired element and, if so, run our code.



        jQuery's on() performs that logic for us. We simply provide an event name, a selector for the desired descendant, and an event handler:






        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <script>
        $(document).on("click", "#test", function(e)
        console.log("clicked: %o", this);
        );
        </script>
        <button id="test">click me</button>





        Note: Typically, this pattern is reserved for elements which didn't exist at load-time or to avoid attaching a large amount of handlers. It's also worth pointing out that while I've attached a handler to document (for demonstrative purposes), you should select the nearest reliable ancestor.




        Option 4: The defer attribute



        Use the defer attribute of <script>.




        [defer, a Boolean attribute,] is set to indicate to a browser that the script is meant to be executed after the document has been parsed.







        <script src="https://gh-canon.github.io/misc-demos/log-test-click.js" defer></script>
        <button id="test">click me</button>





        For reference, here's the code from that external script:



        document.getElementById("test").addEventListener("click", function(e)
        console.log("clicked: %o", this);
        );


        Note: The defer attribute certainly seems like a magic bullet but it's important to be aware of the caveats...

        1. defer can only be used for external scripts, i.e.: those having a src attribute.

        2. be aware of browser support, i.e.: buggy implementation in IE < 10






        share|improve this answer















        The element you were trying to find wasn’t in the DOM when your script ran.



        The position of your DOM-reliant script can have a profound effect upon its behavior. Browsers parse HTML documents from top to bottom. Elements are added to the DOM and scripts are (generally) executed as they're encountered. This means that order matters. Typically, scripts can't find elements which appear later in the markup because those elements have yet to be added to the DOM.



        Consider the following markup; script #1 fails to find the <div> while script #2 succeeds:






        <script>
        console.log("script #1: %o", document.getElementById("test")); // null
        </script>
        <div id="test">test div</div>
        <script>
        console.log("script #2: %o", document.getElementById("test")); // <div id="test" ...
        </script>





        So, what should you do? You've got a few options:




        Option 1: Move your script



        Move your script further down the page, just before the closing body tag. Organized in this fashion, the rest of the document is parsed before your script is executed:






        <body>
        <button id="test">click me</button>
        <script>
        document.getElementById("test").addEventListener("click", function()
        console.log("clicked: %o", this);
        );
        </script>
        </body><!-- closing body tag -->





        Note: Placing scripts at the bottom is generally considered a best practice.




        Option 2: jQuery's ready()



        Defer your script until the DOM has been completely parsed, using ready():






        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <script>
        $(document).ready(function()
        $("#test").click(function()
        console.log("clicked: %o", this);
        );
        );
        </script>
        <button id="test">click me</button>





        Note: You could simply bind to DOMContentLoaded or window.onload but each has its caveats. jQuery's ready() delivers a hybrid solution.




        Option 3: Event Delegation




        Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time.




        When an element raises an event (provided that it's a bubbling event and nothing stops its propagation), each parent in that element's ancestry receives the event as well. That allows us to attach a handler to an existing element and sample events as they bubble up from its descendants... even those added after the handler is attached. All we have to do is check the event to see whether it was raised by the desired element and, if so, run our code.



        jQuery's on() performs that logic for us. We simply provide an event name, a selector for the desired descendant, and an event handler:






        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <script>
        $(document).on("click", "#test", function(e)
        console.log("clicked: %o", this);
        );
        </script>
        <button id="test">click me</button>





        Note: Typically, this pattern is reserved for elements which didn't exist at load-time or to avoid attaching a large amount of handlers. It's also worth pointing out that while I've attached a handler to document (for demonstrative purposes), you should select the nearest reliable ancestor.




        Option 4: The defer attribute



        Use the defer attribute of <script>.




        [defer, a Boolean attribute,] is set to indicate to a browser that the script is meant to be executed after the document has been parsed.







        <script src="https://gh-canon.github.io/misc-demos/log-test-click.js" defer></script>
        <button id="test">click me</button>





        For reference, here's the code from that external script:



        document.getElementById("test").addEventListener("click", function(e)
        console.log("clicked: %o", this);
        );


        Note: The defer attribute certainly seems like a magic bullet but it's important to be aware of the caveats...

        1. defer can only be used for external scripts, i.e.: those having a src attribute.

        2. be aware of browser support, i.e.: buggy implementation in IE < 10






        <script>
        console.log("script #1: %o", document.getElementById("test")); // null
        </script>
        <div id="test">test div</div>
        <script>
        console.log("script #2: %o", document.getElementById("test")); // <div id="test" ...
        </script>





        <script>
        console.log("script #1: %o", document.getElementById("test")); // null
        </script>
        <div id="test">test div</div>
        <script>
        console.log("script #2: %o", document.getElementById("test")); // <div id="test" ...
        </script>





        <body>
        <button id="test">click me</button>
        <script>
        document.getElementById("test").addEventListener("click", function()
        console.log("clicked: %o", this);
        );
        </script>
        </body><!-- closing body tag -->





        <body>
        <button id="test">click me</button>
        <script>
        document.getElementById("test").addEventListener("click", function()
        console.log("clicked: %o", this);
        );
        </script>
        </body><!-- closing body tag -->





        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <script>
        $(document).ready(function()
        $("#test").click(function()
        console.log("clicked: %o", this);
        );
        );
        </script>
        <button id="test">click me</button>





        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <script>
        $(document).ready(function()
        $("#test").click(function()
        console.log("clicked: %o", this);
        );
        );
        </script>
        <button id="test">click me</button>





        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <script>
        $(document).on("click", "#test", function(e)
        console.log("clicked: %o", this);
        );
        </script>
        <button id="test">click me</button>





        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <script>
        $(document).on("click", "#test", function(e)
        console.log("clicked: %o", this);
        );
        </script>
        <button id="test">click me</button>





        <script src="https://gh-canon.github.io/misc-demos/log-test-click.js" defer></script>
        <button id="test">click me</button>





        <script src="https://gh-canon.github.io/misc-demos/log-test-click.js" defer></script>
        <button id="test">click me</button>






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jul 26 '17 at 14:11

























        answered Jan 3 '12 at 18:06









        canoncanon

        31.1k85578




        31.1k85578












        • Ooh, I missed that as it was in fine print under a jQuery heading :)

          – Quentin
          Nov 6 '18 at 17:11

















        • Ooh, I missed that as it was in fine print under a jQuery heading :)

          – Quentin
          Nov 6 '18 at 17:11
















        Ooh, I missed that as it was in fine print under a jQuery heading :)

        – Quentin
        Nov 6 '18 at 17:11





        Ooh, I missed that as it was in fine print under a jQuery heading :)

        – Quentin
        Nov 6 '18 at 17:11













        131





        +100









        Short and simple: Because the elements you are looking for do not exist in the document (yet).




        For the remainder of this answer I will use getElementById as example, but the same applies to getElementsByTagName, querySelector and any other DOM method that selects elements.



        Possible Reasons



        There are two reasons why an element might not exist:




        1. An element with the passed ID really does not exist in the document. You should double check that the ID you pass to getElementById really matches an ID of an existing element in the (generated) HTML and that you have not misspelled the ID (IDs are case-sensitive!).



          Incidentally, in the majority of contemporary browsers, which implement querySelector() and querySelectorAll() methods, CSS-style notation is used to retrieve an element by its id, for example: document.querySelector('#elementID'), as opposed to the method by which an element is retrieved by its id under document.getElementById('elementID'); in the first the # character is essential, in the second it would lead to the element not being retrieved.



        2. The element does not exist at the moment you call getElementById.


        The latter case is quite common. Browsers parse and process the HTML from top to bottom. That means that any call to a DOM element which occurs before that DOM element appears in the HTML, will fail.



        Consider the following example:



        <script>
        var element = document.getElementById('my_element');
        </script>

        <div id="my_element"></div>


        The div appears after the script. At the moment the script is executed, the element does not exist yet and getElementById will return null.



        jQuery



        The same applies to all selectors with jQuery. jQuery won't find elements if you misspelled your selector or you are trying to select them before they actually exist.



        An added twist is when jQuery is not found because you have loaded the script without protocol and are running from file system:



        <script src="//somecdn.somewhere.com/jquery.min.js"></script>


        this syntax is used to allow the script to load via HTTPS on a page with protocol https:// and to load the HTTP version on a page with protocol http://



        It has the unfortunate side effect of attempting and failing to load file://somecdn.somewhere.com...




        Solutions



        Before you make a call to getElementById (or any DOM method for that matter), make sure the elements you want to access exist, i.e. the DOM is loaded.



        This can be ensured by simply putting your JavaScript after the corresponding DOM element



        <div id="my_element"></div>

        <script>
        var element = document.getElementById('my_element');
        </script>


        in which case you can also put the code just before the closing body tag (</body>) (all DOM elements will be available at the time the script is executed).



        Other solutions include listening to the load [MDN] or DOMContentLoaded [MDN] events. In these cases it does not matter where in the document you place the JavaScript code, you just have to remember to put all DOM processing code in the event handlers.



        Example:



        window.onload = function() 
        // process DOM elements here
        ;

        // or

        // does not work IE 8 and below
        document.addEventListener('DOMContentLoaded', function()
        // process DOM elements here
        );


        Please see the articles at quirksmode.org for more information regarding event handling and browser differences.



        jQuery



        First make sure that jQuery is loaded properly. Use the browser's developer tools to find out whether the jQuery file was found and correct the URL if it wasn't (e.g. add the http: or https: scheme at the beginning, adjust the path, etc.)



        Listening to the load/DOMContentLoaded events is exactly what jQuery is doing with .ready() [docs]. All your jQuery code that affects DOM element should be inside that event handler.



        In fact, the jQuery tutorial explicitly states:




        As almost everything we do when using jQuery reads or manipulates the document object model (DOM), we need to make sure that we start adding events etc. as soon as the DOM is ready.



        To do this, we register a ready event for the document.



        $(document).ready(function() 
        // do stuff when DOM is ready
        );



        Alternatively you can also use the shorthand syntax:



        $(function() 
        // do stuff when DOM is ready
        );


        Both are equivalent.






        share|improve this answer




















        • 1





          Would it be worth amending the last bit about the ready event to reflect the "newer" preferred syntax, or is it better to leave it as-is so that it works across older versions?

          – Tieson T.
          Dec 25 '12 at 8:56







        • 1





          For jQuery, is it worth also adding in the alternative $(window).load() (and possibly syntactic alternatives to the $(document).ready(), $(function())? It seems related, but it feels slightly tangential to the point you're making.

          – David Thomas
          Dec 25 '12 at 8:58











        • @David: Good point with .load. Regarding syntax alternatives, they could be looked up in the documentation but since answers should be self contained, it might actually be worth adding them. Then again, I'm pretty sure this specific bit about jQuery was answered already and is probably covered in another answers and linking to it might suffice.

          – Felix Kling
          Dec 25 '12 at 9:00







        • 1





          @David: I have to revise: Apparently .load is deprecated: api.jquery.com/load-event. I don't know if it's for images only or window as well.

          – Felix Kling
          Dec 25 '12 at 9:03







        • 1





          @David: No worries :) Even if you are not sure, it's good that you mentioned it. I will probably add just some simple code snippets to show the usage. Thanks for your input!

          – Felix Kling
          Dec 25 '12 at 9:05















        131





        +100









        Short and simple: Because the elements you are looking for do not exist in the document (yet).




        For the remainder of this answer I will use getElementById as example, but the same applies to getElementsByTagName, querySelector and any other DOM method that selects elements.



        Possible Reasons



        There are two reasons why an element might not exist:




        1. An element with the passed ID really does not exist in the document. You should double check that the ID you pass to getElementById really matches an ID of an existing element in the (generated) HTML and that you have not misspelled the ID (IDs are case-sensitive!).



          Incidentally, in the majority of contemporary browsers, which implement querySelector() and querySelectorAll() methods, CSS-style notation is used to retrieve an element by its id, for example: document.querySelector('#elementID'), as opposed to the method by which an element is retrieved by its id under document.getElementById('elementID'); in the first the # character is essential, in the second it would lead to the element not being retrieved.



        2. The element does not exist at the moment you call getElementById.


        The latter case is quite common. Browsers parse and process the HTML from top to bottom. That means that any call to a DOM element which occurs before that DOM element appears in the HTML, will fail.



        Consider the following example:



        <script>
        var element = document.getElementById('my_element');
        </script>

        <div id="my_element"></div>


        The div appears after the script. At the moment the script is executed, the element does not exist yet and getElementById will return null.



        jQuery



        The same applies to all selectors with jQuery. jQuery won't find elements if you misspelled your selector or you are trying to select them before they actually exist.



        An added twist is when jQuery is not found because you have loaded the script without protocol and are running from file system:



        <script src="//somecdn.somewhere.com/jquery.min.js"></script>


        this syntax is used to allow the script to load via HTTPS on a page with protocol https:// and to load the HTTP version on a page with protocol http://



        It has the unfortunate side effect of attempting and failing to load file://somecdn.somewhere.com...




        Solutions



        Before you make a call to getElementById (or any DOM method for that matter), make sure the elements you want to access exist, i.e. the DOM is loaded.



        This can be ensured by simply putting your JavaScript after the corresponding DOM element



        <div id="my_element"></div>

        <script>
        var element = document.getElementById('my_element');
        </script>


        in which case you can also put the code just before the closing body tag (</body>) (all DOM elements will be available at the time the script is executed).



        Other solutions include listening to the load [MDN] or DOMContentLoaded [MDN] events. In these cases it does not matter where in the document you place the JavaScript code, you just have to remember to put all DOM processing code in the event handlers.



        Example:



        window.onload = function() 
        // process DOM elements here
        ;

        // or

        // does not work IE 8 and below
        document.addEventListener('DOMContentLoaded', function()
        // process DOM elements here
        );


        Please see the articles at quirksmode.org for more information regarding event handling and browser differences.



        jQuery



        First make sure that jQuery is loaded properly. Use the browser's developer tools to find out whether the jQuery file was found and correct the URL if it wasn't (e.g. add the http: or https: scheme at the beginning, adjust the path, etc.)



        Listening to the load/DOMContentLoaded events is exactly what jQuery is doing with .ready() [docs]. All your jQuery code that affects DOM element should be inside that event handler.



        In fact, the jQuery tutorial explicitly states:




        As almost everything we do when using jQuery reads or manipulates the document object model (DOM), we need to make sure that we start adding events etc. as soon as the DOM is ready.



        To do this, we register a ready event for the document.



        $(document).ready(function() 
        // do stuff when DOM is ready
        );



        Alternatively you can also use the shorthand syntax:



        $(function() 
        // do stuff when DOM is ready
        );


        Both are equivalent.






        share|improve this answer




















        • 1





          Would it be worth amending the last bit about the ready event to reflect the "newer" preferred syntax, or is it better to leave it as-is so that it works across older versions?

          – Tieson T.
          Dec 25 '12 at 8:56







        • 1





          For jQuery, is it worth also adding in the alternative $(window).load() (and possibly syntactic alternatives to the $(document).ready(), $(function())? It seems related, but it feels slightly tangential to the point you're making.

          – David Thomas
          Dec 25 '12 at 8:58











        • @David: Good point with .load. Regarding syntax alternatives, they could be looked up in the documentation but since answers should be self contained, it might actually be worth adding them. Then again, I'm pretty sure this specific bit about jQuery was answered already and is probably covered in another answers and linking to it might suffice.

          – Felix Kling
          Dec 25 '12 at 9:00







        • 1





          @David: I have to revise: Apparently .load is deprecated: api.jquery.com/load-event. I don't know if it's for images only or window as well.

          – Felix Kling
          Dec 25 '12 at 9:03







        • 1





          @David: No worries :) Even if you are not sure, it's good that you mentioned it. I will probably add just some simple code snippets to show the usage. Thanks for your input!

          – Felix Kling
          Dec 25 '12 at 9:05













        131





        +100







        131





        +100



        131




        +100





        Short and simple: Because the elements you are looking for do not exist in the document (yet).




        For the remainder of this answer I will use getElementById as example, but the same applies to getElementsByTagName, querySelector and any other DOM method that selects elements.



        Possible Reasons



        There are two reasons why an element might not exist:




        1. An element with the passed ID really does not exist in the document. You should double check that the ID you pass to getElementById really matches an ID of an existing element in the (generated) HTML and that you have not misspelled the ID (IDs are case-sensitive!).



          Incidentally, in the majority of contemporary browsers, which implement querySelector() and querySelectorAll() methods, CSS-style notation is used to retrieve an element by its id, for example: document.querySelector('#elementID'), as opposed to the method by which an element is retrieved by its id under document.getElementById('elementID'); in the first the # character is essential, in the second it would lead to the element not being retrieved.



        2. The element does not exist at the moment you call getElementById.


        The latter case is quite common. Browsers parse and process the HTML from top to bottom. That means that any call to a DOM element which occurs before that DOM element appears in the HTML, will fail.



        Consider the following example:



        <script>
        var element = document.getElementById('my_element');
        </script>

        <div id="my_element"></div>


        The div appears after the script. At the moment the script is executed, the element does not exist yet and getElementById will return null.



        jQuery



        The same applies to all selectors with jQuery. jQuery won't find elements if you misspelled your selector or you are trying to select them before they actually exist.



        An added twist is when jQuery is not found because you have loaded the script without protocol and are running from file system:



        <script src="//somecdn.somewhere.com/jquery.min.js"></script>


        this syntax is used to allow the script to load via HTTPS on a page with protocol https:// and to load the HTTP version on a page with protocol http://



        It has the unfortunate side effect of attempting and failing to load file://somecdn.somewhere.com...




        Solutions



        Before you make a call to getElementById (or any DOM method for that matter), make sure the elements you want to access exist, i.e. the DOM is loaded.



        This can be ensured by simply putting your JavaScript after the corresponding DOM element



        <div id="my_element"></div>

        <script>
        var element = document.getElementById('my_element');
        </script>


        in which case you can also put the code just before the closing body tag (</body>) (all DOM elements will be available at the time the script is executed).



        Other solutions include listening to the load [MDN] or DOMContentLoaded [MDN] events. In these cases it does not matter where in the document you place the JavaScript code, you just have to remember to put all DOM processing code in the event handlers.



        Example:



        window.onload = function() 
        // process DOM elements here
        ;

        // or

        // does not work IE 8 and below
        document.addEventListener('DOMContentLoaded', function()
        // process DOM elements here
        );


        Please see the articles at quirksmode.org for more information regarding event handling and browser differences.



        jQuery



        First make sure that jQuery is loaded properly. Use the browser's developer tools to find out whether the jQuery file was found and correct the URL if it wasn't (e.g. add the http: or https: scheme at the beginning, adjust the path, etc.)



        Listening to the load/DOMContentLoaded events is exactly what jQuery is doing with .ready() [docs]. All your jQuery code that affects DOM element should be inside that event handler.



        In fact, the jQuery tutorial explicitly states:




        As almost everything we do when using jQuery reads or manipulates the document object model (DOM), we need to make sure that we start adding events etc. as soon as the DOM is ready.



        To do this, we register a ready event for the document.



        $(document).ready(function() 
        // do stuff when DOM is ready
        );



        Alternatively you can also use the shorthand syntax:



        $(function() 
        // do stuff when DOM is ready
        );


        Both are equivalent.






        share|improve this answer















        Short and simple: Because the elements you are looking for do not exist in the document (yet).




        For the remainder of this answer I will use getElementById as example, but the same applies to getElementsByTagName, querySelector and any other DOM method that selects elements.



        Possible Reasons



        There are two reasons why an element might not exist:




        1. An element with the passed ID really does not exist in the document. You should double check that the ID you pass to getElementById really matches an ID of an existing element in the (generated) HTML and that you have not misspelled the ID (IDs are case-sensitive!).



          Incidentally, in the majority of contemporary browsers, which implement querySelector() and querySelectorAll() methods, CSS-style notation is used to retrieve an element by its id, for example: document.querySelector('#elementID'), as opposed to the method by which an element is retrieved by its id under document.getElementById('elementID'); in the first the # character is essential, in the second it would lead to the element not being retrieved.



        2. The element does not exist at the moment you call getElementById.


        The latter case is quite common. Browsers parse and process the HTML from top to bottom. That means that any call to a DOM element which occurs before that DOM element appears in the HTML, will fail.



        Consider the following example:



        <script>
        var element = document.getElementById('my_element');
        </script>

        <div id="my_element"></div>


        The div appears after the script. At the moment the script is executed, the element does not exist yet and getElementById will return null.



        jQuery



        The same applies to all selectors with jQuery. jQuery won't find elements if you misspelled your selector or you are trying to select them before they actually exist.



        An added twist is when jQuery is not found because you have loaded the script without protocol and are running from file system:



        <script src="//somecdn.somewhere.com/jquery.min.js"></script>


        this syntax is used to allow the script to load via HTTPS on a page with protocol https:// and to load the HTTP version on a page with protocol http://



        It has the unfortunate side effect of attempting and failing to load file://somecdn.somewhere.com...




        Solutions



        Before you make a call to getElementById (or any DOM method for that matter), make sure the elements you want to access exist, i.e. the DOM is loaded.



        This can be ensured by simply putting your JavaScript after the corresponding DOM element



        <div id="my_element"></div>

        <script>
        var element = document.getElementById('my_element');
        </script>


        in which case you can also put the code just before the closing body tag (</body>) (all DOM elements will be available at the time the script is executed).



        Other solutions include listening to the load [MDN] or DOMContentLoaded [MDN] events. In these cases it does not matter where in the document you place the JavaScript code, you just have to remember to put all DOM processing code in the event handlers.



        Example:



        window.onload = function() 
        // process DOM elements here
        ;

        // or

        // does not work IE 8 and below
        document.addEventListener('DOMContentLoaded', function()
        // process DOM elements here
        );


        Please see the articles at quirksmode.org for more information regarding event handling and browser differences.



        jQuery



        First make sure that jQuery is loaded properly. Use the browser's developer tools to find out whether the jQuery file was found and correct the URL if it wasn't (e.g. add the http: or https: scheme at the beginning, adjust the path, etc.)



        Listening to the load/DOMContentLoaded events is exactly what jQuery is doing with .ready() [docs]. All your jQuery code that affects DOM element should be inside that event handler.



        In fact, the jQuery tutorial explicitly states:




        As almost everything we do when using jQuery reads or manipulates the document object model (DOM), we need to make sure that we start adding events etc. as soon as the DOM is ready.



        To do this, we register a ready event for the document.



        $(document).ready(function() 
        // do stuff when DOM is ready
        );



        Alternatively you can also use the shorthand syntax:



        $(function() 
        // do stuff when DOM is ready
        );


        Both are equivalent.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Mar 13 '17 at 23:46


























        community wiki





        11 revs, 3 users 94%
        Felix Kling








        • 1





          Would it be worth amending the last bit about the ready event to reflect the "newer" preferred syntax, or is it better to leave it as-is so that it works across older versions?

          – Tieson T.
          Dec 25 '12 at 8:56







        • 1





          For jQuery, is it worth also adding in the alternative $(window).load() (and possibly syntactic alternatives to the $(document).ready(), $(function())? It seems related, but it feels slightly tangential to the point you're making.

          – David Thomas
          Dec 25 '12 at 8:58











        • @David: Good point with .load. Regarding syntax alternatives, they could be looked up in the documentation but since answers should be self contained, it might actually be worth adding them. Then again, I'm pretty sure this specific bit about jQuery was answered already and is probably covered in another answers and linking to it might suffice.

          – Felix Kling
          Dec 25 '12 at 9:00







        • 1





          @David: I have to revise: Apparently .load is deprecated: api.jquery.com/load-event. I don't know if it's for images only or window as well.

          – Felix Kling
          Dec 25 '12 at 9:03







        • 1





          @David: No worries :) Even if you are not sure, it's good that you mentioned it. I will probably add just some simple code snippets to show the usage. Thanks for your input!

          – Felix Kling
          Dec 25 '12 at 9:05












        • 1





          Would it be worth amending the last bit about the ready event to reflect the "newer" preferred syntax, or is it better to leave it as-is so that it works across older versions?

          – Tieson T.
          Dec 25 '12 at 8:56







        • 1





          For jQuery, is it worth also adding in the alternative $(window).load() (and possibly syntactic alternatives to the $(document).ready(), $(function())? It seems related, but it feels slightly tangential to the point you're making.

          – David Thomas
          Dec 25 '12 at 8:58











        • @David: Good point with .load. Regarding syntax alternatives, they could be looked up in the documentation but since answers should be self contained, it might actually be worth adding them. Then again, I'm pretty sure this specific bit about jQuery was answered already and is probably covered in another answers and linking to it might suffice.

          – Felix Kling
          Dec 25 '12 at 9:00







        • 1





          @David: I have to revise: Apparently .load is deprecated: api.jquery.com/load-event. I don't know if it's for images only or window as well.

          – Felix Kling
          Dec 25 '12 at 9:03







        • 1





          @David: No worries :) Even if you are not sure, it's good that you mentioned it. I will probably add just some simple code snippets to show the usage. Thanks for your input!

          – Felix Kling
          Dec 25 '12 at 9:05







        1




        1





        Would it be worth amending the last bit about the ready event to reflect the "newer" preferred syntax, or is it better to leave it as-is so that it works across older versions?

        – Tieson T.
        Dec 25 '12 at 8:56






        Would it be worth amending the last bit about the ready event to reflect the "newer" preferred syntax, or is it better to leave it as-is so that it works across older versions?

        – Tieson T.
        Dec 25 '12 at 8:56





        1




        1





        For jQuery, is it worth also adding in the alternative $(window).load() (and possibly syntactic alternatives to the $(document).ready(), $(function())? It seems related, but it feels slightly tangential to the point you're making.

        – David Thomas
        Dec 25 '12 at 8:58





        For jQuery, is it worth also adding in the alternative $(window).load() (and possibly syntactic alternatives to the $(document).ready(), $(function())? It seems related, but it feels slightly tangential to the point you're making.

        – David Thomas
        Dec 25 '12 at 8:58













        @David: Good point with .load. Regarding syntax alternatives, they could be looked up in the documentation but since answers should be self contained, it might actually be worth adding them. Then again, I'm pretty sure this specific bit about jQuery was answered already and is probably covered in another answers and linking to it might suffice.

        – Felix Kling
        Dec 25 '12 at 9:00






        @David: Good point with .load. Regarding syntax alternatives, they could be looked up in the documentation but since answers should be self contained, it might actually be worth adding them. Then again, I'm pretty sure this specific bit about jQuery was answered already and is probably covered in another answers and linking to it might suffice.

        – Felix Kling
        Dec 25 '12 at 9:00





        1




        1





        @David: I have to revise: Apparently .load is deprecated: api.jquery.com/load-event. I don't know if it's for images only or window as well.

        – Felix Kling
        Dec 25 '12 at 9:03






        @David: I have to revise: Apparently .load is deprecated: api.jquery.com/load-event. I don't know if it's for images only or window as well.

        – Felix Kling
        Dec 25 '12 at 9:03





        1




        1





        @David: No worries :) Even if you are not sure, it's good that you mentioned it. I will probably add just some simple code snippets to show the usage. Thanks for your input!

        – Felix Kling
        Dec 25 '12 at 9:05





        @David: No worries :) Even if you are not sure, it's good that you mentioned it. I will probably add just some simple code snippets to show the usage. Thanks for your input!

        – Felix Kling
        Dec 25 '12 at 9:05











        12














        Reasons why id based selectors don't work



        1. The element/DOM with id specified doesn't exist yet.

        2. The element exists, but it is not registered in DOM [in case of HTML nodes appended dynamically from Ajax responses].

        3. More than one element with the same id is present which is causing a conflict.

        Solutions



        1. Try to access the element after its declaration or alternatively use stuff like $(document).ready();


        2. For elements coming from Ajax responses, use the .bind() method of jQuery. Older versions of jQuery had .live() for the same.


        3. Use tools [for example, webdeveloper plugin for browsers] to find duplicate ids and remove them.






        share|improve this answer





























          12














          Reasons why id based selectors don't work



          1. The element/DOM with id specified doesn't exist yet.

          2. The element exists, but it is not registered in DOM [in case of HTML nodes appended dynamically from Ajax responses].

          3. More than one element with the same id is present which is causing a conflict.

          Solutions



          1. Try to access the element after its declaration or alternatively use stuff like $(document).ready();


          2. For elements coming from Ajax responses, use the .bind() method of jQuery. Older versions of jQuery had .live() for the same.


          3. Use tools [for example, webdeveloper plugin for browsers] to find duplicate ids and remove them.






          share|improve this answer



























            12












            12








            12







            Reasons why id based selectors don't work



            1. The element/DOM with id specified doesn't exist yet.

            2. The element exists, but it is not registered in DOM [in case of HTML nodes appended dynamically from Ajax responses].

            3. More than one element with the same id is present which is causing a conflict.

            Solutions



            1. Try to access the element after its declaration or alternatively use stuff like $(document).ready();


            2. For elements coming from Ajax responses, use the .bind() method of jQuery. Older versions of jQuery had .live() for the same.


            3. Use tools [for example, webdeveloper plugin for browsers] to find duplicate ids and remove them.






            share|improve this answer















            Reasons why id based selectors don't work



            1. The element/DOM with id specified doesn't exist yet.

            2. The element exists, but it is not registered in DOM [in case of HTML nodes appended dynamically from Ajax responses].

            3. More than one element with the same id is present which is causing a conflict.

            Solutions



            1. Try to access the element after its declaration or alternatively use stuff like $(document).ready();


            2. For elements coming from Ajax responses, use the .bind() method of jQuery. Older versions of jQuery had .live() for the same.


            3. Use tools [for example, webdeveloper plugin for browsers] to find duplicate ids and remove them.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 12 '17 at 0:54









            Peter Mortensen

            13.7k1986112




            13.7k1986112










            answered Jan 7 '14 at 12:12









            sumitsumit

            9791017




            9791017





















                10














                As @FelixKling pointed out, the most likely scenario is that the nodes you are looking for do not exist (yet).



                However, modern development practices can often manipulate document elements outside of the document tree either with DocumentFragments or simply detaching/reattaching current elements directly. Such techniques may be used as part of JavaScript templating or to avoid excessive repaint/reflow operations while the elements in question are being heavily altered.



                Similarly, the new "Shadow DOM" functionality being rolled out across modern browsers allows elements to be part of the document, but not query-able by document.getElementById and all of its sibling methods (querySelector, etc.). This is done to encapsulate functionality and specifically hide it.



                Again, though, it is most likely that the element you are looking for simply is not (yet) in the document, and you should do as Felix suggests. However, you should also be aware that that is increasingly not the only reason that an element might be unfindable (either temporarily or permanently).






                share|improve this answer



























                  10














                  As @FelixKling pointed out, the most likely scenario is that the nodes you are looking for do not exist (yet).



                  However, modern development practices can often manipulate document elements outside of the document tree either with DocumentFragments or simply detaching/reattaching current elements directly. Such techniques may be used as part of JavaScript templating or to avoid excessive repaint/reflow operations while the elements in question are being heavily altered.



                  Similarly, the new "Shadow DOM" functionality being rolled out across modern browsers allows elements to be part of the document, but not query-able by document.getElementById and all of its sibling methods (querySelector, etc.). This is done to encapsulate functionality and specifically hide it.



                  Again, though, it is most likely that the element you are looking for simply is not (yet) in the document, and you should do as Felix suggests. However, you should also be aware that that is increasingly not the only reason that an element might be unfindable (either temporarily or permanently).






                  share|improve this answer

























                    10












                    10








                    10







                    As @FelixKling pointed out, the most likely scenario is that the nodes you are looking for do not exist (yet).



                    However, modern development practices can often manipulate document elements outside of the document tree either with DocumentFragments or simply detaching/reattaching current elements directly. Such techniques may be used as part of JavaScript templating or to avoid excessive repaint/reflow operations while the elements in question are being heavily altered.



                    Similarly, the new "Shadow DOM" functionality being rolled out across modern browsers allows elements to be part of the document, but not query-able by document.getElementById and all of its sibling methods (querySelector, etc.). This is done to encapsulate functionality and specifically hide it.



                    Again, though, it is most likely that the element you are looking for simply is not (yet) in the document, and you should do as Felix suggests. However, you should also be aware that that is increasingly not the only reason that an element might be unfindable (either temporarily or permanently).






                    share|improve this answer













                    As @FelixKling pointed out, the most likely scenario is that the nodes you are looking for do not exist (yet).



                    However, modern development practices can often manipulate document elements outside of the document tree either with DocumentFragments or simply detaching/reattaching current elements directly. Such techniques may be used as part of JavaScript templating or to avoid excessive repaint/reflow operations while the elements in question are being heavily altered.



                    Similarly, the new "Shadow DOM" functionality being rolled out across modern browsers allows elements to be part of the document, but not query-able by document.getElementById and all of its sibling methods (querySelector, etc.). This is done to encapsulate functionality and specifically hide it.



                    Again, though, it is most likely that the element you are looking for simply is not (yet) in the document, and you should do as Felix suggests. However, you should also be aware that that is increasingly not the only reason that an element might be unfindable (either temporarily or permanently).







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Dec 6 '13 at 17:29









                    Nathan BubnaNathan Bubna

                    6,04422735




                    6,04422735





















                        10














                        If the element you are trying to access is inside an iframe and you try to access it outside the context of the iframe this will also cause it to fail.



                        If you want to get an element in an iframe you can find out how here.






                        share|improve this answer





























                          10














                          If the element you are trying to access is inside an iframe and you try to access it outside the context of the iframe this will also cause it to fail.



                          If you want to get an element in an iframe you can find out how here.






                          share|improve this answer



























                            10












                            10








                            10







                            If the element you are trying to access is inside an iframe and you try to access it outside the context of the iframe this will also cause it to fail.



                            If you want to get an element in an iframe you can find out how here.






                            share|improve this answer















                            If the element you are trying to access is inside an iframe and you try to access it outside the context of the iframe this will also cause it to fail.



                            If you want to get an element in an iframe you can find out how here.







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited May 23 '17 at 12:18









                            Community

                            11




                            11










                            answered Jan 5 '16 at 23:34









                            George MulliganGeorge Mulligan

                            10.6k62845




                            10.6k62845





















                                -2














                                Try putting document.getElementById in setTimeout()



                                E.g.



                                setTimeout(function()
                                console.log(document.getElementById('whatever'));
                                , 100);


                                If this works, then it's just a timing problem.






                                share|improve this answer


















                                • 1





                                  This is unreliable. It’s not a “timing problem”. See the other answers here for real solutions and explanations.

                                  – Xufox
                                  Aug 10 '18 at 14:05















                                -2














                                Try putting document.getElementById in setTimeout()



                                E.g.



                                setTimeout(function()
                                console.log(document.getElementById('whatever'));
                                , 100);


                                If this works, then it's just a timing problem.






                                share|improve this answer


















                                • 1





                                  This is unreliable. It’s not a “timing problem”. See the other answers here for real solutions and explanations.

                                  – Xufox
                                  Aug 10 '18 at 14:05













                                -2












                                -2








                                -2







                                Try putting document.getElementById in setTimeout()



                                E.g.



                                setTimeout(function()
                                console.log(document.getElementById('whatever'));
                                , 100);


                                If this works, then it's just a timing problem.






                                share|improve this answer













                                Try putting document.getElementById in setTimeout()



                                E.g.



                                setTimeout(function()
                                console.log(document.getElementById('whatever'));
                                , 100);


                                If this works, then it's just a timing problem.







                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Aug 6 '18 at 21:36









                                TakaSoftTakaSoft

                                48759




                                48759







                                • 1





                                  This is unreliable. It’s not a “timing problem”. See the other answers here for real solutions and explanations.

                                  – Xufox
                                  Aug 10 '18 at 14:05












                                • 1





                                  This is unreliable. It’s not a “timing problem”. See the other answers here for real solutions and explanations.

                                  – Xufox
                                  Aug 10 '18 at 14:05







                                1




                                1





                                This is unreliable. It’s not a “timing problem”. See the other answers here for real solutions and explanations.

                                – Xufox
                                Aug 10 '18 at 14:05





                                This is unreliable. It’s not a “timing problem”. See the other answers here for real solutions and explanations.

                                – Xufox
                                Aug 10 '18 at 14:05





                                protected by VisioN Jan 27 '13 at 12:11



                                Thank you for your interest in this question.
                                Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                                Would you like to answer one of these unanswered questions instead?



                                Popular posts from this blog

                                Top Tejano songwriter Luis Silva dead of heart attack at 64

                                ReactJS Fetched API data displays live - need Data displayed static

                                Evgeni Malkin