Cross Browsers tabs

I am having some problems with some JS code that does not work cross browsers

Here is my code


<html>
<head>
	<link rel="STYLESHEET" type="text/css" href="../../include/css/tab.css">
	<script src="../../include/js/tabpane.js" type="text/javascript"></script>
</head>
<body>
<div name="objBody">
	<div id="tabpane">
		<div>
			<h2>Contact</h2>
			<div>
				<br>THIS IS CONTACTS TEXT
			</div>
		</div>
		<div>
			<h2>Contact2</h2>
			<div>
				<br>THIS IS CONTACTS TEXT2222
			</div>
		</div>
	</div>
</div>
	<script type="text/javascript">
		var tp = new TabPane(document.getElementById("tabpane"));
	</script>

</body>
</html>


CSS


.tab_pane_holder {
	width: 100%;
	background-color: #336699;
	font-family: verdana;
	font-size: 8pt;
	border-right: 1px solid black;
	border-left: 1px solid black;
	border-top: 1px solid black;
}
.tab_normal {
	border-right: 1px solid black;
	border-left: 1px solid white;
	border-bottom: 1px solid black;
	border-top: 1px solid white;
	padding: 5px;
	background-color: #5a7edc;
	text-align: center;
	/*width: 100px;*/
	height: 10px;
	color: white;
}
.tab_active {
	border-right: 1px solid black;
	border-left: 1px solid black;
	border-top: 1px solid black;
	background-color: white;
	padding: 5px;
	text-align: center;
	/*width: 100px;*/
	height: 10px;
	color: black;
}
.tab_after_active {
	border-right: 1px solid black;
	border-left: 0px solid black;
	border-top: 1px solid white;
	border-bottom: 1px solid black;
	background-color: #5a7edc;
	padding: 5px;
	text-align: center;
	/*width: 100px;*/
	height: 10px;
	color: white;
}
.tab_before_active {
	border-left: 1px solid white;
	border-bottom: 1px solid black;
	background-color: #5a7edc;
	border-top: 1px solid white;
	text-align: center;
	padding: 5px;
	/*width: 100px;*/
	height: 10px;
	color: white;
}


JS


function TabPane(el)
{

	var tmp = this;
	this.element = el;
	this.tabs = new Array();
	this.divs = new Array();
	this.selected = null;
	for(var i = 0; i < el.childNodes.length; i++)
	{
		this.tabs[i] = this.element.childNodes[i].childNodes[0].innerHTML;
	}
	for(var i = 0; i < this.element.childNodes.length; i++)
	{
		this.divs[i] = this.element.childNodes[i];
	}
	for(var i = 0; i < this.element.childNodes.length; i++)
	{
		this.element.childNodes[i].removeChild(this.element.childNodes[i].childNodes[0]);
	}
	this.tabPane = document.createElement("div");
	this.element.insertBefore(this.tabPane,this.element.childNodes[0]);
	this.tabPane.className = "tab_pane_holder";
	for(var i = 0; i < this.tabs.length; i++)
	{
		var x = this.tabs[i];
		this.tabs[i] = document.createElement("span");
		this.tabPane.appendChild(this.tabs[i]);
		this.tabs[i].innerHTML = x;
		this.tabs[i].className = "tab_normal";
		this.tabs[i].style.cursor = "hand";
		this.tabs[i].onselectstart = function()
		{
			return false;
		}
		this.tabs[i].onclick = function()
		{
			tmp.showPage(this);
		}
	}
	for(var i = 0; i < this.divs.length; i++)
	{
		this.divs[i].style.display = "none";
		this.divs[i].style.width = this.element.style.width;
		this.divs[i].style.height = this.element.style.height;
		this.divs[i].style.overflow = "auto";
		this.divs[i].style.borderRight = "1px solid black";
		this.divs[i].style.borderBottom = "1px solid black";
		this.divs[i].style.borderLeft = "1px solid black";
	}
	this.showPage = function(el)
	{
		var x,y;
		for(var i = 0; i < this.tabs.length; i++)
		{
			if(el == this.tabs[i])
			{
				x = i;
			}
		}
		y = ((x-1) < 0)?0:(x-1);
		for(var i = 0; i < this.tabs.length; i++)
		{
			this.tabs[i].className = "tab_normal";
		}
		this.tabs[y].className = (y == x)?"tab_active":"tab_before_active";
		if(this.tabs[y+1])
		{
			this.tabs[y+1].className = (y == x)?"tab_after_active":"tab_active";
		}
		if(this.tabs[y+2])
		{
			this.tabs[y+2].className = (y == x)?this.tabs[y+2].className:"tab_after_active";
		}
		if(x == 0)
		{
			this.tabs[x].style.borderLeft = "0px solid black";
		}
		for(var i = 0; i < this.divs.length; i++)
		{
			var show = (i == x)?"block":"none";
			this.divs[i].style.display = show;
		}
	}
	this.showPage(this.tabs[0])
}


