Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

insertBefore crashing Firefox

Status
Not open for further replies.

Ghodmode

Programmer
Feb 17, 2004
177
0
0
NZ
I'm trying to create some code that will automatically generate a table of contents for the page it's on, and insert anchor links for the table of contents. When I try to use the insertBefore() function Firefox hangs and has to be closed forcefully.

Am I using it wrong?

I created a demo of my problem... [!]Warning! Clicking on the button causes the browser to freeze/hang/crash![/!] ...

Code:
<!DOCTYPE html
	PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"[URL unfurl="true"]http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">[/URL]

<html xmlns="[URL unfurl="true"]http://www.w3.org/1999/xhtml"[/URL] xml:lang="en" lang="en">
<head>
	<meta http-equiv="content-style-type" content="text/css" />
	<meta http-equiv="content-script-type" content="text/javascript" />
	<script type="text/javascript">
	function ib( option ) {
		content_block = document.getElementById( "content" );
		var elements  = content_block.getElementsByTagName( "*" );

		for ( i = 0; i < elements.length; i++ ) {
			if ( elements[i].tagName == "H1" ) {

				var name = elements[i].innerHTML;
				text = document.createTextNode( name );

				linkname = elements[i].innerHTML.replace( /\W/g, "" );

				var p = document.createElement( "P" );
				var t = document.createTextNode( "This is a test" );
				p.appendChild( t );

				if ( option == "element" ) {
					content_block.insertBefore( p, elements[i] );
				} else if ( option == "i" ) {
					content_block.insertBefore( p, content_block.childNodes[i] );
				} else if ( option == "firstchild" ) {
					content_block.insertBefore( p, content_block.firstChild );
				} else if ( option == "child0" ) {
					content_block.insertBefore( p, content_block.childNodes[0] );
				}
			}
		}
	} // End ib function
	</script>
	<style type="text/css">
	input { width: 30em; }
	</style>
</head>
<body>
<form action="#" method="post" onsubmit="return false;">
<input type="button" onclick="ib('element');"    value="insertBefore element" /><br/>
<input type="button" onclick="ib('i');"          value="insertBefore childNodes[i]" /><br/>
<input type="button" onclick="ib('firstchild');" value="insertBefore firstchild" /><br/>
<input type="button" onclick="ib('child0');"     value="insertBefore childNodes[0]" />
</form>

<div id="content">
<h1>Web Development</h1>

<h2>Welcome to My Site</h2>
<p>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin et
</p>
</div><!-- close "content" -->
</body>
</html>

Thank you.

--
-- Ghodmode

Give a man a fish and he'll come back to buy more... Teach a man to fish and you're out of business.
 
I think I figured it out...

When I inserted the new element before the current element, it changed the array as I was iterating through it, pushing down the H1 element. As a result, FF repeatedly found the same H1 element and repeatedly tried to insert a new element before it.

The solution was to save a list of elements and necessary details in separate arrays, then process those in another loop.

Here's the important part of the working code ...

Code:
function ib( option ) {
	content_block = document.getElementById( "content" );
	var elements  = content_block.getElementsByTagName( "*" );
	var items     = new Array();
	var linknames = new Array();

	var p = document.createElement( "P" );
	var t = document.createTextNode( "This is a test" );
	p.appendChild( t );

	for ( i = 0; i < elements.length; i++ ) {
		if ( elements[i].tagName == "H1" ) {

			linkname = elements[i].innerHTML.replace( /\W/g, "" );
			items.push( elements[i] );
			linknames.push( linkname );
		}
	}

	for ( i = 0; i < items.length; i++ ) {
		var a = document.createElement( "A" );
		a.name = "#" + linknames[i];
		content_block.insertBefore( a, items[i] );
	}
} // End ib function


--
-- Ghodmode

Give a man a fish and he'll come back to buy more... Teach a man to fish and you're out of business.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top