Site Navigation

Showing posts with label Opera. Show all posts
Showing posts with label Opera. Show all posts

Friday, November 9, 2007

bug 317 - onload doesn't work everywhere

Issue: #317
Affects: Firefox, IE6, IE7, Opera, Safari

According to the JavaScript documentation, the onload event can be handled for the body, iframe, img, frameset & object tags. However not all browsers obey this the same.

Supports iframe onload:
Firefox - Yes
IE6, IE7 - Yes
Opera - Yes

Safari - No

Supports object onload:
Firefox - No
IE6, IE7 - No
Opera - No
Safari - Yes

So, take this into consideration if you are planning to use object versus an iframe in your next project.


Known Workarounds: None.

Related Issues: None.

Wednesday, October 17, 2007

bug 256 - DOM nodeType constants are not in IE and Opera

Issue: #256
Affects: IE5, IE5.5 IE6, IE7, IE8 Beta 1, Opera 8.2, Opera 9.2
Fixed in: Opera 9.50 alpha 1 build 9500
MSIE Feedback ID: 339307

The ECMAScript specification for the DOM provides a set list of element types or nodeTypes... Text Elements, Node Elements, Comments, etc. They are numbered integers, with a Constant defined for easy to read comparison purposes. The only problem is, that they are not Constants at all, in IE or Opera.

NodeTypes:

interface Node {
// NodeType
const unsigned short ELEMENT_NODE = 1;
const unsigned short ATTRIBUTE_NODE = 2;
const unsigned short TEXT_NODE = 3;
const unsigned short CDATA_SECTION_NODE = 4;
const unsigned short ENTITY_REFERENCE_NODE = 5;
const unsigned short ENTITY_NODE = 6;
const unsigned short PROCESSING_INSTRUCTION_NODE = 7;
const unsigned short COMMENT_NODE = 8;
const unsigned short DOCUMENT_NODE = 9;
const unsigned short DOCUMENT_TYPE_NODE = 10;
const unsigned short DOCUMENT_FRAGMENT_NODE = 11;
const unsigned short NOTATION_NODE = 12;
//...
}


Example:

<script type="text/javascript">
var obj = document.getElementById('someID');
var textContent [];
for(var i=0;i<obj.childNodes.length;i++){
if(obj.childNodes.item(i).nodeType == TEXT_NODE){
textContent.push( obj.childNodes.item(i) );
}
}
alert('The inner text without HTML tags is: ' + textContent.join(', '));
</script>


In a spec compliant browser, the code should be able to test against the TEXT_NODE constant.


Known Workarounds: One. It is extra processing, but each element type can be defined as globals at the begining of every page.

Example Workaround Code:

<script type="text/javascript">
(function(){
var NodeTypes = ['ELEMENT', 'ATTRIBUTE', 'TEXT', 'CDATA_SECTION',
'ENTITY_REFERENCE', 'ENTITY', 'PROCESSING_INSTRUCTION',
'COMMENT', 'DOCUMENT', 'DOCUMENT_TYPE',
'DOCUMENT_FRAGMENT', 'NOTATION'];
for(var i=0i<NodeTypes.length;i++){
window[NodeTypes[i] + '_NODE'] = (i + 1);
}
})();
</script>



Related Issues: None.

Wednesday, August 29, 2007

Opera

Opera:

Opera is an interesting browser, that was first on the scene for many advanced features in the browser (tabs, zooming, security), but didn't gain a lot of traction because it was distributed on a "shareware"-like model when competing directly against IE. It's since been offered for free (since Firefox became very popular), and has had a significant increase in users.

Pros:
Its fast, blazing fast!
Has every feature you'll ever need
Follows most spec items very well

Cons:
Has a legacy of mimicking IE, including many of IE's bugs
Doesn't allow [Tab] navigation of hyperlinks :-(


Bugs: (bug 152)

More to come...

Friday, August 24, 2007

bug 152 - getElementById returns incorrect objects in IE and Opera

Issue: #152
Affects: IE5, IE5.5, IE6, IE7, Opera 8.2, Opera 9.2
Fixed in: Opera 9.50 alpha 1 build 9500
Almost Fixed in: IE8 Beta 1

