[Skip top navbar]

Andrew Gregory's Web Pages

Rocky outcrop at sunset, Approx 27°56'15"S 119°38'17"E

-

Menus


Introduction

The most common problem Opera has in relation to site compatibility, is the use of menus.

Rather than analyse specific web sites that use these menus, I'll analyse the menus themselves, describe what's wrong, and show what changes are needed to make them work in Opera.

Note that of those scripts listed below as working, in some cases their earlier versions do not work with Opera. In particular, I've noticed that many sites continue to use old versions of "HV Menu" from Dynamic Drive. Those sites need to do an update.

The modifications required to support Opera are indicated as follows:

It should be stressed that the modifications outlined here have no adverse effects on non-Opera browsers. The only browser affected by the changes is Opera. However, no version checking is performed, so these modifications to scripts that allow Opera 7 to work, will probably result in the scripts not working for earlier versions of Opera.


Opera Version 8

2005-01-05: Opera Software recently released a beta of version 8 of their browser. It had already been released as a special "preview" version 7.60. After v8 was released, a number of web site navigation menus stopped working! All that Opera Software had changed was the version number, but that was enough to confuse the scripts.

Scripts known to suffer from this problem are:

2005-04-23: With the final release of version 8, Opera Software have revealed a powerful tool to potentially fix all these problems: User Javascript. See my Opera User Javascript page for a version of such a script.


Scripts from Dynamic Drive

When I first analysed all the Dynamic Drive navigation scripts on 2004-07-17, many of them failed to work with Opera. In fact, it seems as if they were designed to not work with Opera.

Since then, most of the navigation scripts appear to have been updated so that they now work with Opera. Unfortunately, many of the other Dynamic Drive scripts still fail with Opera, some of them deliberately blocking Opera from using scripts that would otherwise work perfectly.

Summary

The usual problem is browser sniffing gone wrong:

var ie4=document.all&&navigator.userAgent.indexOf("Opera")==-1 var ns6=document.getElementById&&!document.all?1:0

As you can see, Opera is being deliberately excluded from being treated as Internet Explorer. That wouldn't be so bad, however, Opera's support for document.all also prevents it from being treated as Netscape 6+ (which includes the Mozilla and Firefox browsers). The reason that is a problem is that later on, the code assumes the browser has to be one or the other! Since Opera is neither, and has been correctly identified as neither, the later code will fail.

This is sloppy coding - making the assumption that only two browsers exist, and that no other browsers could possibly work using the existing code.

It's a bit ironic. document.all was implemented by Opera Software to improve compatibility with web sites, but here it's actually working against Opera! If it wasn't for the document.all support, Opera would be identified as Netscape 6+ and in just about every case the Netscape 6+ code would work just fine.

For the most part, I have decided that having the scripts treat Opera as though it's Netscape 6+ is best, as both browsers have good standards support and do the same things the same way. Hence:

var ie4=document.all&&navigator.userAgent.indexOf("Opera")==-1 var ns6=document.getElementById&&!document.all||window.opera?1:0

However, having the scripts treat Opera as though it's Internet Explorer would also work in many cases. The changes for that would be:

var ie4=document.all&&navigator.userAgent.indexOf("Opera")==-1 var ns6=document.getElementById&&!document.all?1:0

During my latest check, on 2005-04-03, I found that almost all the navigation scripts had been fixed up to work with Opera. If only the rest of the Dynamic Drive scripts could have received the same attention!

