Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does getElementById work on elements created by javascript?

I've created two functions to load expanded views of a month in the archive section of my blog when it's link is clicked:

// Load open view of a month in the Archive section
function loadMonth(date) {
  // Remove other open month
     removeMonth();

  // Hide opening month's link
  // Define variable to hold month anchor tag
     var monthLink = document.getElementById(date); 
     monthLink.style.display = "none"; // Hide month anchor

  // Define new open month node and its attributes
     var openMonth = document.createElement("div");
     openMonth.setAttribute("id", "openMonth");
     openMonth.innerHTML = "Testing one, two, three.";

  // Insert open month
  // Define a variable to hold the archive Div node
     var archive = document.getElementById("archive");
  // Insert the open month in the archive node before it's link
     archive.insertBefore(openMonth,monthLink);

     return;
  }


// Close full view of a month and replace with respective link
function removeMonth() {

  // Define global function vars
     var archive = document.getElementById("archive"); // Define a var to hold the archive Div node
     var openMonth = document.getElementById("openMonth"); // Define var to hold the open month Div node

  // Get date of full view month for replacement anchor tag where ID = date
     var month = openMonth.getElementsByTagName("span")[0].innerHTML; // Define var to hold the name of the open month
     var date = (new Date(month + " 15, 2008").getMonth() + 1); // Define var to hold the numerical equivalent of the month
     var year = archive.getElementsByTagName("h3")[0].innerHTML.split(" "); // Define var to hold the year being displayed in the archive
     date = year[1] + "" + date; // Change date var to string and insert year

  // Remove the open month
     archive.removeChild(openMonth);

  // Show Link for that month
     document.getElementById(date).className = "big"; // Fixes display error when anchor has class firstLink
     document.getElementById(date).style.display = "inline"; // Returns link from display "none" state
     return;
}

The functions work when run on the original static content, but when a second link is clicked in the archive, they do nothing. I am wondering if maybe because the elements that were created by my functions cannot be called by document.getElementById. Perhaps a different method of accessing those nodes should be used, or maybe replacing "document" with something that works on javascript created elements too?

Any advice would be greatly appreciated. Thanks.

like image 631
bloudermilk Avatar asked Dec 05 '08 07:12

bloudermilk


People also ask

How does document getElementById work JavaScript?

getElementById() The Document method getElementById() returns an Element object representing the element whose id property matches the specified string. Since element IDs are required to be unique if specified, they're a useful way to get access to a specific element quickly.

Does getElementById only work on document?

getElementById() is a quick way to access an element. Unlike the querySelector() method, the getElementById() is only available on the document object, not other elements. In this syntax, the id is a string that represents the id of the element to select. The id is case-sensitive.

Which JavaScript method is used to access an HTML element by id?

The getElementById Method The most common way to access an HTML element is to use the id of the element.

Should I use getElementById or querySelector?

The getElementById method retrieves an element by its DOM ID. Both methods have wide browser support. You should opt to use the querySelector method if you need to select elements using more complex rules that are easily represented using a CSS selector.


2 Answers

You should be fine with:

openMonth.id = "openMonth";

getElementById() can only work if the element is part of the DOM, but since you already use insertBefore() this is merely a side note.

There is a common source of confusion involved here: An attribute named "id" is not necessarily the one that is defined as the element ID in the underlying DTD. In declarative HTML, they are linked automatically. When you use setAttribute(), you are not more than creating an attribute named "id". The element ID itself is accessible via the .id property.

Edit

The following works for me:

function test()
{
  // create element, set ID
  var p = document.createElement("P");
  p.innerHTML = "Look ma, this is a new paragraph!";
  p.id = "newParagraph";

  // make element part of the DOM
  document.getElementsByTagName("BODY")[0].appendChild(p);

  // get element by ID
  var test = document.getElementById("newParagraph");
  alert(test.innerHTML);
}
like image 167
Tomalak Avatar answered Nov 15 '22 01:11

Tomalak


To answer your main question: document.getElementById does work with dynamically added elements.

In your sample code you are creating the openMonth div and setting its innerHTML. Then in the remove tag you are doing this:

var month = openMonth.getElementsByTagName("span")[0].innerHTML;

openMonth.getElementsByTagName("span") will not exist and will get an error because there are no span elements. I don't know if this is a mistake in the code or if it is just a incomplete sample in the post.

like image 42
Ryan Cook Avatar answered Nov 15 '22 00:11

Ryan Cook