Need help with Javascript DOM scripting

ibex333

Diamond Member
Mar 26, 2005
4,094
123
106
So I just got into the topic about DOM...

I am trying to build a function that would loop through all nodes in the document and if the selected node was found it will say so and if it was not found it will also say so.

Something in my code is not working, and I messed up on my if/else if cases somewhere because the not found message comes out regardless. Can someone please tell me what I am doing wrong? Maybe I am just tired, but I cannot see it...


Code:
function CheckNodeType() {
var selection = parseInt(prompt("This program checks the webpage to see if the node type you entered exists.\n\nPlease enter:\n\n1 to check for Element\n2 to check for Attr\n3 to check for Text\n8 to check for Comment \n9 to check for Document"));
if (selection < 1 || selection > 9){

alert("Your selection was not what the program is asking for! Run the program again");
}
else if(selection >3 && selection <8){
alert("Your selection was not what the program is asking for! Run the program again");
}

else if(isNaN(selection)){
alert("Your selection was not what the program is asking for! Run the program again");
}


 var childNodes = document.childNodes;
 
	     for(var i=0; i<childNodes.length; i++) {
	       if (childNodes[i].nodeType === 1 && selection === 1) {
	       alert("Yes, there is an Element node");
		   }
		   else if (childNodes[i].nodeType === 2 && selection === 2){ 
	       alert("Yes, there is an Attr node") ;
		   }
		   else if (childNodes[i].nodeType === 3 && selection === 3){ 
	       alert("Yes, there is a Text node") ;
		   }
		   else if (childNodes[i].nodeType === 8 && selection === 8){ 
	       alert("Yes, there is a Comment node") ;
		   }
		   else if (childNodes[i].nodeType === 9 && selection === 9){ 
	       alert("Yes, there is a Document node") ;
		   }
		   else { 
	       alert("Node type was not found");
		   }
     }
 

Savatar

Senior member
Apr 21, 2009
230
1
76
Usually people use two equals signs for a comparison operator, but the code you pasted actually seems to work fine for me. It detected an element node (node type 1) without a hitch.

One thing you'll probably want to change, though, is that you're only checking the child nodes - not the document node itself - so it's never going to return yes for the top-level document node.

You could add something like:
if(document.nodeType == 9 && selection == 9)
{
alert("Yes, there is a Document node") ;
}

just before [or after] the for loop
 
Last edited:

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
14
81
www.markbetz.net
Usually people use two equals signs for a comparison operator, but the code you pasted actually seems to work fine for me. It detected an element node (node type 1) without a hitch.

Thing is, '===' will return false if the two operands aren't the same type as well as the same value. So I searched for the type of the value returned by parseInt, and it seems to be 'Number.' I searched for the type of the value returned from .nodeType, and one source says string, another says 'integer.' Always nice to have these things nailed down :).

So, could it be that different browsers are returning different types? OP, if you change that operator to '==' and it starts working I'm going to guess that's the case.
 

GregGreen

Golden Member
Dec 5, 2000
1,688
5
81
To start: I'm guessing the code you are running has this because you are getting at least something, but what you pasted is missing two }

If I understand correctly, your problem is that you are returning an alert for every childNode, so you get multiple messages and at least one of them says that the Node type was not found. To fix this, you'll want to loop through until you find one of that type. If you do, then alert about that type, and break out of the loop. If you don't find one, display message about the node type not being found.

Without changing your code too much, I mocked this up:
Code:
function CheckNodeType() {
  var selection = parseInt(prompt("This program checks the webpage to see if the node type you entered exists.\n\nPlease enter:\n\n1 to check for Element\n2 to check for Attr\n3 to check for Text\n8 to check for Comment \n9 to check for Document")),
    childNodes = document.childNodes,
    alertMsg,
    i;
  
  if (selection < 1 || selection > 9) {
    alert("Your selection was not what the program is asking for! Run the program again");
  }
  else if (selection >3 && selection <8) { 
    alert("Your selection was not what the program is asking for! Run the program again");
  }
  else if (isNaN(selection)) {
    alert("Your selection was not what the program is asking for! Run the program again");
  }

  for (i = 0; i < childNodes.length; i++) {
    if (childNodes[i].nodeType === 1 && selection === 1) {
      alertMsg = "Yes, there is an Element node";
      break;
    }
    else if (childNodes[i].nodeType === 2 && selection === 2) {
      alertMsg = "Yes, there is an Attr node";
      break;
    }
    else if (childNodes[i].nodeType === 3 && selection === 3) {
      alertMsg = "Yes, there is an Text node";
      break;
    }
    else if (childNodes[i].nodeType === 8 && selection === 8) {
      alertMsg = "Yes, there is an Comment node";
      break;
    }
    else if (childNodes[i].nodeType === 9 && selection === 9) {
      alertMsg = "Yes, there is an Document node";
      break;
    }
  }

  if (!alertMsg) {
    alertMsg = "Node type was not found";
  }

  alert(alertMsg)
}

I searched for the type of the value returned from .nodeType, and one source says string, another says 'integer.'

It's type should always be 'number' (and from my quick testing it does). Where did you see something about it being 'integer'? I ask because there isn't an integer type in JavaScript.

Usually people use two equals signs for a comparison operator

In JavaScript, most people use the strict equality operator (===) because the non-strict operator (==) coerces type using rules that are "complicated and unmemorable" and "lack transitivity" (if you don't mind me quoting Crockford). Use == and != at your own risk in JS.
 

Ken g6

Programming Moderator, Elite Member
Moderator
Dec 11, 1999
16,836
4,816
75
GregGreen beat me to it, but...
the not found message comes out regardless
Well, the program is "alert"ing on every node. It seems like you would want to search through all the nodes before reporting whether a node was found or not, wouldn't you? ;)

I've been writing JS for years and didn't know about the === issue! :eek: But, then, I'm used to writing Perl and having it Do What I Mean.

Edit: I think I shied away because in some languages, like Java I think, something like the following would report "Different" because they're different objects:
Code:
var a = "xxx";
var b = "xx" + "x";
if (a === b) alert("Same");
else alert("Different");
 
Last edited:

GregGreen

Golden Member
Dec 5, 2000
1,688
5
81
GregGreen beat me to it, but...
Edit: I think I shied away because in some languages, like Java I think, something like the following would report "Different" because they're different objects:
Code:
var a = "xxx";
var b = "xx" + "x";
if (a === b) alert("Same");
else alert("Different");

Fun fact:
Code:
var a = new String("xxx");
var b = new String("xxx");
If you had done the above instead of what you did, neither == or === would think they are equal in JS because they are different objects and only the same instance of an object will return equal lol
 

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
14
81
www.markbetz.net

ibex333

Diamond Member
Mar 26, 2005
4,094
123
106
Thanks a lot everyone. That really helped.

Greg, just want to make sure that I understand this... So in my code, even if a node was found, the loop would continue to iterate for the duration of length and would trigger the "not found" message. Correct?

So by breaking, once the node is found, program is done and will not proceed to any other checks.


Code:
if (!alertMsg) {
    alertMsg = "Node type was not found";
  }

...what this piece of code accomplishes is triggers only if there was no prior alert event, which means that no nodes were found, which is precisely what I was looking for. This is a beautiful solution, but I'm afraid my thought process is nowhere near as advanced as yours. I was thinking more about how if/else/else if statements work. (or at least how I thought they work) If the previous statement was false, program checks the next case, if that one was false, it checks the next, until it runs into something that's true. So I thought that if all cases were false, the last "else" case would be the only one that would trigger, because it's the only one left that is "true".
 

GregGreen

Golden Member
Dec 5, 2000
1,688
5
81
Thanks a lot everyone. That really helped.

Greg, just want to make sure that I understand this... So in my code, even if a node was found, the loop would continue to iterate for the duration of length and would trigger the "not found" message. Correct?

So by breaking, once the node is found, program is done and will not proceed to any other checks.

You got it.

I was thinking more about how if/else/else if statements work. (or at least how I thought they work) If the previous statement was false, program checks the next case, if that one was false, it checks the next, until it runs into something that's true. So I thought that if all cases were false, the last "else" case would be the only one that would trigger, because it's the only one left that is "true".

I think you've got it now -- with your original for loop, you were going through that if/else if/else tree for each individual DOM node instead of all of them at once. The if/else if/else bit was mostly correct, just a little understanding misunderstood with the for loop.

The more "official" sources say it's an unsigned short...

https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType

Javascript typing makes my brain hurt.

I think this must be a reference to the C/C++/whatever code that powers Firefox/WebKit/etc because there is definitely no unsigned short in JS. MDN is usually right -- maybe one of us should update it :p