Roger said:
I need help : I found the simplest and most precise
way to open and close submenu layers.
Simplicity is at least partly a matter of perception. One line of code
might seem to qualify but when that line of code combines a number of
actions, and eliminates much sensible checking and verification, the
simplicity is only really in its appearance.
it works perfectly with IE, but for some odd
reason NS won't recognize it.
It is not that odd a reason. Any code that employs a Microsoft
proprietary feature should be expected to fail on a non-Microsoft
browsers (and often on non-default configurations, or non-Windows, IE).
The quick answer is the use of - document.all - as Netscape/Gecko
browsers have traditionally not implemented it (the most recent Mozilla
versions are implementing it as a concession to ancient code written in
the "both browsers" days without sensible feature detection. It seems
unlikely that a gecko browser with 'Netscape' in its name will be
released based upon the latest Mozilla code).
And is there a way around the problem ?
The simple act of showing/hiding a DOM element with CSS is achievable on
all dynamic, and many less-dynamic, browsers. Including some relatively
ancient browsers like Netscape 4, if the element in question is assigned
a CSS potion value of 'absolute' or 'relative', for the effort of adding
some extra lines of code.
I really like the elegance of this code and would like to
keep using it.
It is a hack.
^
A closing '>' might be a good idea here.
<script language="Javascript"`>
Script elements are required to include the TYPE attribute in HTML 4.
The language attribute is deprecated and becomes redundant when a TYPE
attribute is included:-
These HTML comment-like sequences are unnecessary in current browser
scripting as they were introduced to address issues with browser that
have not been in use for some considerable time.
function Pop(name){
eval("document.all."+name+".style.visibility='visible'");
}
This is what you are describing as simplicity:-
1. Construct a string representing javascript source code.
2. Have that executed as a javascript program in a new eval
execution context. Starting a javascript interpreter,
have it interpret and execute the program and return the
result. A process consisting of:-
A. Resolve - document - against the scope chain and
retrieve a reference to that object (assuming it
exists, probably a safe assumption as - document -
is universal in HTML web browsers).
B. Resolve - all - as a named property of that object
and retrieve a reference to that object (it doesn't
exist in Netscape browsers so the value retrieved
in - undefined - not an object reference).
C. Resolve - style - as a named property of that object
(Netscape errors here as - all - was not an object) and
retrieve a reference to that object (assuming it exists).
D. Assign a string value to the - visibility - property of
that object.
The use of the - eval - contributes nothing to simplicity here, in the
source code or the execution of the code. It follows from nothing but
the author's ignorance of javascript as a language as it is being use to
dynamically insert one identifier in a dot notation property accessor.
Javascript has always offered the bracket notation property accessor as
a means of referencing objects using string value valuables (and
expressions) in place of identifiers. Simply using the bracket notation
in place of eval produces:-
document.all[ name ].style.visibility='visible';
(a much simpler line of code (and much simplified execution), though
equally error prone).
With the exception of the - document - reference (and some would include
that), everywhere that an assumption is made above a test to verify that
assumption is indicated. Simplicity achieved by omitting those tests is
not valuable simplicity.
Adding an implementation of the minimum testing might produced code
like:-
function Pop(name){
var el;
/* Only attempt to use the - document.all -
collection if it exists on this browser:-
*/
if(document.all){
el = document.all[ name ];
}
/* Verify that the DOM element retrieval happened
and returned a valid/usable object reference.
And then verify that the object reference has
a style property:-
*/
if(el && el.style){
/* It should be safe (non-error producing) to
assign a value to 'visibility' the el.style
object (whether the browser assigned meaning
to that action is another question):-
*/
el.style.visibility='visible';
}
}
Which has lost some of its original simplicity but will now not
error-out.
It still will not work with Netscape browsers as they do not implement -
document.all -. To get round that an alternative element retrieval
mechanism must be used. W3C Core DOM standard browsers provide a -
document.getElementById - method that is designed to retrieve a
reference to an element with a (unique) ID attribute that corresponds
with the string argument provided to the method call. These browsers
include IE 5.0+ and Netscape 6+ (and many others). This method is the
preferred method of retrieving such element references is it is most
wildly supported, - document.all - is now only a fall-back alternative
for ancient browser like IE 4 (and one or two others that are not going
to provide the - style - object anyway).
Again it is necessary to verify that the browser facilitates -
document.getElementByyId -, but if it does not - document.all - can be
tried as a fall back (alternative fall-back mechanisms can be used for
Netscape 4 under some circumstances). The modified code becomes:-
function Pop(name){
var el;
/* Only attempt to use the - document.getElementById -
if it exists on this browser:-
*/
if(document.getElementById){
el = document.getElementByI( name );
}else if(document.all){ // else try - document.all -:-
el = document.all[ name ];
}
/* Verify that the DOM element retrieval happened
and returned a valid/usable object reference.
And then verify that the object reference has
a style property:-
*/
if(el && el.style){
/* It should be safe (non-error producing) to
assign a value to 'visibility' the el.style
object (whether the browser assigned meaning
to that action is another question):-
*/
el.style.visibility='visible';
}
}
The fact that the branching element retrieval mechanism is needed in
both functions, and is more involved than the original anyway, makes
this look considerably less simple. That follows from a failure to
recognise the real steps in this process. The first step in both the
setting of the property to 'visible' or ' hidden' is the retrieval of
the reference to the DOM element. Both functions must use the same
mechanism (and potentially much other code would require the same
facility). This suggests that element retrieval would be better done by
one separate function.
The notes to the newsgroup FAQ cover various approaches to implementing
a single IDed element retrieval mechanism is some detail but a simple
(and non-optimum) implementation might go:-
fucntion getElementWithId(id){
if(document.getElementById){
return document.getElementById(id);
}else if(document.all){
return document.all[id];
}else{
return null; //no retrieval mechanism available
}
}
Reducing the original function to a simple:-
function Pop(name){
var el = getElementWithId(name);
/* Verify that the DOM element retrieval happened
and returned a valid/usable object reference.
And then verify that the object reference has
a style property:-
*/
if(el && el.style){
/* It should be safe (non-error producing) to
assign a value to 'visibility' the el.style
object (whether the browser assigned meaning
to that action is another question):-
*/
el.style.visibility='visible';
}
}
- and having a similar simplifying effect on the internal code of both
functions.
The next step in the process, the verification of and referencing of the
style object, is also common to both functions (and again potentially
useful elsewhere). It would be possible to re-use the element retrieval
function code and wrap the style object handling around it, but element
retrieval is such a generally common requirement in browser DOM
scripting that the element retrieval function is probably best left
available to all code and a style object retrieval function designed to
call it for its element references. So the style object retrieval
function could go:-
function getStyleObjWithId(id){
var el = getElementWithId(id);
return (el && el.style)||el;
}
Reducing the original function to:-
function Pop(name){
var st = getStyleObjWithId(name);
if(st){
st.visibility='visible';
}
}
- and its counterpart to:-
function Wop(name){
var st = getStyleObjWithId(name);
if(st){
st.visibility = 'hidden';
}
}
Which, while not as simple as one line of code, are relatively simple
and clear, will work on DOM standard browsers in addition to IE and will
not error-out on any browsers. (in addition, active support for
dinosaurs like Netscape 4, when such is possible, is now just a matter
of using a more involved element retrieval function (as can be found in
the FAQ notes) as everything down-stream of that is already in place and
cross-browser).
Richard.