Wow, that overhauled script, courtesy of oddz, is working nicely now in other browsers. I had a bit of a play with the original, but gave up on the first hurdle.


function TabPane(el)
{

	var tmp = this;
	this.element = el;
	this.tabs = new Array();
	this.divs = new Array();
	this.selected = null;
	
	var removeItems = [];
	var count = 0;
	for(var i=0;i<el.childNodes.length;i++) {
		
		if(el.childNodes[i].nodeType != 1) continue;
		
		var heading = null;
		var content =  null;
		
		for(var j=0;j < el.childNodes[i].childNodes.length;j++) {
			
			if(el.childNodes[i].childNodes[j].nodeName === 'H2') {
				heading = el.childNodes[i].childNodes[j];
			}
			
			if(el.childNodes[i].childNodes[j].nodeName === 'DIV') {
				content = el.childNodes[i].childNodes[j];
			}
			
		}
		
		if(content !== null && heading !== null) {
			this.tabs[count] = heading.firstChild.nodeValue;
			this.divs[count++] = content;
			removeItems.push(heading);
		}
		
	}
	
	for(var i=0;i < removeItems.length;i++) {
		removeItems[i].parentNode.removeChild(removeItems[i]);
	}
	
	this.tabPane = document.createElement("div");
	this.element.insertBefore(this.tabPane,this.element.childNodes[0]);
	this.tabPane.className = "tab_pane_holder";
	
	
	
	
	for(var i = 0; i < this.tabs.length; i++)
	{
		var x = this.tabs[i];
		this.tabs[i] = document.createElement("span");
		this.tabPane.appendChild(this.tabs[i]);
		this.tabs[i].innerHTML = x;
		this.tabs[i].className = "tab_normal";
		this.tabs[i].style.cursor = "hand";
		this.tabs[i].onselectstart = function()
		{
			return false;
		}
		this.tabs[i].onclick = function()
		{
			tmp.showPage(this);
		}
	}
	for(var i = 0; i < this.divs.length; i++)
	{
		this.divs[i].style.display = "none";
		this.divs[i].style.width = this.element.style.width;
		this.divs[i].style.height = this.element.style.height;
		this.divs[i].style.overflow = "auto";
		this.divs[i].style.borderRight = "1px solid black";
		this.divs[i].style.borderBottom = "1px solid black";
		this.divs[i].style.borderLeft = "1px solid black";
	}
	this.showPage = function(el)
	{
		var x,y;
		for(var i = 0; i < this.tabs.length; i++)
		{
			if(el == this.tabs[i])
			{
				x = i;
			}
		}
		y = ((x-1) < 0)?0:(x-1);
		for(var i = 0; i < this.tabs.length; i++)
		{
			this.tabs[i].className = "tab_normal";
		}
		this.tabs[y].className = (y == x)?"tab_active":"tab_before_active";
		if(this.tabs[y+1])
		{
			this.tabs[y+1].className = (y == x)?"tab_after_active":"tab_active";
		}
		if(this.tabs[y+2])
		{
			this.tabs[y+2].className = (y == x)?this.tabs[y+2].className:"tab_after_active";
		}
		if(x == 0)
		{
			this.tabs[x].style.borderLeft = "0px solid black";
		}
		for(var i = 0; i < this.divs.length; i++)
		{
			var show = (i == x)?"block":"none";
			this.divs[i].style.display = show;
		}
	}
	this.showPage(this.tabs[0])
}

The entire top portion had to be rewritten to account for white space. Needless repetition has also been reduced in the process, though I didn’t touch anything besides the top part. Where ever you pulled that from its one dirty @ss script. No comments, bunch of repetition no organization using methods – yuck.

That script seems to have been written and tested with only IE in mind. It makes frequent use of code like this:

for(var i = 0; i < el.childNodes.length; i++)
{
    this.tabs[i] = this.element.childNodes[i].childNodes[0].innerHTML;
}

That will come unstuck cross-browser, because searching blindly for childNodes like that (without testing for nodeType) will cause some browsers to find a text node, while other browsers will find an element node at the same point in the code execution. Whitespace in the markup will affect the result.

If you didn’t write that code, you may be better off looking for another script.