Why I never wrote this function before is a mystery.
In my experience, people* designing XML response docs for Ajax-y type applications often re-use xHMTL attributes. href
and src
are common examples. One other one that I’ve run into pretty often is id
. Since Javascript’s getElementById()
relies on the document’s DTD defining the id
attribute doing something like
xml_document.getElementById('myid')
returns null
when pointed at the sort of informal XML documents people often spit out for these kind of things.
To remedy that, I wrote this:
function getElementByIdMXL(the_node,the_id) { //get all the tags in the doc node_tags = the_node.getElementsByTagName('*'); for (i=0;i<node_tags.length;i++) { //is there an id attribute? if (node_tags[i].hasAttribute('id')) { //if there is, test its value if (node_tags[i].getAttribute('id') == the_id) { //and return it if it matches return node_tags[i]; } } } }
where the_node
is the DTD-less XML document and the_id
is the id
to search for. It’s a pretty simple script really, but it would have been useful a couple of times in recent memory.
Looking at that bit of code made me want to create a version that searched for arbitrary attribute/value pairs. Since I’ve looked at getElementsByClass
a thousand times it practically wrote itself:
function getElementsByAttribute(the_attribute, the_value, the_node) { if ( the_node == null ) the_node = document; var node_tags = the_node.getElementsByTagName('*'); var results = new Array(); for (i=0, j=0; i<node_tags.length;i++) { if (node_tags[i].hasAttribute(the_attribute)) { if (node_tags[i].getAttribute(the_attribute) == the_value) { results[j] = node_tags[i]; j++; } } } return results; }
The only real difference between the two is the second returns an array and the first just returns the one object.
These aren’t really groundbreaking, of course. They’re just a couple of bits of code I thought I’d share…
*that definitely includes me
A few notes…
1.) I hope this wasn’t meant as a replacement for the getElementsByClass, as it will fail if more than one class is applied to an element. 😉
2.) Minor, but you can save some code, and avoid some global variables (i & j), with a few adjustments to your function.
function getElementsByAttribute(the_node, the_attribute, the_value){
var node_tags = the_node.getElementsByTagName(‘*’);
var results = [];
for(var i=0;i
Doh!… Less than symbol stripped out… lets try this:
function getElementsByAttribute(the_node, the_attribute, the_value){
var node_tags = the_node.getElementsByTagName(‘*’);
var results = [];
for(var i=0;i<node_tags.length;i++){
if(node_tags[i].hasAttribute(the_attribute)){
if(node_tags[i].getAttribute(the_attribute) == the_value){
results.push(node_tags[i]);
}
}
}
return results;
}
definitely not meant as a replacement for getElementsByClass. To be honest, I’m not sure how I would use it as it was a pure “hey, I could do that too” kind of thing. I can imagine some uses and once I put it to use, I imagine there’ll be some adjustments to make.
Speaking of which-
push(). *duh* Thanks 🙂
It’s very help full, but it’s a problem in IE.
in IE, its doesn’t work ! IE Sayd, “Error: Object Doesn’t Support This Property or Method”.
Suwondo, got a sample page?
i will try this out, but I’m thinking 2 questions. 1) Does it make an “index” of the id’s? because this is one of the appealing performance-boosting aspects of the getElementById() method. and
2) Is it possible to have a DTD that just defines a few things, rather then explicitly defining all the tags and everything? If so, can you show the specific requirements of just defining the id thing?