How to view results of document.write()?

E

Eli

I've got a script that I'm trying to debug which uses document.write()
to place HTML within a page. In both IE6 and Firefox when I view
source, I see only the script itself and not any HTML as it's being
written into the page.

Is there a way that I can view what is being placed into the page,
instead of, or in addition to the javascript code?
 
H

Hal Rosser

Eli said:
I've got a script that I'm trying to debug which uses document.write()
to place HTML within a page. In both IE6 and Firefox when I view
source, I see only the script itself and not any HTML as it's being
written into the page.

Is there a way that I can view what is being placed into the page,
instead of, or in addition to the javascript code?

call up the page in the browser.
that is what it writes.
 
R

Randy Webb

Hal said:
call up the page in the browser.
that is what it writes.

Do you ever actually test what you answer?

To the OP:
The simplest way is to add a textarea to the page, instead of
document.write (or in addition to), set the textarea's value to your
variable.
 
E

Eli

Do you ever actually test what you answer?

To the OP:
The simplest way is to add a textarea to the page, instead of
document.write (or in addition to), set the textarea's value to your
variable.

Thank you. As it stands the code doesn't do a single document.write()
of a variable, but numerous writes in conditionals, loops, etc.

I suppose it could be rewritten as such, however, if this is the best
way.
 
R

Randy Webb

Eli said:
Thank you. As it stands the code doesn't do a single document.write()
of a variable, but numerous writes in conditionals, loops, etc.

I suppose it could be rewritten as such, however, if this is the best
way.

It is always best to make a single string and then do one document.write
than doing multiple document.write's
 
M

Michael Winter

On Wed, 10 Nov 2004 01:17:38 -0500, Randy Webb
[snip]
The simplest way is to add a textarea to the page, instead of
document.write (or in addition to), set the textarea's value to your
variable.

Thank you. As it stands the code doesn't do a single document.write()
of a variable, but numerous writes in conditionals, loops, etc.

I suppose it could be rewritten as such, however, if this is the best
way.

If it's too much trouble to change your code, then change what the write
method does. :)

document.write = (function() {
/* Perform a one-time initialisation of the overriding
* function.
*
* This will hold the property name for the original
* write method so it can be called later.
*/
var old = '__write',
/* When this method is called, it is possible that the
* textarea used to hold the output has not been encountered
* yet, so it can not be addressed through the DOM. Until
* it is accessible, output is stored in the variable below.
*/
tmp = '',
/* This is the id of the textarea where output should
* be directed. Change it as you see fit.
*/
output = 'textarea-id',
/* This is text that should be appended to any text sent to
* the output textarea. You might just want to leave it as-is
* (a new line), but change this too if you want. Note that
* it won't affect what is actually written to the document.
*/
suffix = '\n',
/* Similar to the above, but prepended to the text. */
prefix = '';

/* Search for an identifier that is not currently used
* where the original function can be stored.
*/
while('undefined' != typeof document[old]) {old += '__';}
/* Once found, add a reference to the original method. */
document[old] = document.write;

/* Now that the initialisation is complete, the function
* below overrides the original method.
*/
return function(str) {
/* Attempt to get a reference to the debugging
* textarea element.
*/
var o = document.getElementById(output);
/* Store the text in case the call above fails. */
tmp += prefix + str + suffix;
/* Write the text using the original method. */
document[old](str);

/* If the textarea could be found, we can begin preparations
* to use it in every call after this point. As we won't need
* to store the text any more, we can prevent that code from
* being called by substituting yet another function.
*/
if(output) {
/* Send the stored text to the textarea. If you want to use
* the textarea for other things, you might want to change
* this line from an assignment (=) to a concatenation (+=).
*/
output.value = tmp;
/* As we may have built up a lot of text,
* let's free some memory.
*/
tmp = null;
/* From now on, this whole process can be streamlined.
* As we now have access to the textarea element, text
* can be added to it directly.
*/
return function(str) {
output.value += prefix + str + suffix;
document[old](str);
}
}
};
})();

You'll probably have to change the string, output, and possibly the prefix
and suffix strings. Copy this code into a SCRIPT element in the HEAD
section of the document, and call document.write as normal. Depending
where your document.write calls are in respect to the debugging TEXTAREA
element, you may need to add a call at the end of your page - even just
document.write('') - to flush the buffer.

