51

I need to get all the input objects and manipulate the onclick param.

The following does the job for <a> links. Looking for something like this for input tags.

for (var ls = document.links, numLinks = ls.length, i=0; i<numLinks; i++){
  var link = unescape(ls[i].href);
  link = link.replace(/\\'/ig,"#");
  if(ls[i].href.indexOf("javascript:") == -1)
  {
    ls[i].href = "javascript:LoadExtern(\\""+link+"\\",\\"ControlPanelContent\\",true,true);";
  }
}
freginold
  • 3,946
  • 3
  • 13
  • 28
Jeremy Gwa
  • 2,333
  • 7
  • 25
  • 31
  • 1
    Ouch, that's ugly and has several escaping problems. You don't ever want to use `javascript` URLs. My suggestion for this particular code: leave the `href` where it is and instead just set `ls[i].onclick= function() { LoadExtern(this.href, 'ControlPanelContent', true, true); };`. – bobince Feb 06 '10 at 18:48

3 Answers3

124

(See update at end of answer.)

You can get a NodeList of all of the input elements via getElementsByTagName (DOM specification, MDC, MSDN), then simply loop through it:

var inputs, index;

inputs = document.getElementsByTagName('input');
for (index = 0; index < inputs.length; ++index) {
    // deal with inputs[index] element.
}

There I've used it on the document, which will search the entire document. It also exists on individual elements (DOM specification), allowing you to search only their descendants rather than the whole document, e.g.:

var container, inputs, index;

// Get the container element
container = document.getElementById('container');

// Find its child `input` elements
inputs = container.getElementsByTagName('input');
for (index = 0; index < inputs.length; ++index) {
    // deal with inputs[index] element.
}

...but you've said you don't want to use the parent form, so the first example is more applicable to your question (the second is just there for completeness, in case someone else finding this answer needs to know).


Update: getElementsByTagName is an absolutely fine way to do the above, but what if you want to do something slightly more complicated, like just finding all of the checkboxes instead of all of the input elements?

That's where the useful querySelectorAll comes in: It lets us get a list of elements that match any CSS selector we want. So for our checkboxes example:

var checkboxes = document.querySelectorAll("input[type=checkbox]");

You can also use it at the element level. For instance, if we have a div element in our element variable, we can find all of the spans with the class foo that are inside that div like this:

var fooSpans = element.querySelectorAll("span.foo");

querySelectorAll and its cousin querySelector (which just finds the first matching element instead of giving you a list) are supported by all modern browsers, and also IE8.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • why did you use ++index? The elements in NodeList start with 0..so that way, you skip the first element?? – Alko Dec 31 '14 at 10:51
  • 6
    @Alko: I *don't* skip the first. The first value of `index` within the loop **is** `0`. The `++index` doesn't happen until after the first loop iteration. – T.J. Crowder Dec 31 '14 at 11:24
  • Will this get nested elements? For example if I have a form and then inside that form there's a table, and inside that table there is row, and inside that row there is an input - will this actually get that input? I think it might only work for top level inputs. I need to get ALL inputs, nested or not nested. Probably need recursion – MobileMon Nov 12 '20 at 15:32
  • @MobileMon - Yes, it works for non-child descendant elements. I'm not aware of any DOM **method** that finds elements that only looks at child elements, in fact. (Only DOM **collections**, like `children` and `childNodes`.). – T.J. Crowder Nov 12 '20 at 15:34
14

querySelectorAll returns a NodeList which has its own forEach method:

document.querySelectorAll('input').forEach( input => {
  // ...
});

getElementsByTagName now returns an HTMLCollection instead of a NodeList. So you would first need to convert it to an array to have access to methods like map and forEach:

Array.from(document.getElementsByTagName('input')).forEach( input => {
  // ...
});
JSON C11
  • 11,272
  • 7
  • 78
  • 65
6
var inputs = document.getElementsByTagName('input');
for (var i = 0; i < inputs.length; ++i) {
  // ...
}
Pointy
  • 405,095
  • 59
  • 585
  • 614