error: object required when declaring variable

F

fred

I don't know if I'm doing this correctly. I have a little programming
experience in python, c++ and some others but this is my first time with
javascript. I'm trying have my website detect the user's browser and
assign a variable with different items if it's Internet Explorer. My
code works with firefox, opera and others but not IE.

<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Untitled Document</title>

<script language="JavaScript" type="text/javascript"><!--
browser_version= parseInt(navigator.appVersion);
browser_type = navigator.appName;
//var sizex,sizey
if (browser_type == "Microsoft Internet Explorer") {
sizex=document.body.clientWidth
sizey=document.body.clientHeight;
}
else {
sizex=window.outerWidth-window.innerWidth
sizey=window.outerHeight-window.innerHeight;
}
alert ("width = " + sizex + "height = " + sizey)
// -->
</script>
</head>

There it is, I get the error on:(line 10)sizex=document.body.clientWidth

Thanks for any help.

FF
 
R

Richard Cornford

fred said:
I don't know if I'm doing this correctly. I have a little
programming experience in python, c++ and some others but
this is my first time with javascript. I'm trying have
my website detect the user's browser

Don't ever try to detect the user's browsers. If you want to match
script behaviour with the DOM of the environment in which it is
executing use feature detection instead (see the FAQ, particularly <URL:
http://jibbering.com/faq/#FAQ4_26 > and related links).
and assign a variable with different items if it's Internet
Explorer. My code works with firefox, opera and others but
not IE.

It only works in Opera and Firefox as you have them configured (and
given a fairly vague definition of "works").
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1"> <title>Untitled Document</title>

<script language="JavaScript" type="text/javascript"><!--
^^^^^^^^ ^^^^
The language attribute is deprecated and rendered redundant by the use
of the required type attribute.

HTML style comments are not needed inside script elements and should be
omitted/avoided. (You don't by any chance have a really out of date book
on browser scripting?)
browser_version= parseInt(navigator.appVersion);
browser_type = navigator.appName;
//var sizex,sizey

If you are going to use global variables in javascript it is best
practice to explicitly declare them globally.
if (browser_type == "Microsoft Internet Explorer") {
sizex=document.body.clientWidth
sizey=document.body.clientHeight;

The conditions in which any given browser will return "Microsoft
Internet Explorer" from the - navigator.appName - property are unrelated
to the type of browser in use, and it don't relate to the
appropriateness of reading the - document.body.clientHeight - to acquire
any form of dimensions, even when the browser is IE. (See:- <URL:
http://jibbering.com/faq/#FAQ4_9 > and recent newsgroup threads related
to the subject)
}
else {
sizex=window.outerWidth-window.innerWidth
sizey=window.outerHeight-window.innerHeight;

In principle the difference between outerWidth and innerWidth would be
the width of the window's chrome (totalled left and right) and very
different information from anything that could be acquired through
clientWidth.
}
alert ("width = " + sizex + "height = " + sizey)
// -->
</script>
</head>

There it is, I get the error on:(line
10)sizex=document.body.clientWidth
^^^^^^^^^^^^^
The document.body property is not populated until the BODY element is
created (at the soonest) and the BODY element cannot be created until
the HTML parser sees (or implies) the opening body tag. Script executed
inline within the HEAD will have finished prior to the browser
encountering the opening BODY tag in the HTML source.

Richard.
 
F

Fred Oz

What Richard said. Here is a viewport tester that tells you what
properties work for a the user agent it is loaded into.

This has been posted before, but I've done a little extra work and
think this is a better version.

Have fun, Fred.

<html><head>
<title>Viewport Tester</title>
<meta name="author" content="Various">
<meta name="keywords" content="">
<meta name="description" content="
This page was orignally from:

http://www.quirksmode.org/viewport/compatibility.html

and has been modified for a table layout that can be
copied and pasted from different browsers to more easily
compile a browser compatability matrix.

It also report user agent (UA) and platform, however
these are not reliable because some UA's allow the user
to sepcify what will reported, regardless of the actual UA
or platform.">

<style type="text/css">
td,th
{font-size: 14px; padding-right: 5; padding-left: 10;
border-bottom: 1px solid #999999;}
..pass
{font-size: 14px; background-color: green;
font-weight: bold; text-align: center; color: gold;}
..fail
{font-size: 14px; background-color: red;
font-weight: bold; text-align: center; color: darkblue;}
..Yes
{font-size: 14px; background-color: green;
font-weight: bold; text-align: center; color: gold;}
..No
{font-size: 14px; background-color: red;
font-weight: bold; text-align: center; color: darkblue;}
..count
{font-size: 14px; text-align: right; font-weight: bold;
padding-right: 10; padding-left: 10;}
p
{font-family: sans-serif; size: 14px;}
</style>

<script type="text/javascript">
var x = navigator;
var props = new Array(
'self.pageXOffset',
'self.pageYOffset',
'self.screenX',
'self.screenY',
'self.innerHeight',
'self.innerWidth',
'self.outerHeight',
'self.outerWidth',
'self.screen.height',
'self.screen.width',
'self.screen.availHeight',
'self.screen.availWidth',
'self.screen.availTop',
'self.screen.availLeft',
'self.screen.Top',
'self.screen.Left',
'self.screenTop',
'self.screenLeft',
'self.screen.colorDepth',
'self.screen.pixelDepth',
'document.body.clientHeight',
'document.body.clientWidth',
'document.body.scrollHeight',
'document.body.scrollWidth',
'document.body.scrollLeft',
'document.body.scrollTop',
'document.body.offsetHeight',
'document.body.offsetWidth',
'document.body.offsetTop',
'document.body.offsetLeft'
);
function uaDetail() {
var p = '<table border=\"0"\>'
+ '<tr><th style=\"text-align: left;\">Property</th>'
+ '<th style=\"text-align: left;\">Value</th</tr>';
if (navigator) {
var x = navigator;
p += '<tr><td>CodeName</td><td>' + x.appCodeName + '&nbsp;</td></tr>'
p += '<tr><td>MinorVersion</td><td>' + x.appMinorVersion +
'&nbsp;</td></tr>'
p +='<tr><td>Name</td><td>' + x.appName + '&nbsp;</td></tr>'
p +='<tr><td>Version</td><td>' + x.appVersion + '&nbsp;</td></tr>'
p +='<tr><td>CookieEnabled</td><td>' + x.cookieEnabled +
'&nbsp;</td></tr>'
p +='<tr><td>CPUClass</td><td>' + x.cpuClass + '&nbsp;</td></tr>'
p +='<tr><td>OnLine</td><td>' + x.onLine + '&nbsp;</td></tr>'
p +='<tr><td>Platform</td><td>' + x.platform + '&nbsp;</td></tr>'
p +='<tr><td>User Agent (UA)</td><td>' + x.userAgent +
'&nbsp;</td></tr>'
p +='<tr><td>BrowserLanguage</td><td>' + x.browserLanguage +
'&nbsp;</td></tr>'
p +='<tr><td>SystemLanguage</td><td>' + x.systemLanguage +
'&nbsp;</td></tr>'
p +='<tr><td>UserLanguage</td><td>' + x.userLanguage + '&nbsp;</td></tr>'
p +='</table>'
} else {
p = 'Your user agent does not support the navigator object,'
+ '\nso I can\'t determine your viewport properties';
}
return p;
}
function viewportDetail() {
var count = 0;
var printstring = '';
var c = '';
printstring += '<table border=\"0\"><tr>'
+ '<th>#</th>'
+ '<th style=\"text-align: left;\">Property</th>'
+ '<th>Supported?<br>y/n</th>'
+ '<th>Value</th>'
+ '</tr>';
for (var i=0;i<props.length;i++) {
if (!self.screen && props.indexOf('self.screen') != -1) continue;
if (!document.body && props.indexOf('document.body') != -1)
continue;

(eval(props) || eval(props) == 0 ) ? c = 'Yes' : c = 'No';
++count;
printstring +=
'<tr><td class=\"count\">' + count
+ '</td><td>' + props
+ '</td><td class=\"' + c + '\">' + c
+ '</td><td>' + eval(props)
+ '</td></tr>';
if (props.indexOf('document.body') != -1) {
var end = props.substring(props.lastIndexOf('.')+1);
newprop = 'document.documentElement.' + end;
if (eval(newprop)) {
(eval(newprop)) ? c = 'Yes' : c = 'No';
++count;
printstring +=
'<tr><td class=\"count\">' + count
+ '</td><td>' + newprop
+ '</td><td class=\"' + c + '\">' + c
+ '</td><td>' + eval(newprop)
+ '</td></tr>';
} } }
printstring += '</table>'
return printstring;
}
function getUA() {
if (!document.getElementById) return;
document.getElementById('uaDetail').innerHTML = getUA();
}
function reGet() {
if (!document.getElementById) return;
document.getElementById('viewportDetail').innerHTML = viewportDetail();
}
</script>
</head>
<body>
<h4>Your user agent's properties<sup><a href="#note">1</a></h4>
<pre id="uaDetail">
<script type="text/javascript">
document.write(uaDetail());
</script>
</pre>
<h4>These are the properties that work in your browser:</h4>
<pre id="viewportDetail">
<script type="text/javascript">reGet();</script>
</pre>
<p>(<a href="#" onclick="reGet(); return false">Refresh</a> list)</p>
<p><a name="note">The user agent values are as reported by your user
agent (browser). Depending upon the UA you are using, you may be able
to change these in a preference setting. Some browsers pretend to
be some other browser by default - please check your UA's settings
to determine if the values are accurate.</a></p>
<div style="margin-left: 50;"><p id="zz" style="padding-left: 20;"><a
href="#" onclick="
var x = document.getElementById('zz');
var msg = 'offsetTop: ' + x.offsetTop
+ '\noffsetLeft: ' + offsetLeft;
alert(msg);
return false;
">Set offsetTop/Left</a></p></div>

</body></html>
 
R

Richard Cornford

Fred said:
... . Here is a viewport tester that tells you what
properties work for a the user agent it is loaded into.

That isn't strictly true. The script lists a number of properties of the
browser but does nothing towards indicating which of them most closely
relate to the viewport/client-region of any particular browsers.

'self.screen.height',
'self.screen.pixelDepth',

No screen properties relate in any way to the viewport dimensions (it
wouldn't even be valid to assume they represented an upper limit to the
viewport dimensions).

function uaDetail() {
var p = '<table border=\"0"\>'
+ '<tr><th style=\"text-align: left;\">Property</th>'
+ '<th style=\"text-align: left;\">Value</th</tr>';
if (navigator) {
var x = navigator;
} else {
p = 'Your user agent does not support the navigator object,'
+ '\nso I can\'t determine your viewport properties';

This is a bizarre, and slightly ludicrous, comment to be making to the
user. The browser's lack of support for a - navigator - object has
nothing to do with its ability to report viewport dimensions (either in
reality or in any of the rest of the code on this page).

if (props.indexOf('document.body') != -1) {
var end = props.substring(props.lastIndexOf('.')+1);
newprop = 'document.documentElement.' + end;
if (eval(newprop)) {
(eval(newprop)) ? c = 'Yes' : c = 'No';

<snip>

In the event that the expression - eval(newProp) - evaluated as true
then the following conditional expression must always assign "Yes" to
the value of - c -.

The recent thread with the subject "Top warning signs of bad code?"
proposes categorising all uses of - eval - to resolve constructed dot
notation property accessors as 'bad code'. This is a specific example of
where such an abuse could be directly replaced with a bracket notation
property accessor and the - eval - use omitted.

However, the rest of the code also makes extensive use of - eval, - and
because the data has been prepared in the form of full dot notation
property accessor stings their resolution to correspo0nding objects
could not be achieved otherwise (except with the Function constructor).
But the assertion that - eval - use for this task is wrong remains valid
because it is still unnecessary to use - eval - here, it is just a
matter of designing the need for - eval - out of the code.

Directly replacing the - viewportDetail - function and the - props -
array with the following, plus the addition of some additional functions
and arrays, removes the need for - eval - from the design (though it is
not the only way of doing so):-

var objects = [
['self'],
['screen'],
['document', 'body'],
['document', 'documentElement']
];
function arToString(){
return this.join('.');
}
for(var c = 0;c < objects.length;c++){
objects[c].toString = arToString;
}
var props = new Array(
'pageXOffset','pageYOffset',
'screenX','screenY',
'innerHeight','innerWidth',
'outerHeight','outerWidth',
'height','width',
'availHeight','availWidth',
'availTop','availLeft',
'Top','Left',
'screenTop','screenLeft',
'colorDepth','pixelDepth',
'clientHeight','clientWidth',
'scrollHeight','scrollWidth',
'scrollLeft','scrollTop',
'offsetHeight','offsetWidth',
'offsetTop','offsetLeft'
);

function getObjectWithArray(ar){
var o = this, c = 0;
while(
(c < ar.length)&&
(
(
(o = o[ar[c++]])&&
(
(typeof o == 'object')||
(typeof o == 'function')
)
)||
(o = null)
)
);
return o;
}

function viewportDetail() {
var obj, prop,count = 0;
var outAr = [
'<tr><td class=\"count\">','',
'<\/td><td>','',
'<\/td><td>','',
'<\/td><\/tr>'
];
var printstring = ('<table border=\"0\"><tr>'
+ '<th>#<\/th>'
+ '<th style=\"text-align: left;\">Property<\/th>'
+ '<th>Value<\/th>'
+ '<\/tr>');
for(var c = 0;c < objects.length;c++){
obj = getObjectWithArray(objects[c]);
if(obj){
for(var d = 0;d < props.length;d++){
if(typeof obj[(prop = props[d])] == 'number'){
outAr[1] = count++;
outAr[3] = objects[c]+'.'+prop;
outAr[5] = obj[prop];
printstring += outAr.join('');
}
}
}
}
return (printstring + '<\/table>');
}

Richard.
 
F

Fred Oz

Richard Cornford wrote:
[snip]
Directly replacing the - viewportDetail - function and the - props -
array with the following, plus the addition of some additional functions
and arrays, removes the need for - eval - from the design (though it is
not the only way of doing so):-
[snip]

Thanks Richard, your comments are gratefully received.

Regards, Fred.
 
T

Thomas 'PointedEars' Lahn

Fred said:
[...] Here is a viewport tester that tells you what
properties work for a the user agent it is loaded into.

This has been posted before, but I've done a little extra work and
think this is a better version.
[...]

People might want to try

<http://www.pointedears.de/scripts/test/ObjectInspector/nightly/latest/index>

instead (even if there is still a bug crashing IE on expanding
the "history" property subtree). Comments and bug reports not
covered by the bug list in "About" are welcome.


PointedEars
 

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,995
Messages
2,570,231
Members
46,820
Latest member
GilbertoA5

Latest Threads

Top