5

I want to get all input element in html page. I've tried this:

window.onload = function(){
    input = document.querySelectorAll("input");
}

But, when I check it with alert function outside onload, it doesn't do anything

alert(input.length) // doesn't do anything

If I use this, this will give me the numbers of input element in html page.

window.onload = function(){
    input = document.querySelectorAll("input");
    alert(input.length);
}

And that's mean I can't access it outside. How can I access it outside?

UPDATE

This is how the html page looks like:

<html>
<head>
    <script type="text/javascript" src="actions.js"></script>
</head>
<body>
    <label for="name">Name:</label><br/>
    <input type="text" id="name" /><br/>
    <label for="address">Address:</label><br/>
    <input type="text" id="address" /><br/>
    <label for="email">E-mail:</label><br/>
    <input type="text" id="email" />
</body>
</html>
Mas Bagol
  • 4,377
  • 10
  • 44
  • 72
  • 1
    You're making a global variable because you're not declaring it with `var`, so you **can** access it outside the function. You'll have to post more code in order for anybody to tell what's going wrong. (If `alert(input.length)` really does not do *anything* then there's an error and you should check your developer console.) – Pointy Mar 02 '15 at 15:18
  • 1
    *When* are you checking it outside `onload`? You may simply be checking too early, before `onload` has actually been called. – Paul Roub Mar 02 '15 at 15:20
  • Actually, that's all my code. I just testing it and wondering how to make it works. – Mas Bagol Mar 02 '15 at 15:20
  • Well, thats probably because the alert-function is aleady called, before the window.onload-event is fired. But i can't figure why theres no error shown.. – Agash Thamo. Mar 02 '15 at 15:22
  • I put `alert(input.length)` right below `onload` function (in first example). So, the `alert` function is called first? – Mas Bagol Mar 02 '15 at 15:23
  • [when is window.onload fired?](http://stackoverflow.com/questions/3520780/when-is-window-onload-fired) – Paul Roub Mar 02 '15 at 15:23
  • Yes - you're telling the browser what to do *when* the window is fully loaded. That will happen later. Then you tell it to call `alert()`, *right now*. – Paul Roub Mar 02 '15 at 15:24
  • Yes it is called first. The function you added behind the onload event is called after everything is loaded. The alert-function is just called, the moment the browser parsed it. – Agash Thamo. Mar 02 '15 at 15:24

2 Answers2

6

There are a couple ways of doing it.

The Dangerous Way

var input; // Input declared outside
window.onload = function(){
    input = document.querySelectorAll("input");
}
// Sometime later...
alert(input.length);

This assumes that Sometime later... magically happens after window.onload was fired, which may or may not be the case, you have no guarantee.

The Hacky Way

You can make sure all of your <script> elements are found at the bottom of your page. This eliminates the need for window.onload, but as I said, it's hacky. Order of inclusion shouldn't matter.

The Promised Way

With ES6 (or with a library like bluebird), you have Promises! So you can do something like this:

/**
 * Returns a promise the resolves when window fires the load event
 */
function onload() {
    return new Promise(function(resolve, reject) {
        // Resolve if window is already loaded by the time this is called.
        if (document.readyState === 'complete') { return resolve(); }
        // If reached here, window not loaded. Resolve when it is.
        window.addEventListener('load', resolve);
    }
}

Then you can call...

var inputAvailable = onload().then(function() {
    var input = document.querySelectorAll('input');
    return input;
});
// inputAvailable is a Promise object that resolves once querySelectorAll()
// is executed and the result returned. It resolves with the returned value.

And somewhere else...

// The handler passed to .then will be called once inputAvailable resolves.
// Which is always after querySelectorAll() was executed.
inputAvailable.then(function(inputs) {
    alert(inputs.length);
});
Madara's Ghost
  • 172,118
  • 50
  • 264
  • 308
1

Reference your script tags at the bottom of the HTML page and not in the head. This will remove any ambiguity as to whether the page has been loaded.

window.onload = function(){
    input = document.querySelectorAll("input");
    alert(input.length);
}

Now you should be able to extract the code from "window.load()" and get the expected results.

input = document.querySelectorAll("input");
alert(input.length);
Da Rod
  • 701
  • 5
  • 11
  • While that definitely works, it's somewhat hacky. You can't always control the order of inclusion either. – Madara's Ghost Mar 02 '15 at 15:37
  • which part is hacky? if you're referring to my comment about the position of the script tags, referencing them at the bottom of the page is considered a best practice these days. placing them at the bottom always forces them to be loaded last. – Da Rod Mar 02 '15 at 15:55
  • No, it's not. The position of where I put my ` – Madara's Ghost Mar 02 '15 at 15:55
  • ... My point is that if you write your JavaScript and DOM correctly, the place where you put your script doesn't matter. "Always put your script at the bottom" is a faux best practice for those who don't know how to correctly utilize events. The *only* thing that always putting your scripts at the bottom does, is save you one level of indentation. Not good enough reason to call it an absolute best practice IMO. – Madara's Ghost Mar 02 '15 at 16:10
  • it was originally considered a best practice because it ensured 2 things 1) that the DOM was completely loaded prior to referencing any objects and 2) for loading performance – Da Rod Mar 02 '15 at 16:18
  • that being said, i completely agree with you. if you wanted to ensure that no matter where your scripts are loaded that they ran correctly, your solution is key. – Da Rod Mar 02 '15 at 16:21