Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 3 of 3
  1. #1
    New to the CF scene
    Join Date
    Sep 2009
    Location
    Manchester/Birmingham UK
    Posts
    1
    Thanks
    0
    Thanked 0 Times in 0 Posts

    XMLHttpRequest problems with IE 8 or WAMP

    Hi there, I have been developing the following code which I run on my WAMP localhost. The following code works in Firefox but not IE (surprise surprise).

    I know I have gone about this solution in a weird way, but my XML files can be recursive. So I run into problems when using getElementsByTagName.

    Basically my XML file denotes a multi level navigation menu for a website, where li elements would contain more ul element blocks etc etc. Hence the 'suboptions' tag and the idea is that (theoretically at least) it could have as many levels as required.

    XML File
    Code:
    <?xml version="1.0" encoding="ISO-8859-1"?>
    
    <menu>
    	<option>
    		<title>Home</title>
    		<link>home.html</link>
    		<suboptions>
    			<option>
    				<title>News</title>
    				<link>home.html#news</link>
    			</option>
    		</suboptions>
    	</option>
    	<option>
    		<title>Vercors Overview</title>
    		<link>vercors_overview.html</link>
    	</option>
    	<option>
    		<title>SV Projects</title>
    		<link>projects.html</link>
    		<suboptions>
    			<option>
    				<title>Long Term Projects</title>
    				<link>projects.html#ongoing</link>
    			</option>
    			<option>
    				<title>Scialet de la Jarjatte</title>
    				<link>projects.html#scialet_de_la_jarjatte</link>
    			</option>
    		</suboptions>
    	</option>
    	<option>
    		<title>Vercors Caving</title>
    		<link>vercors_caving.html</link>
    		<suboptions>
    			<option>
    				<title>Vercors Caving Log</title>
    				<link>caving_log.html</link>
    			</option>
    			<option>
    				<title>Scialet du Combeau</title>
    				<link>scialet_du_combeau.html</link>
    			</option>
    			<option>
    				<title>Gouffre Berger</title>
    				<link>gouffre_berger.html</link>
    			</option>
    		</suboptions>
    	</option>
    	<option>
    		<title>A Caver's Guide</title>
    		<link>cave_guide.html</link>
    		<suboptions>
    			<option>
    				<title>Zone 1</title>
    				<link>cave_guide.html#zone1</link>
    			</option>
    			<option>
    				<title>Zone 2</title>
    				<link>cave_guide.html#zone2</link>
    			</option>
    			<option>
    				<title>Zone 3</title>
    				<link>cave_guide.html#zone3</link>
    			</option>
    			<option>
    				<title>Zone 4</title>
    				<link>cave_guide.html#zone4</link>
    			</option>
    			<option>
    				<title>Zone 5</title>
    				<link>cave_guide.html#zone5</link>
    			</option>
    			<option>
    				<title>Zone 6</title>
    				<link>cave_guide.html#zone6</link>
    			</option>
    			<option>
    				<title>Zone 7</title>
    				<link>cave_guide.html#zone7</link>
    			</option>
    			<option>
    				<title>Zone 8</title>
    				<link>cave_guide.html#zone8</link>
    			</option>
    			<option>
    				<title>Zone 9</title>
    				<link>cave_guide.html#zone9</link>
    			</option>
    			<option>
    				<title>French Caving Terms</title>
    				<link>french_caving_terms.html</link>
    			</option>
    		</suboptions>
    	</option>
    	<option>
    		<title>Vercors Walking</title>
    		<link>vercors_walking.html</link>
    	</option>
    	<option>
    		<title>Canyons</title>
    		<link>canyons.html</link>
    	</option>
    	<option>
    		<title>Vercors Skiing</title>
    		<link>vercors_skiing.html</link>
    	</option>
    	<option>
    		<title>Gallery</title>
    		<link>gallery.html</link>
    	</option>
    	<option>
    		<title>Useful Links</title>
    		<link>links.html</link>
    	</option>
    </menu>
    HTML/Javascript file
    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html>
    	<head>
    		<link href="styles/main.css" rel="stylesheet" type="text/css"/>
    		<script type="text/javascript">	
    			function getXmlHttpObject(){
    				if (window.XMLHttpRequest){
    					// code for IE7+, Firefox, Chrome, Opera, Safari
    					return new XMLHttpRequest();
    				}
    				if (window.ActiveXObject){
    					// code for IE6, IE5
    					return new ActiveXObject('Microsoft.XMLHTTP');
    				}
    				return null;
    			}
    			
    			function loadXMLDoc(url){
    				xmlhttp = getXmlHttpObject();
    				if (xmlhttp == null){
    					alert ('Your browser does not support XMLHTTP!');
    					return;
    				}
    				xmlhttp.onreadystatechange = onResponse;
    				xmlhttp.open('GET', url, true);
    				xmlhttp.send(null);
    			}
    			
    			function onResponse(){
    				if(xmlhttp.readyState != 4) return;
    				if(xmlhttp.status != 200){
    					alert('Problem retrieving XML data');
    					return;
    				}
    				var tree = xmlhttp.responseXML.documentElement; //Get root element
    				document.getElementById('nav').appendChild(parseOptionGroup(tree));
    			}
    			
    			function parseOptionGroup(tree){
    				if(tree.children.length > 0){
    					var ul = document.createElement('ul');
    					var child = tree.firstElementChild;
    					while(child != null){
    						li = parseOptionXML(child);						
    						ul.appendChild(li);
    						
    						child = child.nextElementSibling;
    					}
    					li.setAttribute('class', 'nav_bottom');
    					return ul;
    				}
    			}
    			
    			function parseOptionXML(node){			
    				var li = document.createElement('li');
    				var text = null;
    				var href = null;
    				var ul = null;
    				
    				for(i = 0; i < node.childElementCount; i++){
    					var child = node.children.item(i);
    					switch (child.tagName) {
    						case "title":
    							text = child.textContent;
    							break;
    						case "link":
    							href = child.textContent;
    							break;
    						case "suboptions":
    							ul = parseOptionGroup(child);
    							break;
    					}
    				}
    				if(text != null && href != null){
    					var a = document.createElement('a');
    					a.setAttribute('href', href);
    					a.appendChild(document.createTextNode(text));
    					li.appendChild(a);
    					if(ul != null){
    						li.appendChild(ul);
    						li.setAttribute('class', 'nav_expand');
    					}
    				}
    				return li;
    			}
    		</script>
    	</head>
    	<body onload="loadXMLDoc('menu.xml')">
    		<div id="nav">
    		</div>
    	</body>
    </html>
    What I get when running the code in IE8
    0){ var ul = document.createElement('ul'); var child = tree.firstElementChild; while(child != null){ li = parseOptionXML(child); ul.appendChild(li); child = child.nextElementSibling; } li.setAttribute('class', 'nav_bottom'); return ul; } } function parseOptionXML(node){ var li = document.createElement('li'); var text = null; var href = null; var ul = null; for(i = 0; i < node.childElementCount; i++){ var child = node.children.item(i); switch (child.tagName) { case "title": text = child.textContent; break; case "link": href = child.textContent; break; case "suboptions": ul = parseOptionGroup(child); break; } } if(text != null && href != null){ var a = document.createElement('a'); a.setAttribute('href', href); a.appendChild(document.createTextNode(text)); li.appendChild(a); if(ul != null){ li.appendChild(ul); li.setAttribute('class', 'nav_expand'); } } return li; }
    Does anyone know why I cant get this to work in IE? Have I used unsupported methods/attributes?
    I have had a search around on google and I cant find a decent website that can tell me what DOM technologies IE does and does not support, so if anyone has a decent link to something similar that would be awesome!

  • #2
    Kor
    Kor is offline
    Red Devil Mod Kor's Avatar
    Join Date
    Apr 2003
    Location
    Bucharest, ROMANIA
    Posts
    8,478
    Thanks
    58
    Thanked 379 Times in 375 Posts
    firstElementChild, childElementCount and nextElementSibling selectors (and all the DOM traversal selectors)are not implemented in IE. Furthermore, IE and Moz count the child nodes in different ways. FF counts the "gaps" (possible text nodes) as well, while IE counts only some of them.

    The crossbrowser workaround could be one based on the nodeType attribute (check whether a child node is a tag node or not within a loop through the child nodes) and the nextSibling / previousSibling crossbrowser selectors.

    Moreover, IE does to treat the class as an attribute, thus element.setAttribute('class','someclass') woun't work. Instead you should use DOM 0 crossbrowser syntax:
    Code:
    element.className='someclass';
    textContent is not the best choice. I would have rather used:
    Code:
    element.firstChild.nodeValue;
    //or
    element.firstChild.data;
    Furthermore, you should use rather the nodeName selector, not the tagName. The advantage is that nodeName will return '#text' if the node is a text node, while tagName will return an error and block the code.

    A good site regarding the DOM (and javascript) compatibility is quirksmode
    Last edited by Kor; 10-07-2009 at 09:42 AM.
    KOR
    Offshore programming
    -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

  • #3
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,371
    Thanks
    11
    Thanked 591 Times in 572 Posts
    Quote Originally Posted by Kor View Post
    textContent is not the best choice. I would have rather used:
    Code:
    element.firstChild.nodeValue;
    //or
    element.firstChild.data;
    there is a problem with data and nodeValue, stemming back to the xbrowser differences you noted: firstChild is not always a proper element.

    text content is probably what the OP wants, since it grabs all the text nodes and text nodes under child elements.
    the only drawback is that textContent doesn't work in IE, and it misses inputs...

    but that's not a huge issue, because we can try to assign a few properties, and take only the first one that works.

    for example:
    Code:
    href = child.value || child.innerText || child.text || child.textContent;
    should work in all browsers...

    node.childElementCount should be node.childNodes.length;

    i see you are also using the brand new tree.children collection, which is also not included in IE.
    it's like child nodes, but it skips text nodes. you can use getElmentsByTagName, or loop through childNodes and ignore the text nodes with an if statement.


    to keep everything simple and concise, i like to write a few helper functions for traversing the dom.
    i don't know what your level of JS is, but i can't stand using the dom without
    1. coercing collections into true arrays
    2. using the javascript 1.6 array methods on the arrays.

    it makes it SOO much easier to do things cross browser when you have a reliable and consistent set of functions to do what you need to do. You can easily gather and filter collections and handle special cases without a ton of if statements.

    i can whip up some examples if you like.

    cheers.
    Last edited by rnd me; 10-07-2009 at 07:29 PM.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/9/03) IE7:0.1, IE8:4.6, IE11:9.1, IE9:3.1, IE10:3.0, FF:17.2, CH:46, SF:11.4, NON-MOUSE:38%


  •  

    Tags for this Thread

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •