2

Update: I originally had

document.addEventListener("DOMContentLoaded"...

and was linking to the JS file in the head of the HTML document.

The result was: some parts of another js script weren't working.

I then replaced 'DOMContentLoaded' with 'load' and it started working!

The weird thing now is:

When I move the link to the JS file to the footer of the HTML document, then and only then it actually works with 'DOMContentLoaded'. But that's very weird isn't it?

I have no idea what's going on! Any pointers?

Original post:

There is a big mystery I'm trying to unravel. While this code is working perfectly:

(function () {
    "use strict";

    var state = document.getElementById("s-state");
    var btnEstimate = document.getElementById("btn-estimate");

// document.addEventListener("load", function() {

        btnEstimate.setAttribute("disabled", "disabled");
        btnEstimate.value = "Please select your state first!";

        state.addEventListener("change", function () {
            if (state.value === "") {
                btnEstimate.setAttribute("disabled", "disabled");
                btnEstimate.value = "Please select your state first!";
            } else {
                btnEstimate.removeAttribute("disabled");
                btnEstimate.value = "Estimate Total";
            }
        });

// }, false);

})();

the following code does NOT work:

(function () {
    "use strict";

    var state = document.getElementById("s-state");
    var btnEstimate = document.getElementById("btn-estimate");

    document.addEventListener("load", function() {

        btnEstimate.setAttribute("disabled", "disabled");
        btnEstimate.value = "Please select your state first!";

        state.addEventListener("change", function () {
            if (state.value === "") {
                btnEstimate.setAttribute("disabled", "disabled");
                btnEstimate.value = "Please select your state first!";
            } else {
                btnEstimate.removeAttribute("disabled");
                btnEstimate.value = "Estimate Total";
            }
        });

    }, false);

})();

So, the big question is WHY??? Why is wrapping the code around in this:

document.addEventListener("load", function() {
    }, false);

prevent it from working? That doesn't make any sense, does it? First, I thought the problem was me using 'DOMContentLoaded' but nope. Using 'load' produces the same result: non-working code.

Big mystery!

Here's the snippet with the code I actually had originally:

(function () {
"use strict";

var state = document.getElementById("s-state");
var btnEstimate = document.getElementById("btn-estimate");

document.addEventListener("load", function() {
    
    btnEstimate.setAttribute("disabled", "disabled");
    btnEstimate.value = "Please select your state first!";

    state.addEventListener("change", function () {
        if (state.value === "") {
            btnEstimate.setAttribute("disabled", "disabled");
            btnEstimate.value = "Please select your state first!";
        } else {
            btnEstimate.removeAttribute("disabled");
            btnEstimate.value = "Estimate Total";
        }
    });
    
}, false);

})();
<div class="group state">
<label for="s-state">State (required):</label>
<select id="s-state" required>
                            <option value="">- select -</option>
                            <option value="CA">California</option>
                            <option value="IL">Illinois</option>
                            <option value="NH">New Hampshire</option>
                            <option value="PA">Pennsylvania</option>
</select>
</div>


<p>
<label for="btn-estimate">Click to estimate:</label>
<br>
<input type="submit" value="Estimate Total" id="btn-estimate">
</p>
WebDevBooster
  • 14,674
  • 9
  • 66
  • 70
  • Here's the weirdest thing in the world: I first had the link to JS file in the head of the HTML document and was using 'DOMContentLoaded' there. It wasn't working! I then changed it to 'load' and some parts started working. So, DOMContentLoaded was definitely preventing stuff from working properly WHEN linking to the JS file in the HEAD of the HTML document. The strange thing now is: when moving the js file line to the footer DOMContentLoaded actually works. This is way too strange! I need to understand what the hell is going on? Any pointers? – WebDevBooster Sep 30 '17 at 00:36

4 Answers4

3

3 possible ways to resolve this issue using native javascript:

  • using window.addEventListener insted of document.addEventListener
  • using DOMContentLoaded like this document.addEventListener("DOMContentLoaded", function(event) {});
  • using window.onload = function() {}
Mohamed Chaawa
  • 918
  • 1
  • 9
  • 23
  • I just realized: When I put the link to the js file in the footer of the HTML document, then and ONLY THEN 'DOMContentLoaded' actually does work! But when I move the link to the js file into the head it stops working! WHY??? – WebDevBooster Sep 30 '17 at 00:46
  • Simply, because the action is triggered before the body is loaded and hence your code couldn't find the addressed elements and your listeners are not bound. – Mohamed Chaawa Sep 30 '17 at 00:59
  • Right. But wouldn't then the use of "load" instead of "DOMContentLoaded" solve the problem? It should in theory, right? But it didn't in practice! That's why I'm finding the whole thing extremely weird and a big mystery... – WebDevBooster Sep 30 '17 at 01:04
1

The event you're looking for is "DOMContentLoaded", not "load"

document.addEventListener('DOMContentLoaded', function () {
  console.log('loaded')
})
Sidney
  • 4,495
  • 2
  • 18
  • 30
  • Mate, I certainly tried with DOMContentLoaded as the very first thing! Didn't work! – WebDevBooster Sep 30 '17 at 00:23
  • The "DOMContentLoaded" event should work. Can you post that version of your code? There's likely something else that's causing a problem. – Sidney Sep 30 '17 at 00:36
  • Yes, I have the snippet above. The strangest thing is: When I put the link to the js file in the footer of the HTML document, then and ONLY THEN 'DOMContentLoaded' actually does work! But when I move the link to the js file into the head it stops working! WHY??? – WebDevBooster Sep 30 '17 at 00:45
  • If you put the ` – Sidney Sep 30 '17 at 00:52
  • Yep, that's extremely odd! And a big mystery! I posted the exact code (including HTML) in the snippet. The only difference now is that I replaced "load" with "DOMContentLoaded". – WebDevBooster Sep 30 '17 at 01:01
0

Because document.onload isn't called? could use window.onload, or if you have jQuery, use jQuery(document).ready(function(){...})

  • I was actually using an Immediately-Invoked Function Expression (see updated code). That should have done the trick, right? But it didn't! – WebDevBooster Sep 30 '17 at 00:29
0

It will be helpful to read the MDN about this useCapture option: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

useCapture Optional A Boolean indicating that events of this type will be dispatched to the registered listener before being dispatched to any EventTarget beneath it in the DOM tree. Events that are bubbling upward through the tree will not trigger a listener designated to use capture. Event bubbling and capturing are two ways of propagating events which occur in an element that is nested within another element, when both elements have registered a handle for that event. The event propagation mode determines the order in which elements receive the event. See DOM Level 3 Events and JavaScript Event order for a detailed explanation. If not specified, useCapture defaults to false.

It will be additionally helpful to read this post about directionality of event propagation: Unable to understand useCapture attribute in addEventListener

The capture phase: the event is dispatched to the target's ancestors from the root of the tree to the direct parent of the target node.

The target phase: the event is dispatched to the target node.

The bubbling phase: the event is dispatched to the target's ancestors from the direct parent of the target node to the root of the tree.

useCapture indicates for which phases the event travel will be on:

If true, useCapture indicates that the user wishes to add the event listener for the capture phase only, i.e. this event listener will not be triggered during the target and bubbling phases.

If false, the event listener will only be triggered during the target and bubbling phases.

I am not certain how this pertains to your code, but this will indicate why it isn't working correctly for the load event.

I imagine it is because the document is the root node, so it has no parents.

agm1984
  • 15,500
  • 6
  • 89
  • 113