Cross-browser programming

S

Simba

In some pages of my website I use a code like the following:


for (var n = 0; n < getTagsArray("SPAN").length; n++){

//SPAN is just an example. I also use other tags
tag = getTagsArray("SPAN")[n];

//make something with tag...
}


function getTagsArray(Tag){

if(document.all){ //Internet Explorer
return document.all.tags(Tag);
}
else if (document.layers){ //Netscape
eval("return document.tags." + Tag);
}

}

I want to put all browser-specific code inside the getTagsArray
function. So far, I've programmed only for Internet Explorer (my
browser), but now I want to make my website visible to all browsers.
I'm not sure about the getTagsArray function. Is it right or is there
a better way to do the same thing? And how can I extend that function
to make it work in other browsers?

Finally, where can I find some information about cross-browser
programming? I have the javascript reference for Internet Explorer and
Netscape, but I know nothing about other browsers.

Thanks for your help,

Simba
 
K

Keith Bowes

Simba said:
In some pages of my website I use a code like the following:


for (var n = 0; n < getTagsArray("SPAN").length; n++){

//SPAN is just an example. I also use other tags
tag = getTagsArray("SPAN")[n];

//make something with tag...
}


function getTagsArray(Tag){

if(document.all){ //Internet Explorer
return document.all.tags(Tag);
}
else if (document.layers){ //Netscape
eval("return document.tags." + Tag);
}

The modern way to do this is:
document.getElementsByTagName(Tag)

So you may want:
if (document.getElementsByTagName)
return document.getElementsByTagName(Tag);
else if (document.all) ...
}


I want to put all browser-specific code inside the getTagsArray
function. So far, I've programmed only for Internet Explorer (my
browser), but now I want to make my website visible to all browsers.
I'm not sure about the getTagsArray function. Is it right or is there
a better way to do the same thing? And how can I extend that function
to make it work in other browsers?

Finally, where can I find some information about cross-browser
programming? I have the javascript reference for Internet Explorer and
Netscape, but I know nothing about other browsers.

All modern sciptable browsers should implement the W3C DOM
<http://www.w3.org/DOM>, level 1 at least.

As long as you stick to DOM 1 objects, methods and properties, you
should be fine. Also, accessing the style property of elements is
fairly global. The single biggest cross-browser trap nowadays is events
(MS refuses to support DOM events).

Search Google for "DOM Compatibility" for more specific info.
 
L

Lasse Reichstein Nielsen

Keith Bowes said:
Simba wrote:
So you may want:
if (document.getElementsByTagName)
return document.getElementsByTagName(Tag);
else if (document.all) ...

I second that. You will also find that the newer versions
of IE understands getElementsByTagName too.

My reason to butt in: You don't need the eval for Netscape 4. Just
write:
return document.tags[Tag]

/L
 
R

Richard Cornford

Simba said:
In some pages of my website I use a code like the following:

for (var n = 0; n < getTagsArray("SPAN").length; n++){

//SPAN is just an example. I also use other tags
tag = getTagsArray("SPAN")[n];

//make something with tag...
}

This is very inefficient coding. The process of acquiring a collection
or nodeList of all of the tags of a particular type is quite intensive
so repeating that process for each evaluation of the length of the
collection and again to acquire each reference to an element is very
wasteful and relatively slow.

Also, as it is the getTagsArray function is not guaranteed to return an
object at all. The following might be better:-

var tagsCollection = getTagsArray("SPAN")
if(tagsCollection){
for (var n = 0; n < tagsCollection.length; n++){
tag = tagsCollection[n];
//make something with tag...
}
}
function getTagsArray(Tag){

if(document.all){ //Internet Explorer
return document.all.tags(Tag);
}
else if (document.layers){ //Netscape
eval("return document.tags." + Tag);

That particular incantation is misguided in several ways. First, it uses
eval to resolve a constructed dot notation property accessor. This is
not necessary and relatively inefficient when compared with the
alternatives:-

URL: http://www.litotes.demon.co.uk/js_info/sq_brackets.html >

However, the document.tags collection on Netscape 4 is not a collection
of references to HTML elements. Netscape 4 does not make the majority of
HTML elements accessible to JavaScript and the document.tags collection
is entirely related to Netscape 4's JavaScript Style Sheets (JSS)
implementation of CSS.
}

}

I want to put all browser-specific code inside the getTagsArray
function. So far, I've programmed only for Internet Explorer
(my browser), but now I want to make my website visible to all
browsers. I'm not sure about the getTagsArray function. Is it
right or is there a better way to do the same thing? And how
can I extend that function to make it work in other browsers?

