How do I enumerate all of the html id's in a document with javascript?
Asked Answered
N

10

56

I would like to be able to use javascript to find every id (or name) for every object in an html document so that they can be printed at the bottom of the page.

To understand more fully what I'm trying to accomplish, let me explain. I build large forms from time to time for things such as property applications, rental listings, detailed medical website user registration forms and such. As I do it now, I build the form, assign the id's and names and decide which values are required and such. Then when I build the php form validation and database insert portion for the form, I've been manually going through the html and pulling out all of the id's to reference from the $_post array for the input validation and database insert. This has been very time consuming and a real pain, often laced with typing errors.

The form I'm working on currently is just too big, and I'd much rather write a javascript function that I can run on my local copy of the page to list all of the id's so that I don't have to copy and paste them one by one, or write them down. I could then also use the javascript loop to event print out the php code around the id names so that I'd only have to copy the list and lightly edit out the id's I dodn't need... I hope you guys get the idea.

Any suggestions on how I can drop all of the id's into an array, or if there is already an array I can access and loop through (I couldn't find anything on google). Also, any suggestions for how to speed up the process of producing large forms with a work flow that generates the php or makes it quicker than my current method would be greatly appreciated!

Noman answered 18/8, 2011 at 22:42 Comment(0)
C
78

On modern browsers you can do this via

document.querySelectorAll('*[id]')

should do the job.

If you need all descendants of myElement with IDs, then do

myElement.querySelectorAll('*[id]')

If you want to be really careful to exclude <span id="">, then maybe

document.querySelectorAll('*[id]:not([id=""])')

If compatibility with older browsers is required

var allElements = document.getElementsByTagName("*");
var allIds = [];
for (var i = 0, n = allElements.length; i < n; ++i) {
  var el = allElements[i];
  if (el.id) { allIds.push(el.id); }
}

should leave you with all the IDs in allIds.

If you find you need to just enumerate the IDs under a particular form node, then you can replace document.getElementsByTagName with myFormNode.getElementsByTagName.

If you want to include both IDs and NAMEs, then put

else if (el.name) { allIds.push(el.name); }

below the if above.

Carreno answered 18/8, 2011 at 22:44 Comment(2)
I keep searching for *[id] on the internet, I can't find anything, where do I read on it? why does it return all ID's and why doesn't it work on var s = new Array; s[s.length] = document.getElementById("*[id]") (inside a for loop)Whippoorwill
@Shayan, getElementById takes an ID not a CSS selector so you're passing the wrong kind of thing. Mozdev explains CSS selectors. * is a universal selector and [id] is an attribute selector.Carreno
V
26

If you're doing your development using a fairly modern browser, you can use querySelectorAll(), then use Array.prototype.forEach to iterate the collection.

var ids = document.querySelectorAll('[id]');

Array.prototype.forEach.call( ids, function( el, i ) {
    // "el" is your element
    console.log( el.id ); // log the ID
});

If you want an Array of IDs, then use Array.prototype.map:

var arr = Array.prototype.map.call( ids, function( el, i ) {
    return el.id;
});
Venturous answered 18/8, 2011 at 22:51 Comment(1)
In 2015, this is the best answer.Hertzog
G
9

Get all tags with the wildcard:

var allElements = document.getElementsByTagName('*');
for(var i = 0; i < allElements.length; i++) {
    // ensure the element has an Id that is not empty and does exist
    // and string other than empty, '', will return true
    allElements[i].id && console.log(allElements[i].id);
}
Gussi answered 18/8, 2011 at 22:46 Comment(0)
P
9

The jQuery selector $('[id]') will get all the elements with an id attribute:

$('[id]').each(function () {
    do_something(this.id);
});

Working example here: http://jsfiddle.net/RichieHindle/yzMjJ/2/

Putnem answered 18/8, 2011 at 22:48 Comment(1)
I forgot about the attribute selectors, much simplerAbomination
I
5