Dynamic Drive Script Analyses (2005-04-03)
NameWorks?Code
Slide-In Menu Bar I Yes n/a
Slide-In Menu Bar II Yes n/a
Slide-In Menu Bar III Yes n/a
Fold out external menu Yes n/a
Dynamic-FX Slide-In Menu Yes n/a
HV Menu Yes n/a
Top Navigational Bar Yes n/a
Top Navigational Bar II Yes n/a
Top Navigational Bar III Yes n/a
Jim's DHTML Menu Yes n/a
JsDOMenu Yes n/a
Switch Menu Yes n/a
Floating Menu Script Yes n/a
Static Menu Script II Yes n/a
Drop down menu w/ description Yes n/a
Chained select menu Yes n/a
DD Tab Menu Yes n/a
DD Tab Menu II Yes n/a
Tabs Menu (mouseover) Yes n/a
Drop down menu generator Yes n/a
Pop-it menu Yes n/a
Hover-up menu bar Yes n/a
Highlight menu effect Yes n/a
3-State highlight menu effect Yes n/a
CSS Menu highlight Yes n/a
Context menu Script No By default, Opera does not allow scripts to receive context menu events. This is by design (intentional). However, even if "Allow script to receive right clicks" is enabled, Opera still does not appear to pass the event on. That would seem to be a bug.
Context menu script II No Script uses Internet Explorer proprietary createPopup() function.
Microsoft Outlook bar No

This is a very Internet Explorer-specific bar. Firefox has no hope of handling this, but Opera comes very close! (Actually, by the time Firefox gets to 1.0, it could be that it will be able to support this script.) The problem is that when Opera reads the value of the "clip" style, it returns something like "rect(1px, 2px, 3px, 4px)", however, the code is not expecting the commas to be there (Internet Explorer does not return commas - this is OK as the commas are optional). It's easy to modify the code so that commas are accepted as well as spaces:

filter = /rect\((\d*)px[, ]*(\d*)px[, ]*(\d*)px[, ]*(\d*)px\)/;

(The filter occurs four times in the code)

There is still some sort of glitch with Opera where the folders don't always open out properly. Eventually the opening/closing will come good. Once it comes good it stays good. Note that the scroll up/down arrow images are missing in IE too!

Microsoft Outlook bar II Yes n/a

Likno Menu Scripts

Likno produce a pretty good commercial menu script. Also known as "All Web Menus", older versions were only written with Opera 6 (and maybe earlier) in mind. Opera 7 was given code for Opera 6, which, unfortunately, didn't work in the more recent Opera. However, the code used by the older versions of the menu script to support Gecko browsers (Mozilla/Firefox) would work perfectly in Opera 7.

Likno Script Analysis (2004-07-17)
NameWorks?Code
All Web Menus Yes

Versions earlier than 3.0 build 498 (dated 2003-01-31) do not support Opera 7. If those versions of the script that support Gecko browsers (Mozilla/Firefox) were to send the same code to Opera 7, Opera would work.

