setPage is not defined error in Mozilla/Firefox

J

Johan

Hi,

I've been working on the following piece of code and it works fine in IE
and Opera, dut keep getting the same error in Firefox. Can anyone tell
me what's wrong with this code? What I'm trying to do is rewrite the
left (navigationframe) and load a page on the right (mainframe).

tia,
Johan

Here's a piece of the code:

function setHome(pageCode) {
with (document) {
open();
write('<?xml version="1.0" encoding="iso-8859-1"?>\n<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n');
write('\n<html xmlns="http://www.w3.org/1999/xhtml">\n\n');
write('<head>\n<link rel="stylesheet" type="text/css"
href="./nav.css" />\n<script src="./nav.js" type="text/javascript"
language="JavaScript">\n</script>\n</head>\n\n');
write('<body>\n');
write('<div id="navigation">\n');
write('<table>\n');
write('<tr>\n<td><a href="#" onclick="setHome(\'./homemain.html\')"
class="current">Home</a></td>\n</tr>');
write('<tr>\n<td><a href="#"
onclick="setSoftware(\'./software.html\')">Software</a></td>\n</tr>');
write('<tr>\n<td><a href="#"
onclick="setLinks(\'linksmain.html\')">Links</a></td>\n</tr>');
write('<tr>\n<td><a href="#"
onclick="setInfo(\'./informatie.html\')">Informatie</a></td>\n</tr>');
write('</table>');
write('</div>');
write('</body>');
write('</html>');
close();
setPage(pageCode);
}
}

....

function setPage(url) {
parent.mainframe.location.href = url.toString();
}
 
M

Michael Winter

I've been working on the following piece of code and it works fine in IE
and Opera, dut keep getting the same error in Firefox. Can anyone tell
me what's wrong with this code? What I'm trying to do is rewrite the
left (navigationframe) and load a page on the right (mainframe).

[snipped code]

Could you provide a URL? I don't see anything wrong (though I might have
missed something). A working example would make it much easier to see the
problem.

I would like to mention a few points before I finish:

- You should make sure you escape "</" sequences into "<\/". This is
because browsers are allowed to treat "</" as the end of the SCRIPT
element.
- The TITLE element is required in a HTML document. Even if you leave it
empty[1],

<title></title>

always include it.
- You can use the writeln method to end a written line with a new-line
character.
- The language attribute in a SCRIPT element has been deprecated in favour
of the (required) type attribute. You needn't use the former any more.
- As the content you're writing into the frame is static, why not load a
HTML file instead?

Mike



[1] There's no real reason to leave it empty. You'll always have some form
of label for a page.
 
L

Lasse Reichstein Nielsen

max power said:
I'm no real JS guru, but if it's like other languages, then you have to
define functions *before* you can call/use them.

It is defined before it is used. Both functions are defined at the
same scope level, and therefore at almost the same time, long before
the code in that scope is executed.
Your code calls setPage() inside the setHome() function, but
setPage() is not defined until later in the code

The position in the code is not important. The use has to be later (in
time) than the declaration, but not after in the code.
- I'm surprised it works in any browser.

I think the problem is a string literal that spans several
lines. That's not valid Javascript. A string literal may not
contain newlines (but can contain the escape sequence "\n" which
will cause the resulting string value to contain a newline).

/L
 
J

Johan

max said:
I'm no real JS guru, but if it's like other languages, then you have to
define functions *before* you can call/use them. Your code calls
setPage() inside the setHome() function, but setPage() is not defined
until later in the code - I'm surprised it works in any browser.
Thanks for your reply. I 've tried what you're suggesting, but it didn't
change a thing.
Johan
 
J

Johan

Lasse said:
It is defined before it is used. Both functions are defined at the
same scope level, and therefore at almost the same time, long before
the code in that scope is executed.




The position in the code is not important. The use has to be later (in
time) than the declaration, but not after in the code.




I think the problem is a string literal that spans several
lines. That's not valid Javascript. A string literal may not
contain newlines (but can contain the escape sequence "\n" which
will cause the resulting string value to contain a newline).

/L
Thanks for your reply. As far as I can see I'm doing what you're
suggesting. I don't see where the newlines are, because every write
starts on a newline and spans just one line.
Johan
 
J

Johan

Michael said:
I've been working on the following piece of code and it works fine in
IE and Opera, dut keep getting the same error in Firefox. Can anyone
tell me what's wrong with this code? What I'm trying to do is rewrite
the left (navigationframe) and load a page on the right (mainframe).


[snipped code]

Could you provide a URL? I don't see anything wrong (though I might
have missed something). A working example would make it much easier to
see the problem.

I would like to mention a few points before I finish:

- You should make sure you escape "</" sequences into "<\/". This is
because browsers are allowed to treat "</" as the end of the SCRIPT
element.
- The TITLE element is required in a HTML document. Even if you leave
it empty[1],

<title></title>

always include it.
- You can use the writeln method to end a written line with a new-line
character.
- The language attribute in a SCRIPT element has been deprecated in
favour of the (required) type attribute. You needn't use the former any
more.
- As the content you're writing into the frame is static, why not load
a HTML file instead?

Mike



[1] There's no real reason to leave it empty. You'll always have some
form of label for a page.
Thanks for your reply. I changed the </ into <\/ and removed the
language bit, added a title and changed write into writeln and removed
the \n bits. This didn't solve it :(

I'm not using different html files because I would be changing to many
filis if I add or remove an menuitem. This way I'm only working on one
file. I will be changing the code into something more OO but for now
it's ok if it just would work.

I don't have a link to the code btw, sorry. The rest of the code is
build the same as the first part (as the setHome part). It is used to
show or hide several menuitems. There're no other functions in the file
(it is an .js file)

Here's the changed code, maybe it becomes more clear whats wrong(?):

function setPage(url) {
parent.mainframe.location.href = url.toString();
}

function setHome(pageCode) {
with (document) {
open();
writeln('<?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">');
writeln('<html xmlns="http://www.w3.org/1999/xhtml">');
writeln('<head><link rel="stylesheet" type="text/css"
href="./nav.css" /><title>Belois Automatisering -
Software<\/title><script src="./nav.js"
type="text/javascript"><\/script><\/head>');
writeln('<body>');
writeln('<div id="navigation">');
writeln('<table>');
writeln('<tr><td><a href="#" onclick="setHome(\'./homemain.html\')"
class="current">Home<\/a><\/td><\/tr>');
writeln('<tr><td><a href="#"
onclick="setSoftware(\'./software.html\')">Software<\/a><\/td><\/tr>');
writeln('<tr><td><a href="#"
onclick="setLinks(\'linksmain.html\')">Links<\/a><\/td><\/tr>');
writeln('<tr><td><a href="#"
onclick="setInfo(\'./informatie.html\')">Informatie<\/a><\/td><\/tr>');
writeln('<\/table>');
writeln('<\/div>');
writeln('<\/body>');
writeln('<\/html>');
close();
setPage(pageCode);
}
}
....
 
J

Johan

Andrew said:
So, let me guess.. That's a 'Fluffy_kittens
not defined error' perhaps? In that case,
change line 43, char 19 from a '.' to a ';'.

No good?

Filing that it might be more productive
to state *specifically* what error you
are getting.
As it says in the subject "setPage is not defined". It is shown in the
Javascript console.
Aaahh yes. 'a piece of the code'..

If it it is broken, and you do not know
how to fix it, what makes you think it
is this part of the code that is broken?

<http://www.physci.org/codes/sscce.jsp>
The rest of the code is build the same way.
 
L

Lasse Reichstein Nielsen

Johan said:
Thanks for your reply. As far as I can see I'm doing what you're
suggesting. I don't see where the newlines are, because every write
starts on a newline and spans just one line.

I cut this from another reply:
---
writeln('<tr><td><a href="#"
onclick="setSoftware(\'./software.html\')">Software<\/a><\/td><\/tr>');
---
The way "onclick" is indented suggests that it is on another line,
and it's not just your news-client that has broken the line.

I can't be sure ofcourse. Some news-clients always breaks long lines
(both at the posting and the reading end), and they aren't consistent
about how they do it, which is why program code posted here should not
be too long (72 characters works well).

What you posted does have incorrect newlines inside the string
literal. That bug, if it is in the original, would give the symptoms
you are experiencing.

/L
 
G

Grant Wagner

Johan said:
Hi,

I've been working on the following piece of code and it works fine in IE
and Opera, dut keep getting the same error in Firefox. Can anyone tell
me what's wrong with this code? What I'm trying to do is rewrite the
left (navigationframe) and load a page on the right (mainframe).

tia,
Johan

Here's a piece of the code:

function setHome(pageCode) {
with (document) {
open();
write('<?xml version="1.0" encoding="iso-8859-1"?>\n<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n');
write('\n<html xmlns="http://www.w3.org/1999/xhtml">\n\n');
write('<head>\n<link rel="stylesheet" type="text/css"
href="./nav.css" />\n<script src="./nav.js" type="text/javascript"
language="JavaScript">\n</script>\n</head>\n\n');
write('<body>\n');
write('<div id="navigation">\n');
write('<table>\n');
write('<tr>\n<td><a href="#" onclick="setHome(\'./homemain.html\')"
class="current">Home</a></td>\n</tr>');
write('<tr>\n<td><a href="#"
onclick="setSoftware(\'./software.html\')">Software</a></td>\n</tr>');
write('<tr>\n<td><a href="#"
onclick="setLinks(\'linksmain.html\')">Links</a></td>\n</tr>');
write('<tr>\n<td><a href="#"
onclick="setInfo(\'./informatie.html\')">Informatie</a></td>\n</tr>');
write('</table>');
write('</div>');
write('</body>');
write('</html>');
close();
setPage(pageCode);
}
}

...

function setPage(url) {
parent.mainframe.location.href = url.toString();
}

I could be wrong, but I think everyone missed the obvious here. The function
setHome() does document.write(). The moment the code issues document.open();
document.write(...); the content of the current document (including the
function setPage()) is destroyed.

By the time Firefox gets to the call "setPage(pageCode);", that function no
longer exists.

It's generally not a good idea to document.write() into the current document
after it has been closed by "</body></html>".
 
L

Lasse Reichstein Nielsen

Grant Wagner said:
I could be wrong, but I think everyone missed the obvious here. The function
setHome() does document.write(). The moment the code issues document.open();
document.write(...); the content of the current document (including the
function setPage()) is destroyed.

I think you are wrong (but I could be too :). As long as the Javascript
is executing, its execution context remains in existence. That means that
even after writing the document, even if the new document was put into
a fresh window object, the original code can still see its own variables.

A simple test would be:
---
<script type="text/javascript">
function foo() {alert("I exist");}
document.open();
document.write("<html><head><title>test</title></head><body>hello");
document.write("</body></html>");
document.close();
foo();
setTimeout(foo, 2000);
</script>
 
G

Grant Wagner

Lasse said:
I think you are wrong (but I could be too :). As long as the Javascript
is executing, its execution context remains in existence. That means that
even after writing the document, even if the new document was put into
a fresh window object, the original code can still see its own variables.

A simple test would be:
---
<script type="text/javascript">
function foo() {alert("I exist");}
document.open();
document.write("<html><head><title>test</title></head><body>hello");
document.write("</body></html>");
document.close();
foo();
setTimeout(foo, 2000);
</script>

Perhaps you are correct. I was under the impression the OP was calling setHome()
after the page had been closed:

<body>
<a href="#" onclick="setHome(someUrl);return false;">Reload menu</a>
<!-- ... -->
</body>

Rather than being called while the page was still being processed:

<body>
<script type="text/javascript">
setHome(someUrl);
</script>
<!-- ... -->
</body>

I just read and re-read the original post and I'm not sure you can make a
convincing argument either way. We'll have to wait for the OP to tell us how he
was invoking setHome(). However, given the behaviour he is seeing, I would not be
surprised to discover he is trying to use setHome() after the document has been
closed.
 
L

Lasse Reichstein Nielsen

Grant Wagner said:
Perhaps you are correct. I was under the impression the OP was
calling setHome() after the page had been closed:

Yes, not a very good example I made, doing a document.open() while
it is already open :)

The real page initiates the writing with a document.open(), so the
existing page will be cleared. My guess was that it might not be
completely forgotten as long as there are scripts referring to it.
<body>
<a href="#" onclick="setHome(someUrl);return false;">Reload menu</a>
<!-- ... -->
</body>

Let's try the test with this change:
---
<html><head><title>Test</title></head><body>
<script type="text/javascript">
function foo() {alert("I exist");}
function doit() {
document.open();
document.write("<html><head><title>test</title></head><body>hello");
document.write("</body></html>");
document.close();
setTimeout(function(){alert(typeof foo);foo();}, 2000);
alert(typeof foo);
foo();
}
</script>
<p><input type="button" onclick="doit()" value="do it!"></p>
</body></html>
---

Now:
- Opera makes all four alerts and says the type is "function" both times.
- IE only makes the first two alerts, saying "function". The timeout is
completely lost.
- Mozilla FF makes two alerts saying "undefined", so "foo" is gone.

So, you do seem to be right for Mozilla.

/L
 
J

Johan

Lasse said:
I cut this from another reply:
---
writeln('<tr><td><a href="#"
onclick="setSoftware(\'./software.html\')">Software<\/a><\/td><\/tr>');
---
The way "onclick" is indented suggests that it is on another line,
and it's not just your news-client that has broken the line.

I can't be sure ofcourse. Some news-clients always breaks long lines
(both at the posting and the reading end), and they aren't consistent
about how they do it, which is why program code posted here should not
be too long (72 characters works well).

What you posted does have incorrect newlines inside the string
literal. That bug, if it is in the original, would give the symptoms
you are experiencing.

/L
Thanks again for replying. As far as I can see this is not the problem.
Every writeln is on one line. You're right about the news-client, it is
cutting up the lines. I don't see any other newlines (besides the
writeln) in my code (or am I wrong).

Johan
 
J

Johan

Lasse said:
Yes, not a very good example I made, doing a document.open() while
it is already open :)

The real page initiates the writing with a document.open(), so the
existing page will be cleared. My guess was that it might not be
completely forgotten as long as there are scripts referring to it.




Let's try the test with this change:
---
<html><head><title>Test</title></head><body>
<script type="text/javascript">
function foo() {alert("I exist");}
function doit() {
document.open();
document.write("<html><head><title>test</title></head><body>hello");
document.write("</body></html>");
document.close();
setTimeout(function(){alert(typeof foo);foo();}, 2000);
alert(typeof foo);
foo();
}
</script>
<p><input type="button" onclick="doit()" value="do it!"></p>
</body></html>
---

Now:
- Opera makes all four alerts and says the type is "function" both times.
- IE only makes the first two alerts, saying "function". The timeout is
completely lost.
- Mozilla FF makes two alerts saying "undefined", so "foo" is gone.

So, you do seem to be right for Mozilla.

/L
Thanks for thinking with me guys. I looked at the code and I don't see
how I can change it to make it work the way you suggest. Maybe it will
help if I also add the code of the originating navigation page? here's
the code:

<?xml version="1.0" encoding="UTF-8"?>
<!doctype html public "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml-1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<link rel="stylesheet" type="text/css" href="nav.css"/>
<title>Belois Automatisering</title>
<script src="./nav.js" type="text/javascript">
</script>
</head>

<body>
<script type="text/javascript">
setHome('homemain.html');</script>
</body>
</html>

When I look at the source in IE I see the code from the .js file, with
mozilla I see the code above and I get the javascript error mentioned
earlier. Considering no one can find a error (for now) in the earlier
posted code, maybe the error is in this page.
Johan
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top