"David List" <da***@davidlist.dk> wrote in message
news:ef************@initio.dk...
I'm having a problem using different properties of the document
object in the example javascripts in my textbook with browsers
that identify themselves as using the Mozilla engine.
The majority of books on browser scripting are out of date (including
this one by the look of it), and browsers cannot be trusted to identify
themselves at all. All are capable of lying and many do so as a matter
of course.
One example of these problems is using document.layers.
I have Google'd for examples of how to use the document
object specifically with Mozilla, but I cannot
find anything that explains why my problems occur.
Mozilla based browsers do not have a document.layers collection.
Could anyone here see through the included example and tell me
if there is anything absolutely wrong with this?
OK.
It seems to me that the examples in my textbook simplify browser
identification to the point where it doesn't work. Am I right
in this?
Browser identification does not ever work, it is impossible. The whole
idea has been dropped in favour of feature/object detection related
specifically to the objects and features of the browser that the script
is interested in using (well, at least by everyone who knows what they
are doing). That approach achieves functionality up to the browser's
ability to support the script without ever needing to know any specifics
about which browser is executing the script.
----------example----------
<html>
<head>
<meta name="keywords" content="">
<meta name="description" content="">
Empty meta tags? We didn't need to see those. Newsgroup posts should be
edited down to the minimum (valid code) needed to explain the problem.
<title>Test-titel</title>
<link rel="stylesheet" href="./style.css">
<script language="javascript">
The language attribute has been deprecated in favour of the type
attribute (which is both backward and forward compatible):-
<script type="text/javascript">
<!--
This "hide from older browsers" stuff is no longer needed. The browsers
that were young when it was introduced are now so old themselves that
they have all gone out of use.
var active = 0;
var browser = null;
function Init()
{
browser = new BrowserObj();
}
function BrowserObj()
{
this.navigator = null;
this.explorer = null;
this.other = null;
if((navigator.appName.toLowerCase()).
indexOf("netscape") >= 0)
this.navigator = 1;
These values (this.navigator, explorer and other) look like they are
boolean so assigning numeric values seems inappropriate. As the - if -
test expressions resolve to boolean values it would probably be more
efficient to assign the results of the resolved expressions to the
object properties directly:-
this.navigator=(navigator.appName.toLowerCase().in dexOf("netscape")>=0)
else
if((navigator.appName.toLowerCase()).indexOf("expl orer") >= 0)
this.explorer = 1;
else
this.other = 1;
this.major = parseInt(navigator.appVersion);
this.minor = parseFloat(navigator.appVersion);
}
Browser detecting is _absolutely_ wrong. Browser detecting based on the
userAgent and appVersion (and/or appName) is utterly useless, browser's
lye habitually so nothing can be learnt by asking these questions. Chuck
it all out!
function ChangeLayer(now)
{
if(browser.navigator != null)
{
This is where browser detecting demonstrates its inferiority to
feature/object detecting. This branch wants to use the -
document.layers - collection. There is no relationship between a browser
having the substring "netscape" in its - navigator.appName - property
and its support for a - document.layers - collection, but there is a
direct relationship between a browser's support for a -
doucment.layers - collection and that browser having
a -document.layers - collection. So that is what should be tested prior
to the use of that object (though not necessarily prior to each and
every invocation). The test should be:-
if(document.layers){
. . . // use the layers collection, it exists!
}
document.layers["content" + active].visibility = "hide";
document.layers["content" + now].visibility = "show";
}
else
{
var current = document.all("content" + active).style;
IE browsers are very tolerant of errors, second guessing the author and
letting them fall into bad habits that they will have to unlearn when
exposed to any other browser. One of those bad habits is using
parentheses to access object properties. The - document.all - collection
is an object (and it is supported on a very large number of current
browsers), so property access syntax is to use square brackets. Doing
that will make this code functional on any browser with a -
document.all - collection instead of just the ones that reproduce IE's
error correcting behaviour:-
var current = document.all["content" + active].style;
var next = document.all("content" + now).style;
current.visibility = "hidden";
next.visibility = "visible";
active = now;
}
}
// -->
</script>
</head>
<body onLoad="Init()">
<div id="menua" style="top: 5; left: 5; visibility: visible;
position: absolute; z-index: 5;">
O.T. but CSS property values that represent lengths/dimensions are
required to specify the unit (px, em, en, ex, etc.). It is always a good
idea to validate HTML and CSS as there are no standards for the handling
of invalid code so only valid code can reasonably be expected to produce
a consistent DOM for JavaScript manipulation.
<p class="SWITCH">
<a href="#" onClick="ChangeLayer(0)">One</a>
<a href="#" onClick="ChangeLayer(1)">Two</a>
<a href="#" onClick="ChangeLayer(2)">Three</a>
<snip>
Onclick handlers are allowed to cancel the navigation specified in the
HREF attribute by returning false. If the intention of the onclick code
is only to execute a function then it should cancel the navigation (even
if it is only to the top of the current page as in "#").
For contrast this is an alternative version of your page. Note that the
browser detecting is gone, this page is not interested in the browser at
all only its features. It will also work with Mozilla based browsers
because it branches to use the W3C Core DOM Level 1 -
document.getelementById - method to look up the reference to the DIVs,
and uses that method in preference to all others because it is common to
the largest number of current browsers including IE 5.0+.
<html>
<head>
<title>Test-titel</title>
<link rel="stylesheet" href="./style.css">
<script type="text/javascript">
var active = 0;
function getStyleObj(id){
var obj = null;
if(document.getElementById){
obj = document.getElementById(id);
}else if(document.all){
obj = document.all[id];
}else if(document.layers){
obj = document.layers[id];
}
return (obj && obj.style) || obj;
}
function ChangeLayer(now){
var current = getStyleObj("content" + active);
var next = getStyleObj("content" + now);
if(current && next){
current.visibility = "hidden";
next.visibility = "visible";
active = now;
}
return false;
}
</script>
</head>
<body>
<div id="menua"
style="top:5px;left:5px;visibility:visible;positio n:absolute">
<p class="SWITCH">
<a href="#" onClick="return ChangeLayer(0)">One</a>
<a href="#" onClick="return ChangeLayer(1)">Two</a>
<a href="#" onClick="return ChangeLayer(2)">Three</a>
</p>
</div>
<div id="content0"
style="top:40px;left:0px;visibility:hidden;positio n:absolute;">
<h1>A test header</h1>
<p>Here is some text</p>
</div>
<div id="content1"
style="top:40px;left:0px;visibility:hidden;positio n:absolute;">
<h1>One more test header</h1>
<p>Some more test</p>
</div>
<div id="content2"
style="top:40px;left:0px;visibility:hidden;positio n:absolute;">
<h1>Yet one more test header</h1>
<p>Yet more text</p>
</div>
</body>
</html>
Richard.