((nua.indexOf('Opera')>-1)?42


HierMenus Scripts

HierMenus is another commercial web menu script. Versions before 5.0 actively blocked Opera. Admittedly, those versions were developed before Opera 7 was released (the last version 4 script, 4.3, was released around 2002-06, about six months before Opera 7), however, many sites are still using pre-5.0 versions of HierMenus. Versions 5.0 and later of the script support Opera.

HierMenus Script Analysis (2004-07-20)
NameWorks?Code
HierMenus Yes

Versions earlier than 5.0 block Opera, however, if those versions of the script that support Gecko browsers (Mozilla/Firefox) were to send the same code to Opera 7, Opera would work.

HM_IsMenu = !HM_Opera && !HM_IE4M && (HM_DOM || HM_NS4 || HM_IE4 || HM_Konqueror || HM_Opera);


OpenCube Scripts

Recent versions of OpenCube's menu scripts attempted to refer to a completely undocumented JavaScript object (window.vxml), presumably in a misguided effort to test for "recent" Opera browsers. If they were only interested in version 7 of Opera, why they decided to not do the obvious thing and actually check the version number is anybody's guess! And what the heck does some random "vxml" object have to do with menus anyway? They don't even use it, after going to the effort of testing for it!

It should be obvious that relying on hidden and undocumented features is simply asking for trouble. Even the "error message" is totally inappropriate: "Please update your Opera browser". Every person using any version of Opera released in the last four months will see that and go "Huh?".

The usual recommendation myself and others make when faced with non-working menus is "update to the latest". In this case, the result is more broken menus! The poor web site maintainer is stuck in the middle of angry browser users and dodgy scripts!

It's even worse for Opera users. Opera is a minority browser and getting web site maintainers to even consider supporting Opera is a huge struggle. When script writers go about doing stupid things that can only create compatibility problems, web site maintainers are just encouraged to give Opera the flick!

Enthusiasts like myself sometimes go to a lot of effort lobbying web sites to update their scripts for Opera. That already gives the impression that Opera has trouble handling scripts, and can only handle the latest. When the latest code still doesn't work, it simply confirms the web site maintainers opinion that Opera can't handle even the simplest scripting. Never mind that it's nothing to do with Opera and is actually down to poor decisions made by the script developers!

UPDATE: Finally, eleven days after reporting the issue, OpenCube has made the trivial fixes to their code to allow Opera to work. They've also updated their web demos and download zip. Now it's just "Mission Impossible" to try and get the sites using their script to update!

OpenCube Script Analysis (2004-09-24)
NameWorks?Code
OpenCube Yes

Recent versions of their script used to test for the undocumented JavaScript object window.vxml. This object happens to exist in all Opera 7 versions up to and including 7.23. It does not exist in the next higher Opera 7 version, 7.50, or later. The test has now been replaced with window.attachEvent, which appears to be a much more sensible choice.

if(window.vxmlattachEvent){

(The test is performed twice in the "pbrowser_opera.js" file)


OpenCube Scripts, The Saga Continues...

This time it's been discovered that Open Cube has two versions of its menu code for Opera. A modern, fully functional one for Version 7, and a lesser one designed for Opera 6. The problem is that the V7 code is sent only to Opera 7, every other version of the Opera browser gets the V6 code! That includes the new version 8 Opera browser!

OpenCube Script Analysis (2004-12-30)
NameWorks?Code
OpenCube Yes

Version checks are too specific.

bd_v7opera=q148&&(q137("7.")!=-1parseFloat(navigator.userAgent.substr(navigator.userAgent.indexOf("Opera")+6))>=7);


Milonic Menus

Unfortunately, Milonic menus have a reputation as being a bit fragile. You really need to ensure you keep right up-to-date with these scripts.

Milonic Script Analysis (2004-09-24)
NameWorks?Code
Milonic Yes

Versions of this menu before 3.5.08 dated 2002-11-13 are not compatible with Opera 7. This old code is probably designed for Opera 6 or earlier. The change below fixes the scripts operation under Opera 7 by having the script treat it the same as Gecko-based browsers, but will break older Opera browsers.

konq=(navigator.userAgent.indexOf("Konqueror")!=-1)?true:false if(opera){ns6=ns61=true;ie55=opera=false;} mp=(ns6)?"pointer":"hand";oatop=0;aleft=0;oaleft=1;osy=0;oww=-1;owh=-1;frs=0;fre=0;nsmatch=0;


SoThink Menus

Versions of the SoThink DHTML menus written before Opera 7 was released, are coded to work around bugs in Opera 6, except the script doesn't do any version checking and the bug fixes are inappropriately applied to the relatively bug-free Opera 7. The result is non-functioning menus.

SoThink Script Analysis (2004-11-28)
NameWorks?Code
SoThink Yes

Versions of this menu up to at least 3.72 do not work with Opera 7. Preventing the script from detecting Opera allows the menus to work (more or less - there is still a glitch when the menus first display that disappears when the menus are redisplayed).

nOP=naAgn.indexOf("Opera")>=0false;

A better solution is the following, which results in perfect operation:

if(nOP){nOP=nOP5=false;nNN=nNN6=true;} nSTMENU=nOP5||nIE4||nNN;


-