well, since it is a form, im sure that you want to iterate only over the form elements and not all the tags in the document ( like href , div's etc.. )

for (var i=0; i < form.elements.length; i++) {
   var elementId = form.elements[i].id;
}
Incredulity answered 18/8, 2011 at 23:0 Comment(0)
A
3

with jQuery

$('*').map(function() {
   return this.id || null;
}).get().join(',');

this gets all the elements in the DOM, and runs a function on each to return the id (and if undefined, returning null won't return anything. This returns a jQuery object which is then converted to a JavaScript array with get() and this is then converted to a comma-separated string of ids.

Try it on this page and you get

"notify-container,overlay-header,custom-header,header,portalLink,topbar,hlinks,hlinks-user,hlinks-nav,hlinks-custom,hsearch,search,hlogo,hmenus,nav-questions,nav-tags,nav-users,nav-badges,nav-unanswered,nav-askquestion,content,question-header,mainbar,question,edit-tags,link-post-7115022,close-question-7115022,flag-post-7115022,comments-7115022,add-comment-7115022,comments-link-7115022,answers,answers-header,tabs,answer-7115033,link-post-7115033,flag-post-7115033,comments-7115033,add-comment-7115033,comments-link-7115033,answer-7115042,link-post-7115042,flag-post-7115042,comments-7115042,add-comment-7115042,comments-link-7115042,answer-7115043,link-post-7115043,delete-post-7115043,flag-post-7115043,post-editor-7115043,wmd-button-bar-7115043,wmd-button-row-7115043,wmd-bold-button-7115043,wmd-italic-button-7115043,wmd-spacer1-7115043,wmd-link-button-7115043,wmd-quote-button-7115043,wmd-code-button-7115043,wmd-image-button-7115043,wmd-spacer2-7115043,wmd-olist-button-7115043,wmd-ulist-button-7115043,wmd-heading-button-7115043,wmd-hr-button-7115043,wmd-spacer3-7115043,wmd-undo-button-7115043,wmd-redo-button-7115043,wmd-help-button-7115043,wmd-input-7115043,draft-saved-7115043,communitymode-7115043,wmd-preview-7115043,fkey,author,edit-comment-7115043,edit-comment-error-7115043,submit-button-7115043,comments-7115043,add-comment-7115043,comments-link-7115043,post-form,post-editor,wmd-button-bar,wmd-input,draft-saved,communitymode,wmd-preview,fkey,author,submit-button,show-editor-button,sidebar,qinfo,adzerk2,newsletter-ad,newsletter-ad-header,newsletter-signup-container,newsletter-signup,newsletter-preview-container,newsletter-preview,h-related,feed-link,feed-link-text,prettify-lang,footer,footer-menu,footer-sites,footer-flair,svnrev,copyright"

Abomination answered 18/8, 2011 at 22:46 Comment(0)
G
3

A simple ES6 (es2015) solution based on answer of user113716

const elementsById = document.querySelectorAll('[id]');
const elementsByIdArr = Array.prototype.map.call(elementsById, el => el.id);

/**
* identify all element ID's on a page,
* construct array of all element ID's on a page,
*/

const elementsById = document.querySelectorAll('[id]');
const elementsByIdArr = Array.prototype.map.call(elementsById, el => el.id);

for (const el of elementsByIdArr) {
  document.getElementById(el).innerHTML = `My id is &quot;&num;${el}&quot;`;
}
.title {font-weight: bolder; font-size: 24px;}
.description {line-height: 1.8em;}
<div id="primary" class="title"></div>
<div id="description" class="description"></div>
Giustino answered 18/5, 2018 at 9:9 Comment(0)
P
0

You can use this code

var el_up = document.getElementById("UP");
var el_down = document.getElementById("DOWN");
el_up.innerHTML = "Click on the button to get " +
  "all IDs in an array.";

function runJquery() {
  var IDStr = "// Special characters will be removed\n";
  $("*").each(function() {
    if (this.id) {
      let id = this.id;
      id = id.replace(/[^\w\s]/gi, "");
      id = id.toUpperCase();
      window[id] = document.getElementById(this.id);
      IDStr += `var ${id} = document.getElementById('${this.id}');\n`;
    }
  });
  el_down.innerHTML = IDStr;
}

function runNormalJS() {
  var IDStr = "// Special characters will be removed\n";
  [...document.querySelectorAll("*")].forEach(function(e) {
    if (e.id) {
      let id = e.id;
      id = id.replace(/[^\w\s]/gi, "");
      id = id.toUpperCase();
      window[id] = document.getElementById(e.id);
      IDStr += `var ${id} = document.getElementById('${e.id}');\n`;
    }
  });
  el_down.innerHTML = IDStr;
}
* {
  text-align: center;
}

#DOWN {
  color: blue;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js">
</script>


<h1 style="color: blue">
  MrAni
</h1>

<p class="text-center" id="UP"></p>

<button type="button" class="btn btn-outline-primary" onclick="runJquery()">
        Click Here To Run With Jquery
    </button>

<button type="button" class="btn btn-outline-primary" onclick="runNormalJS()">
        Click Here To Run With Normal JS
    </button>

<p class="text-center" id="DOWN"></p>

This code is understandable and also works smoothly

Pierpont answered 7/10, 2021 at 13:23 Comment(0)
U
-1

The following snippet creates the code to make a const from every element with an ID in any document. If you work with forms as often as I do, this snippet can will recover hours of your life you would never get back otherwise.

/*===================================
* The function below does the following:
* 1) find all element IDs in a document
* 2) create textarea field 
* 3) insert a "const" for all IDs into textarea
* 4) embed at bottom of page
* 5) scroll to the bottom of page
* 6) set focus to textarea field
* 7) select all text in textarea field 
*----------------------------------*/

    function createConstFromIDs() {
      let allIDs;
      document.querySelectorAll("[id]").forEach((item) => {
        allIDs += `const ${item.id.replaceAll('-','_')} = document.getElementById('${item.id}');\n`;
      });
      let _create_const = document.createElement('textarea');
      _create_const.setAttribute('id', 'create_const_from_ids');
      _create_const.setAttribute('style', 'width: 96%;height:200px;font-size:0.65rem;color:#0000ff;background:#f2f8ff;');
      document.body.insertAdjacentElement("beforeend", _create_const);
      create_const_from_ids.innerHTML = allIDs.replace('undefined', '');
      create_const_from_ids.scrollIntoView();
      setTimeout(function() {
        create_const_from_ids.focus();  
        create_const_from_ids.select();
      }, 2500);
    }
    // createConstFromIDs();
* {
  box-sizing: border-box;
  font-family: sans-serif;
}
main {
  width: 480px;
  border: 1px solid #ffee99;
  margin: 0 auto;
  padding: 0.5rem;
  display: flex;
}
section {
  width: 240px;
}
aside {
  width: 600px;
  text-align: center;
  margin: 0 auto;
}
.small-text {
  width: 50px;
  text-align: center;
}
label {
  display: inline-block;
  width: 100px;
}
.small-label {
  width: 50px;
  text-align: center;
}
.row {
  width: 400px;
}
.btn {
  padding-top: 10px;
  padding-right: 10px;
  padding-bottom: 10px;
  padding-left: 10px;

  margin-top: 10px;
  margin-right: 10px;
  margin-bottom: 10px;
  margin-left: 10px;
}
.btn:hover {
  padding-top: 10px;
  padding-right: 10px;
  padding-bottom: 10px;
  padding-left: 10px;

  margin-top: 10px;
  margin-right: 10px;
  margin-bottom: 10px;
  margin-left: 10px;
}
.bold {
  font-weight: bold;
}
.test-button {
  background: darkgreen;
  color: #fff;
}
  <main>
    <section>
      <div class="row"><label for="padding" class="bold">padding</label><label class="small-label" for="padding">normal</label><label class="small-label" for="padding">hover</label></div>
      <div class="row"><label for="padding-top-normal">top</label><input type="text" value="10" class="small-text" id="padding-top-normal"><input type="text" value="10" class="small-text" id="padding-top-hover"></div>
      <div class="row"><label for="padding-right-normal">right</label><input type="text" value="10" class="small-text" id="padding-right-normal"><input type="text" value="10" class="small-text" id="padding-right-hover"></div>
      <div class="row"><label for="padding-bottom-normal">top</label><input type="text" value="10" class="small-text" id="padding-bottom-normal"><input type="text" value="10" class="small-text" id="padding-bottom-hover"></div>
      <div class="row"><label for="padding-left-normal">top</label><input type="text" value="10" class="small-text" id="padding-left-normal"><input type="text" value="10" class="small-text" id="padding-left-hover"></div>
      <div class="row"><label for="padding-height">height</label><input type="text" value="10" class="small-text" id="padding-height-normal"><input type="text" value="10" class="small-text" id="padding-height-hover"></div>
      <div class="row"><label for="padding-width">width</label><input type="text" value="10" class="small-text" id="padding-width-normal"><input type="text" value="10" class="small-text" id="padding-width-hover"></div>
  
    </section>
    <section>
      <div class="row"><label for="margin" class="bold">margin</label><label class="small-label" for="margin">normal</label><label class="small-label" for="margin">hover</label></div>
      <div class="row"><label for="margin-top-normal">top</label><input type="text" value="10" class="small-text" id="margin-top-normal"><input type="text" value="10" class="small-text" id="margin-top-hover"></div>
      <div class="row"><label for="margin-right-normal">right</label><input type="text" value="10" class="small-text" id="margin-right-normal"><input type="text" value="10" class="small-text" id="margin-right-hover"></div>
      <div class="row"><label for="margin-bottom-normal">top</label><input type="text" value="10" class="small-text" id="margin-bottom-normal"><input type="text" value="10" class="small-text" id="margin-bottom-hover"></div>
      <div class="row"><label for="margin-left-normal">top</label><input type="text" value="10" class="small-text" id="margin-left-normal"><input type="text" value="10" class="small-text" id="margin-left-hover"></div>
      <div class="row"><label for="margin-height">height</label><input type="text" value="10" class="small-text" id="margin-height-normal"><input type="text" value="10" class="small-text" id="margin-height-hover"></div>
      <div class="row"><label for="margin-width">width</label><input type="text" value="10" class="small-text" id="margin-width-normal"><input type="text" value="10" class="small-text" id="margin-width-hover"></div>
    </section>
  </main>
  <aside>
    <button class="btn">Test Button</button><button class="btn">Test Button</button>
    <br><br>  
    <button class="test-button" onclick="createConstFromIDs()">create const from Element IDs</button>
  </aside>
function createConstFromIDs() {
  let allIDs;
  document.querySelectorAll("[id]").forEach((item) => {
    allIDs += `const ${item.id.replaceAll('-','_')} = document.getElementById('${item.id}');\n`;
  });
  let _create_const = document.createElement('textarea');
  _create_const.setAttribute('id', 'create_const_from_ids');
  _create_const.setAttribute('style', 'width: 96%;height:200px;font-size:0.65rem;color:#0000ff;background:#f2f8ff;');
  document.body.insertAdjacentElement("beforeend", _create_const);
  create_const_from_ids.innerHTML = allIDs.replace('undefined', '');
  create_const_from_ids.scrollIntoView();
  setTimeout(function() {
    create_const_from_ids.focus();  
    create_const_from_ids.select();
  }, 2500);
}
Urtication answered 14/8 at 20:12 Comment(0)
L
-3

First of all, I would highly recommend jQuery. It has simplified my JavaScript development soooo much. (See RichieHindle's answer)

Second, I know that a lot of browsers keep a list of IDs for direct (fast) access, but I don't know of a way to access them. It would probably be browser-specific anyways, so that's probably not the best route.

Finally, the code:

var elementList = document.getElementsByTagName("*");
var idList = [];
for (var i in elementList) {
  if (elementList[i].id != "") {
    idList.push(elementList[i].id);
  }
}
// Do something with your array of ids
Lakes answered 18/8, 2011 at 22:52 Comment(5)
@patrick Haha, oops. It's been too long since I've used vanilla JavaScript. EditedLakes
It also will not work because there are at least three enumerable properties of the NodeList returned by getElementsByTagName that are not nodes (or elements), so the list of ids will contain three empty members that, when passed to getElementById, will return null. The OP may not be expecting that.Tramp
@RobG: Interesting; I didn't know that.Lakes
@RobG: So, is the check if (elementList[i].id != "") not enough? Can text nodes or comment nodes or nodes other than elements have an ID specified?Lakes
No, because NodeList properties that don't have an id property (e.g. NodeList.item.id) will return undefined, and undefined != ''. But undefined is a valid id, so you can't simply filter it out. You could try a hasOwnProperty test, but there's no guarantee that a host object will follow ECMA–262 for that.Tramp

© 2022 - 2024 — McMap. All rights reserved.