Browsers that implement the W3C DOM level 1 standard (Opera 5+, IE 5.0+,
Netscape 6+, Konqueror 3+, ICEBrowser, and many others) have a
document.getelementsByTagName function that will do the required task.

For Netscape 4 the process is considerably more complex as you would
have to provide code to search the various collections. Elements with
CSS position properties of 'relative' or 'absolute' will be in the
document.layers collection. INPUT, SELECT and TEXTAREA elements could be
recovered by searching the elements collection of each form on the page
(plus the forms on any documents within layers), and OPTION tags from
the options collections of SELECT elements. FORM elements from the forms
collections, IMG from the images collection and A elements from a
combination of document.anchors and document.links. That is 120 odd
lines of code to provide a very limited emulation of
getElementsByTagName on a browser that is little used and will probably
not let you do whatever you were planning on doing with the elements
anyway.
Finally, where can I find some information about cross-browser
programming? I have the javascript reference for Internet
Explorer and Netscape, but I know nothing about other browsers.

Locate the comp.lang.javascript newsgroup archive on groups.google.com
and read as much of it as you have time to.

Richard.
 
R

Richard Cornford

... That is 120 odd lines of code to provide a very limited
emulation of getElementsByTagName on a browser that is
little used and will probably not let you do whatever you were
planning on doing with the elements anyway.

You might still be interested in what that 120 odd lines of code might
look like. This is an example, its strategy is to normalise
document.getElementsByTagName on browser that do not support it. This
version does not attempt to handle the problem of extracting CSS
positioned elements on Netscape 4.

if(!document.getElementsByTagName){
if(document.all){
document.getElementsByTagName = function(nem){
return document.all.tags(nem.toUpperCase());
}
}else{
document.getElementsByTagName = function(){
var selTypes = ['select-one','select-multiple','select'];
var inpTypes = ['radio','text','reset','submit','image',
'password','hidden','checkbox','button','file'];
var txATypes = ['textarea'];
function handleName(name, ob, ar){
if((ar[name])&&(ar[name] != ob)){
if((typeof ar[name].length == 'number')&&
(!ar[name].options)){ //is an array (not a select)
var add = true;
for(var c = ar[name].length;c--;){
if(ar[name][c] == ob){
add = false;
break;
}
}
if(add)ar[name][ar[name].length] = ob;
}else{ //is an element
ar[name] = [ar[name], ob];
}
}else{
ar[name] = ob;
}
}
function addCollection(col, ar){
if(col){
for(var ob,c = col.length;c--;){
ob = col[c];
if(ob.name)handleName(ob.name, ob, ar);
if(ob.id)handleName(ob.id, ob, ar);
ar[ar.length] = ob;
}
}
};
function addOptionsEls(frms, ar){
var ob,sels = [];
addFormEls(frms, 'select', sels);
for(var c = sels.length;c--;){
if(sels[c].options){
for(var d = sels[c].options.length;d--;){
ob = sels[c].options[d];
if(ob.name)handleName(ob.name, ob, ar);
if(ob.id)handleName(ob.id, ob, ar);
ar[ar.length] = ob;
}
}
}
}
function addFormEls(frm, nem, ar){
if(frm){
var types;
switch(nem){
case 'input':
types = inpTypes;
break;
case 'select':
types = selTypes;
break;
case 'textarea':
types = txATypes;
break;
default:
break;
}
if(types){
for(var e = frm.length;e--;){
var fr = frm[e].elements||frm[e];
var ob,ty,el;
for(var c = fr.length;c--;){
el = fr[c];
if((typeof el.length == 'undefined')||(el.options)){
el = [el];
}
for(var f = el.length;f--;){
if(ty = el[f].type){
for(var d = types.length;d--;){
if(ty == types[d]){
ob = el[f];
if(ob.name)handleName(ob.name, ob, ar);
if(ob.id)handleName(ob.id, ob, ar);
ar[ar.length] = ob;
break;
}
}
}
}
}
}
}
}
};
function searchDoc(doc, nem, ar){
if(doc){
switch(nem){
case 'a':
addCollection(doc.links, ar);
addCollection(doc.anchors, ar);
break;
case 'img':
addCollection(doc.images, ar);
break;
case 'input':
case 'select':
case 'textarea':
addFormEls(doc.forms, nem, ar);
break;
case 'option':
addOptionsEls(doc.forms, ar);
break;
case 'form':
addCollection(doc.forms, ar);
break;
default:
break;
}
if(doc.layers){
for(var c = doc.layers.length;c--;){
searchDoc(doc.layers[c].document, nem, ar);
}
}
}
};
return function(nem){
var ar = [];
searchDoc(document, nem.toLowerCase(), ar)
return ar;
};
}();
}
}

Richard.
 

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,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top