Link to home
Start Free TrialLog in
Avatar of johnny99
johnny99

asked on

document.write() never finishes in Netscape 4

I've got a whole load of stuff in DHTML menus which I want to write to the document, and I've made the code smaller by putting all the menus into arrays, then iterating through the arrays more or less like this in the HEAD:

     menu1 = new Array(
          'label1','URL1',
          'label2','URL2',
          [etc]
     )

     document.write('<table>')
     for(i=0;i<menu1.length;i+=2){
          document.write('<tr><td>')
          document.write('<A HREF="menu1[(i+1)]">menu1[i]</A></td></tr>')
     }
    document.write('</table>')
     
This is rather simplified, there's a mass of stylesheet information in there too, but I don't think it matters in terms of my question.

This works fine in IE, and Netscape 6, but what happens in Netscape 4 is that the document.write() statements never seem to end.

The document just keeps loading and loading, and when I hit the Stop button, the menus appear, but not until.

Is there some known bug in IE4 with document.write()? is it possible that something in the actual code being written is preventing Netscape 4 from realising it's finished writing?



Avatar of rootnash
rootnash

after using document.write, u need to close at the end. use document.close()
sorry, thought ur creating a new window.
Avatar of johnny99

ASKER

Just to clarify, no I'm not opening a new window, I'm just writing invisible DIVs for DHTML menus.
A couple of things:

- document.write has to be used in this way:

document.open();

document.write( ... ) or document.writeln( ... ) ...

document.close();

- You can't write DIV's in Netscape. It uses LAYERS. But you can convert DIV's in LAYER's if you write them like this, for example:

<DIV style="position: absolute; left: X px; right: Y px">

NOTE: DIV's are converted to LAYER's (and usable for IE and NS) where they are in absolute position. You have to assing them (X,Y) coordinates in document.
rabanero gives and interesting ansewer that I'm gonna really have try out!

My two cents worth:
this is the fairly simple branching as the document writes, but works every time.  I don't write the tables at the same time though, just write to the DIV/LAYER after creating it.  Then I use a generic writeDHTML fucntion to write to the appropriate layer

GENERIC WRITE CODE------
function writeDHTML(writeText, divTag) {
          if (document.getElementById) {
               document.getElementById(divTag).innerHTML = writeText;
          } else if (document.all) {
               ie4Write = "document.all." + divTag + ".innerHTML = writeText";
               eval(ie4Write);
          } else if (document.layers) {
               var nnWrite = "document." + divTag + "N1.document." + divTag + "N2.document.write(writeText);"
               var nnClose = "document." + divTag + "N1.document." + divTag + "N2.document.close();"
               eval(nnWrite);
               eval(nnClose);
          }
}

BRANCHING AS DOC WRITES---------
      <script language="Javascript"><!--
     if ((document.getElementById) || (document.all)) {
          document.write("<div id=\"biccycrumbs\"></div>");
     } else if (document.layers) {
          document.write("<ilayer id=\"biccycrumbsN1\" width=\"640\" height=\"20\"><layer id=\"biccycrumbsN2\" width=\"640\" height=\"20\"></layer></ilayer>");
     }
//--></script>

CALLING IT---------------
writeDHTML(variablewithwritecode, 'strDivTagName'

Hope it helps,  can give examples of code in action if necessary

eilLOC




I'll reply to rabanero -- I want to do document.writes from the HEAD section of the document, then have other content in the BODY section, so I don't want to close the document following my writes, I want the document to continue loading as normal. My DIVs are indeed absolutely positioned.

eiLOC, My intention with the branching is to make the code as small as possible, so what I was intending to do was like this:

1) Browser detection
2) If the browser can do DHTML, write a SCRIPT SRC tag which would load the arrays containing the code for the DIVs
3) Branch at that point, writing another SCRIPT SRC tag which would write the arrays from item 2 in different ways for the different browsers.