If you use the writeln method, too, you can pretty much copy the above,
changing "write" to "writeln" where needed. The code is actually quite
compact - it's just the comments that make it so imposing.

Good luck,
Mike
 
G

Grant Wagner

Eli said:
Thank you. As it stands the code doesn't do a single document.write()
of a variable, but numerous writes in conditionals, loops, etc.

I suppose it could be rewritten as such, however, if this is the best
way.

This doesn't work all that well, but it will show you the dynamic content (as
well as the script:

<button
onclick="window.open('javascript:eek:pener.document.documentElement.innerHTML.replace(/</g,
\'&\' + \'lt;\');');">View Dynamic Source</button>

Others can probably improve on this, but it's probably best to design your
script to output known HTML, rather than guessing and using some hack like
the above to try to make sure it's right.
 
M

Matt Kruse

Eli said:
Is there a way that I can view what is being placed into the page,
instead of, or in addition to the javascript code?

I use the code below in my IE context menu. You could easily turn it into a
bookmarklet if you wanted to. It shows me the source exactly as IE sees it,
which is what I usually need:

var srcwin =
window.open('about:blank','src','width=1200,height=900,top=0,left=0');
srcwin.document.open();
srcwin.document.writeln('<html><body><form><table width=100%
height=100%><tr><td><textarea name="src" id="src"
style="width:100%;height:100%;"
wrap="off"></textarea></td></tr></table></form></body></html>');
srcwin.document.close();
srcwin.document.forms[0].src.value =
doc.getElementsByTagName('html').item(0).outerHTML;
 
R

RobB

Grant Wagner said:
This doesn't work all that well, but it will show you the dynamic content (as
well as the script:

<button
onclick="window.open('javascript:eek:pener.document.documentElement.innerHTML.replace(/</g,
\'&\' + \'lt;\');');">View Dynamic Source</button>

Others can probably improve on this, but it's probably best to design your
script to output known HTML, rather than guessing and using some hack like
the above to try to make sure it's right.

You might try something like this:

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>untitled</title>
<script type="text/javascript">
//<![CDATA[

var ptwin = null,
r = null,
gstr = '';

function plaintextwin()
{
if (null != r)
clearTimeout(r);
if (ptwin && !ptwin.closed)
ptwin.close();
var str = '';
for (var a = 0; a < arguments.length; ++a)
str += arguments[a].concat('\n');
gstr = gstr.concat(str.replace(/(<[^/])/g, '\n$1').concat('\n'));
ptwin = open('about:blank', 'ptwin',
'width=100,height=100,left=20,top=50,scrollbars,resizable');
ptwin.document.open('text/plain');
ptwin.document.write(gstr);
ptwin.document.close();
ptwin.focus();
r = setTimeout('ptwin.resizeTo(' + (screen.width * .95) + ',' +
(screen.height * .66) + ')',100);
}

document.write = plaintextwin;