MSIE Feedback ID: 333979

Example:
<script type="text/javascript">
var descField = document.getElementById( 'description' );
alert( descField.nodeName );
</script>

The above code works perfectly, in all browsers returning the element with the id "description". Well almost. IE will return the element with that id, but it will also return any element with a name set to "description". At first glance this may not seem such an issue, but consider this; Do you have a meta tag on any of your pages? Do any of them have a name attribute with the value description? If so, you will get a reference to the meta tag, not the form element (or whatever you thought you were getting, as indicated in the spec for getElementById).

When you think for a moment, about where the name attribute is set, this becomes rather scary. Any named anchor, can now conflict with your well defined element ids.

Notes:
So you might ask, why is this broken in Opera? Opera is usually pretty good at supporting the specs! Well, it seems that for maximum compatibility with IE, even though it is implemented wrong, they mimicked the broken behavior.


Known Workarounds: No direct methods, using Option #3 below is suggested.

Workaround Option: 1
If you rely heavily on getElementById, and you suspect that you may have name conflicts, or that user specific content added to a page may cause conflicts you can use getElementsByTagName( tagName ) then iterate over the results and compare the value returned by getAttribute( 'id' ).

Example Workaround Code:
var inputs = document.getElementsByTagName( 'textarea' );
var descField = null;
for(var i=0;i<inputs.length;i++){
if(inputs.item(i).getAttribute( 'id' ) == 'description' ){
descField = inputs.item(i);
break;
}
}




Workaround Option: 2
If you have the ability to globally apply fixes for IE and Opera, the following code will make both of them follow the spec to a 'T', with a very tiny performance hit.

In this example, we redifine the getElementById method, to work as it was intended.
Example Workaround Code:
//use browser sniffing to determine if IE or Opera (ugly, but required)
var isOpera, isIE = false;
if(typeof(window.opera) != 'undefined'){isOpera = true;}
if(!isOpera && navigator.userAgent.indexOf('Internet Explorer')){isIE = true;}

//fix both IE and Opera (adjust when they implement this method properly)
if(isOpera || isIE){
document.nativeGetElementById = document.getElementById;
//redefine it!
document.getElementById = function(id){
var elem = document.nativeGetElementById(id);
if(elem){
//verify it is a valid match!
if(elem.id == id){
//valid match!
return elem;
} else {
//not a valid match!
//the non-standard, document.all array has keys for all name'd, and id'd elements
//start at one, because we know the first match, is wrong!
for(var i=1;i<document.all[id].length;i++){
if(document.all[id][i].id == id){
return document.all[id][i];
}
}
}
}
return null;
};
}



Oh my! this just gets better and better! (after posting and using this I noted (as did J. Max Wilson) that the second workaround, actually exposes another bug in IE!

Third time's a charm (we hope!)

Workaround Option: 3

Same as workaround 2 above, but rather than test elem.id or elem.getAttribute('id') we'll use the much safer elem.attributes collection. Unfortunately if the element you are looking for, in turn has a child element with a name or id attribute, that is set to "id", it will not test the attribute, but rather the child element. (bug 162 - global namespace pollution)

Example Workaround Code:
//use browser sniffing to determine if IE or Opera (ugly, but required)
var isOpera, isIE = false;
if(typeof(window.opera) != 'undefined'){isOpera = true;}
if(!isOpera && navigator.userAgent.indexOf('Internet Explorer')){isIE = true;}

//fix both IE and Opera (adjust when they implement this method properly)
if(isOpera || isIE){
document.nativeGetElementById = document.getElementById;
//redefine it!
document.getElementById = function(id){
var elem = document.nativeGetElementById(id);
if(elem){
//verify it is a valid match!
if(elem.attributes['id'] && elem.attributes['id'].value == id){
//valid match!
return elem;
} else {
//not a valid match!
//the non-standard, document.all array has keys for all name'd, and id'd elements
//start at one, because we know the first match, is wrong!
for(var i=1;i<document.all[id].length;i++){
if(document.all[id][i].attributes['id'] && document.all[id][i].attributes['id'].value == id){
return document.all[id][i];
}
}
}
}
return null;
};
}




Related Issues: (bug 154), (bug 411), (bug 162).