That way I only load the DIVs (they're quite big) if the browser can handle them, and I only load browser-specific code at point 3, not multi-browser branching code.

Am I being too ambitious? Basically size is important in this implementation. I'm choosing to sacrifice some simplicity if I can make savings in size.
Hey, why can't I exceed 300 points for a question?

I'd happily give you more!
Hi johnny99,

Give me a a couple of hours to think about it...
Without knowing the actual specifics of what you are trying to do, here's what I think, hope its helpful

1 Branching the Code
------------------

Can either use full detection or psuedo detection

Full detection-
http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html
(view it using netscape or they won't let you see it!)

Psuedo
Use the following
//Browser Sniff
if (document.getElementById) {
      var dom = true;
} else if (document.all) {
      var ie4ish = true;      
} else if (document.layers) {
      var nn4ish = true;
} else {
      alert("Sorry, your browser may not support the\nJavascript on this page.\n\nPlease visit out \'plug-ins\' page to\nobtain a newer browser");
}


2 If browser supports write script code
-------------------------------------
Remember and split up your script statement when writing Javascript dynamically, i.e.

document.write("<scr" + "ipt src=\"myfolder/myfilename.js\"></scr" + "ipt>");

3 Branch and write Arrays for different browsers
------------------------------------------------
Don't forget that the Div Tags and Layer tags are just empty holders that can be written to with what ever you want.  There are some restrictions in size to what you can write but you can only find out the true limits by testing.

You will have to write your div/layer tags inline with Javascript or you are getting into a whole load more compatibility issues.

What you want to do, is write the div tags as the page loads (using the  browser detection to do it) them pass the relevant Array to it after the page has loaded.  IMHO this is the best way to do it.

Here is some rough code (it'll need a bit of tweaking to do what you are saying...

<HTML><HEAD>
<script language="Javascript"><!--
if (document.getElementById) {
      var dom = true;
} else if (document.all) {
      var ie4ish = true;      
} else if (document.layers) {
      var nn4ish = true;
} else {
      alert("Sorry, your browser may not support the\nJavascript on this page.\n\nPlease visit out \'plug-ins\' page to\nobtain a newer browser");
}

if (dom) {
      document.write("<scr" + "ipt src=\"myfolder/domArrays.js\"></scr" + "ipt>");
} else if (ie4ish) {
      document.write("<scr" + "ipt src=\"myfolder/ie4Arrays.js\"></scr" + "ipt>");
} else if (nn4ish) {
      document.write("<scr" + "ipt src=\"myfolder/nn4filename.js\"></scr" + "ipt>");
} else {
      //some code
}

function writeDHTML(writeText, divTag) {
         if (document.getElementById) {
              document.getElementById(divTag).innerHTML = writeText;
         } else if (document.all) {
              ie4Write = "document.all." + divTag + ".innerHTML = writeText";
              eval(ie4Write);
         } else if (document.layers) {
              var nnWrite = "document." + divTag + "N1.document." + divTag + "N2.document.write(writeText);"
              var nnClose = "document." + divTag + "N1.document." + divTag + "N2.document.close();"
              eval(nnWrite);
              eval(nnClose);
         }
}

function writeToDivTags() {
      //Code that will use the relevant array info and pass to Div Tags
      //This function could be contained in each browser specific external JS file
      //As long as you give the kickstart function the same name in all files
      //It can acontain any code

      var array1 = stuffToDo();
      var array2 = stuffToDo2();

      writeDHTML(array1,'Array1');
      writeDHTML(array2,'Array2');
}

//--></script>
</head>
<body onLoad="writeToDivTags()">

<script language="Javascript"><!--
    if ((document.getElementById) || (document.all)) {
         document.write("<div id=\"Array1\"></div>");
    } else if (document.layers) {
         document.write("<ilayer id=\"Array1N1\" width=\"640\" height=\"20\"><layer id=\"Array1N2\"
width=\"640\" height=\"20\"></layer></ilayer>");
    }
//--></script>

<script language="Javascript"><!--
    if ((document.getElementById) || (document.all)) {
         document.write("<div id=\"Array2\"></div>");
    } else if (document.layers) {
         document.write("<ilayer id=\"Array2N1\" width=\"whatever\" height=\"whatever\"><layer id=\"Array2N2\"
width=\"whatever\" height=\"whatever\"></layer></ilayer>");
    }
//--></script>


</body>
</html>

Points of note
Netscape's a PITA
If it is loads of information, branch the pages out in terms of Netscape version and IE version (means have to do tow pages instead of one)
Netscape requires that it's Ilayer and layer tag gets the height and width that it is going to use- don't leave them blank

Hope it helps
ASKER CERTIFIED SOLUTION
Avatar of eilloc
eilloc

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Here are the points, though I haven't quite got all my bugs worked out, because you set me straight on a lot of things I was thinking about all wrong!