s = '<span class="foo">hah</span><h4>Hello, World !</h4><br />';
document.write(s);
document.write('<div class=vs6>&nbsp;</div><a
href="http://ftp.netscape.com/pub/netscape7/english/7.2/mac/Netscape-MachO.dmg.gz">Mac
OS X</a>');
document.write("I've got a script that I'm trying to debug which uses
document.write() to place HTML within a page.");
document.write('.vbmenu_hilite a:hover, .vbmenu_hilite a:active
{color: #FFFFFF; text-decoration: none;}');
document.write('alpha' , 'beta' , 'gamma');

//]]>
</script>
</head>
<body>
</body>
</html>

Works in IE, which allows a mimetype as an argument to
document.open(). Buggy in Firefox, no time to find out why. Should
allow you to at least see what's printing. I disagree about the 'one
big string' approach - document.write/ln take multiple arguments,
comma-separated as usual, an efficient way to avoid repeated
invocations.
 
R

Robert

Eli said:
Is there a way that I can view what is being placed into the page,
instead of, or in addition to the javascript code?

There are a number of one line Javascript programs you can use that
have appeared in this forum that will display the generated html. Use
the search term one liner against this forum.

What you do is take one of these one liners and place it as a bookmark
in your browser. One way of creating the bookmark is to take a
bookmark and change it to the one liner by editing bookmarks.

The following one-liner when pasted into the command line will
display the generated html. (It looks for line ends which are OS
dependent.):

javascript:'<html><head><title>SourceFileListing<\/title><\/head><body><code><ol><li>'+(document.documentElement||document.body).innerHTML.replace(/&/g,%22&amp;%22).replace(/</g,%22&lt;%22).replace(/%20%20/g,%22&nbsp;%20%22).replace(/\r\n/g,%22<li>%22).replace(/\n/g,%22<li>%22).replace(/\r/g,%22<li>%22)+'<\/ol><\/code><\/body><\/html>';


Robert
 
M

Michael Winter

On Wed, 10 Nov 2004 14:19:06 GMT, Michael Winter

[snipped script]

Damn it! I posted the wrong script.

document.write = (function() {
/* Perform a one-time initialisation of the overriding
* function.
*
* This will hold the property name for the original
* write method so it can be called later.
*/
var old = '__write',
/* When this method is called, it is possible that the
* textarea used to hold the output has not been encountered
* yet, so it can not be addressed through the DOM. Until
* it is accessible, output is stored in the variable below.
*/
tmp = '',
/* This is the id of the textarea where output should
* be directed. Change it as you see fit.
*/
output = 'textarea-id',
/* This is text that should be appended to any text sent to
* the output textarea. You might just want to leave it as-is
* (a new line), but change this too if you want. Note that
* it won't affect what is actually written to the document.
*/
suffix = '\n',
/* Similar to the above, but prepended to the text. */
prefix = '';

/* Search for an identifier that is not currently used
* where the original function can be stored.
*/
while('undefined' != typeof document[old]) {old += '__';}
/* Once found, add a reference to the original method. */
document[old] = document.write;

/* Now that the initialisation is complete, the function
* below overrides the original method.
*/
function func(str) {
/* Attempt to get a reference to the debugging
* textarea element.
*/
var o = document.getElementById(output);
/* Store the text in case the call above fails. */
tmp += prefix + str + suffix;
/* Write the text using the original method. */
document[old](str);

/* If the textarea could be found, we can begin preparations
* to use it in every call after this point. As we won't need
* to store the text any more, we can prevent that code from
* being called by substituting yet another function.
*/
if(o) {
/* Send the stored text to the textarea. If you want to use
* the textarea for other things, you might want to change
* this line from an assignment (=) to a concatenation (+=).
*/
o.value = tmp;
/* As we may have built up a lot of text,
* let's free some memory.
*/
tmp = null;
/* From now on, this whole process can be streamlined.
* As we now have access to the textarea element, text
* can be added to it directly.
*/
func = function(str) {
o.value += prefix + str + suffix;
document[old](str);
}
}
}
return function(s) {func(s);};
})();

Mike
 
J

Jim Ley

On Wed, 10 Nov 2004 14:19:06 GMT, Michael Winter

[snipped script]

Damn it! I posted the wrong script.

document.write = (function() {

This causes an error on Win 2000 fully patched IE5.5's so it might be
worth avoiding!

Jim.
 
M

Michael Winter

On Thu, 11 Nov 2004 18:52:45 GMT, "Michael Winter"
[snip]
document.write = (function() {

This causes an error on Win 2000 fully patched IE5.5's so it might be
worth avoiding!

Is that because it doesn't like a script overriding a host method, or
can't it handle that pattern? I don't have IE 5.5 to test and there are no
problems with IE6/XP.

Anyway, it was only a debugging suggestion, not production code. Thanks
for mentioning it in any event.

Mike
 
J

Jim Ley

On Thu, 11 Nov 2004 18:52:45 GMT, "Michael Winter"
[snip]
document.write = (function() {

This causes an error on Win 2000 fully patched IE5.5's so it might be
worth avoiding!

Is that because it doesn't like a script overriding a host method, or
can't it handle that pattern? I don't have IE 5.5 to test and there are no
problems with IE6/XP.

It's just document.write and writeln - I assume it's a bug, took out
an intranet of mine, hopefully another patch will fix it. it seemed
IE 5.5sp2 and win2000 specific, although didn't test than many other
5.5's

Jim.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,439
Members
44,829
Latest member
PIXThurman

Latest Threads

Top