PDA

View Full Version : Chrome CSS Drop Down Menu (v2.5) - Does not work with IE 5



filetmignon
12-15-2008, 03:08 AM
The drop down menu is advertised as working for IE 5, but the drop down menu javascript breaks for IE 5, and does not work even on your demo at:

http://www.dynamicdrive.com/dynamicindex1/chrome/index.htm

IE 5 does not work.
All other browswer versions works as advertised.

A copy of the IE 5 standalone web browser and all older versions of IE for testing can be found at:

http://browsers.evolt.org/?ie/32bit/standalone

ddadmin
12-15-2008, 07:37 AM
I have a copy of IE5.01 on my PC, but it's no good as it basically crashes immediately each time after launching for some reason. The script does work in my copy of IE5.5. Either way though, IE5 should be dead long ago, and it's not really a priority at this point for me for scripts to work in that browser. I may just update the compatibility list for Chrome Menu to IE5.5.

Snookerman
12-15-2008, 07:39 AM
Is ie5 really used anymore?

filetmignon
12-15-2008, 10:15 PM
According to:

http://en.wikipedia.org/wiki/Internet_Explorer

IE 5 comes with Windows 2000 by default.
People might still use Win 2000.

http://en.wikipedia.org/wiki/Windows_2000
(under Common Features)

Win98 and older should be gone.

I think you may want to try the standalone IE 5.01 archived at Evoke:

There is a: 9x version and a NT version: of 5.01

9x Version:
http://browsers.evolt.org/download.php?/ie/32bit/standalone/ie501sp2_9x.zip

NT Version:
http://browsers.evolt.org/download.php?/ie/32bit/standalone/ie501sp2_nt.zip

If the NT version didn't work for you, the 9x version might just work.
It may just be the version you are using. I remember encountering that crash problem
before, and I got it working by using the correct version.

jscheuer1
12-16-2008, 04:15 AM
This really is, in my opinion, the gold standard for multiple IE's (up to and including v6 with v7 as the actual installed browser on the machine):

http://tredosoft.com/Multiple_IE

It comes with an installer that modifies your registry so that the standalone versions actually identify as the version number that they are and more (not all) features - like filters - work in those versions that do support them.

That said, the script in question doesn't work with my IE 5. But there are so many errors on the demo page in IE 5 that it might not be the script itself, rather other code that is halting script processing.

In any case, I'm with ddadmin. Even if someone is using Win 2000, they probably long ago upgraded to IE 5.5 or 6.

I do still test in IE 5 sometimes, mostly just for my own amusement. The css support is horrible and the javascript interpreter doesn't support many standard objects, or supports them incorrectly. This is a problem with all IE , but at least more recent versions aren't so outdated, and can usually be whipped into shape with minimal tweaking of a script or layout.

filetmignon
12-17-2008, 02:03 AM
That said, the script in question doesn't work with my IE 5. But there are so many errors on the demo page in IE 5 that it might not be the script itself, rather other code that is halting script processing.



The script itself does have a problem in IE 5.
I've tried the script on my own site by itself, and got it to work correctly with every other major browswer. But IE 5.01 gives error messages.

jscheuer1
12-17-2008, 04:05 AM
OK, you got me curious, so I just downloaded the install archive and tested it out. It appears that the problem with this script in IE 5 arose whenever it was updated to utilized addEventListener and attachEvent, the latter of which is supported by IE 5. However, in order to get the event and element passed to the attached function, the Function.prototype.call method was used for IE which otherwise would not recognise the target element as 'this' when assigning the event using attachEvent, and wouldn't easily accept event as a parameter to it. This works fine in IE 5.5 and up which support Function.prototype.call, but not in IE 5. So if we could find an older version of the script, before it was upgraded to use attachEvent, that could work. Otherwise, either a way of spoofing Function.prototype.call in IE 5 would need to be found, or the functions attached would need to be rewritten in a way that would work by direct assignment, ex:

el.onevent = function(){whatever;};

Doing it like that would make the 'this' keyword work without Function.prototype.call, but won't pass in the event in the same manner as the script currently is setup to do.

Line reference:

168 in chrome.js


target.attachEvent('on'+tasktype, function(){return functionref.call(target, window.event)});

jscheuer1
12-17-2008, 06:12 AM
I got it working. I was able to replace:


target.attachEvent('on'+tasktype, function(){return functionref.call(target, window.event)});

with:


target['on'+tasktype] = functionref;

for IE less than 5.5. But then it became apparent that the iframe shim thing wouldn't work with IE 5 either, so I added code to hide selects while menus were dropped down in that browser instead:


//** Chrome Drop Down Menu- Author: Dynamic Drive (http://www.dynamicdrive.com)

//** Updated: July 14th 06' to v2.0
//1) Ability to "left", "center", or "right" align the menu items easily, just by modifying the CSS property "text-align".
//2) Added an optional "swipe down" transitional effect for revealing the drop down menus.
//3) Support for multiple Chrome menus on the same page.

//** Updated: Nov 14th 06' to v2.01- added iframe shim technique

//** Updated: July 23rd, 08 to v2.4
//1) Main menu items now remain "selected" (CSS class "selected" applied) when user moves mouse into corresponding drop down menu.
//2) Adds ability to specify arbitrary HTML that gets added to the end of each menu item that carries a drop down menu (ie: a down arrow image).
//3) All event handlers added to the menu are now unobstrusive, allowing you to define your own "onmouseover" or "onclick" events on the menu items.
//4) Fixed elusive JS error in FF that sometimes occurs when mouse quickly moves between main menu items and drop down menus

//** Updated: Oct 29th, 08 to v2.5 (only .js file modified from v2.4)
//1) Added ability to customize reveal animation speed (# of steps)
//2) Menu now works in IE8 beta2 (a valid doctype at the top of the page is required)

var cssdropdown={
disappeardelay: 250, //set delay in miliseconds before menu disappears onmouseout
dropdownindicator: '<img src="down.gif" border="0" />', //specify full HTML to add to end of each menu item with a drop down menu
enablereveal: [true, 5], //enable swipe effect? [true/false, steps (Number of animation steps. Integer between 1-20. Smaller=faster)]
enableiframeshim: 1, //enable "iframe shim" in IE5.5 to IE7? (1=yes, 0=no)

//No need to edit beyond here////////////////////////

dropmenuobj: null, asscmenuitem: null, domsupport: document.all || document.getElementById, standardbody: null, iframeshimadded: false, revealtimers: {},

getposOffset:function(what, offsettype){
var totaloffset=(offsettype=="left")? what.offsetLeft : what.offsetTop;
var parentEl=what.offsetParent;
while (parentEl!=null){
totaloffset=(offsettype=="left")? totaloffset+parentEl.offsetLeft : totaloffset+parentEl.offsetTop;
parentEl=parentEl.offsetParent;
}
return totaloffset;
},

css:function(el, targetclass, action){
var needle=new RegExp("(^|\\s+)"+targetclass+"($|\\s+)", "ig")
if (action=="check")
return needle.test(el.className)
else if (action=="remove")
el.className=el.className.replace(needle, "")
else if (action=="add" && !needle.test(el.className))
el.className+=" "+targetclass
},

showmenu:function(dropmenu, e){
if (this.enablereveal[0]){
if (!dropmenu._trueheight || dropmenu._trueheight<10)
dropmenu._trueheight=dropmenu.offsetHeight
clearTimeout(this.revealtimers[dropmenu.id])
dropmenu.style.height=dropmenu._curheight=0
dropmenu.style.overflow="hidden"
dropmenu.style.visibility="visible"
this.revealtimers[dropmenu.id]=setInterval(function(){cssdropdown.revealmenu(dropmenu)}, 10)
}
else{
dropmenu.style.visibility="visible"
}
this.css(this.asscmenuitem, "selected", "add")
},

revealmenu:function(dropmenu, dir){
var curH=dropmenu._curheight, maxH=dropmenu._trueheight, steps=this.enablereveal[1]
if (curH<maxH){
var newH=Math.min(curH, maxH)
dropmenu.style.height=newH+"px"
dropmenu._curheight= newH + Math.round((maxH-newH)/steps) + 1
}
else{ //if done revealing menu
dropmenu.style.height="auto"
dropmenu.style.overflow="hidden"
clearInterval(this.revealtimers[dropmenu.id])
}
},

clearbrowseredge:function(obj, whichedge){
var edgeoffset=0
if (whichedge=="rightedge"){
var windowedge=document.all && !window.opera? this.standardbody.scrollLeft+this.standardbody.clientWidth-15 : window.pageXOffset+window.innerWidth-15
var dropmenuW=this.dropmenuobj.offsetWidth
if (windowedge-this.dropmenuobj.x < dropmenuW) //move menu to the left?
edgeoffset=dropmenuW-obj.offsetWidth
}
else{
var topedge=document.all && !window.opera? this.standardbody.scrollTop : window.pageYOffset
var windowedge=document.all && !window.opera? this.standardbody.scrollTop+this.standardbody.clientHeight-15 : window.pageYOffset+window.innerHeight-18
var dropmenuH=this.dropmenuobj._trueheight
if (windowedge-this.dropmenuobj.y < dropmenuH){ //move up?
edgeoffset=dropmenuH+obj.offsetHeight
if ((this.dropmenuobj.y-topedge)<dropmenuH) //up no good either?
edgeoffset=this.dropmenuobj.y+obj.offsetHeight-topedge
}
}
return edgeoffset
},

dropit:function(obj, e, dropmenuID){
if (this.dropmenuobj!=null) //hide previous menu
this.hidemenu() //hide menu
this.clearhidemenu()
this.dropmenuobj=document.getElementById(dropmenuID) //reference drop down menu
this.asscmenuitem=obj //reference associated menu item
this.showmenu(this.dropmenuobj, e)
this.dropmenuobj.x=this.getposOffset(obj, "left")
this.dropmenuobj.y=this.getposOffset(obj, "top")
this.dropmenuobj.style.left=this.dropmenuobj.x-this.clearbrowseredge(obj, "rightedge")+"px"
this.dropmenuobj.style.top=this.dropmenuobj.y-this.clearbrowseredge(obj, "bottomedge")+obj.offsetHeight+1+"px"
this.positionshim() //call iframe shim function
},

positionshim:function(){ //display iframe shim function
if (this.iframeshimadded){
if (this.dropmenuobj.style.visibility=="visible"){
this.shimobject.style.width=this.dropmenuobj.offsetWidth+"px"
this.shimobject.style.height=this.dropmenuobj._trueheight+"px"
this.shimobject.style.left=parseInt(this.dropmenuobj.style.left)+"px"
this.shimobject.style.top=parseInt(this.dropmenuobj.style.top)+"px"
this.shimobject.style.display="block"
}
} else if (this.enableiframeshim && this.ie5){
for (var i = document.all.tags('select').length - 1; i > -1; --i)
document.all.tags('select')[i].style.visibility = 'hidden';
}
},

hideshim:function(){
if (this.iframeshimadded)
this.shimobject.style.display='none'
else if (this.enableiframeshim && this.ie5){
for (var i = document.all.tags('select').length - 1; i > -1; --i)
document.all.tags('select')[i].style.visibility = '';
}
},

isContained:function(m, e){
var e=window.event || e
var c=e.relatedTarget || ((e.type=="mouseover")? e.fromElement : e.toElement)
while (c && c!=m)try {c=c.parentNode} catch(e){c=m}
if (c==m)
return true
else
return false
},

dynamichide:function(m, e){
if (!this.isContained(m, e)){
this.delayhidemenu()
}
},

delayhidemenu:function(){
this.delayhide=setTimeout("cssdropdown.hidemenu()", this.disappeardelay) //hide menu
},

hidemenu:function(){
this.css(this.asscmenuitem, "selected", "remove")
this.dropmenuobj.style.visibility='hidden'
this.dropmenuobj.style.left=this.dropmenuobj.style.top="-1000px"
this.hideshim()
},

clearhidemenu:function(){
if (this.delayhide!="undefined")
clearTimeout(this.delayhide)
},

addEvent:function(target, functionref, tasktype){
if (target.addEventListener)
target.addEventListener(tasktype, functionref, false);
else if (target.attachEvent){
this.ie5 = false;
/*@cc_on @*/
/*@if(@_jscript_version >= 5)
if(navigator.appVersion.replace(/^.*MSIE (\d+\.\d+).*$/, '$1') >= 5.5)
target.attachEvent('on'+tasktype, function(){return functionref.call(target, window.event)});
else {
target['on'+tasktype] = functionref;
this.ie5 = true;
}
@end @*/
}
},

startchrome:function(){
if (!this.domsupport)
return
this.standardbody=(document.compatMode=="CSS1Compat")? document.documentElement : document.body
for (var ids=0; ids<arguments.length; ids++){
var menuitems=document.getElementById(arguments[ids]).getElementsByTagName("a")
for (var i=0; i<menuitems.length; i++){
if (menuitems[i].getAttribute("rel")){
var relvalue=menuitems[i].getAttribute("rel")
var asscdropdownmenu=document.getElementById(relvalue)
this.addEvent(asscdropdownmenu, function(){cssdropdown.clearhidemenu()}, "mouseover")
this.addEvent(asscdropdownmenu, function(e){cssdropdown.dynamichide(this, e)}, "mouseout")
this.addEvent(asscdropdownmenu, function(){cssdropdown.delayhidemenu()}, "click")
try{
menuitems[i].innerHTML=menuitems[i].innerHTML+" "+this.dropdownindicator
}catch(e){}
this.addEvent(menuitems[i], function(e){ //show drop down menu when main menu items are mouse over-ed
if (!cssdropdown.isContained(this, e)){
var evtobj=window.event || e
cssdropdown.dropit(this, evtobj, this.getAttribute("rel"))
}
}, "mouseover")
this.addEvent(menuitems[i], function(e){cssdropdown.dynamichide(this, e)}, "mouseout") //hide drop down menu when main menu items are mouse out
this.addEvent(menuitems[i], function(){cssdropdown.delayhidemenu()}, "click") //hide drop down menu when main menu items are clicked on
}
} //end inner for
} //end outer for
if (!this.ie5 && this.enableiframeshim && document.all && !window.XDomainRequest && !this.iframeshimadded){ //enable iframe shim in IE5.5 thru IE7?
document.write('<IFRAME id="iframeshim" src="about:blank" frameBorder="0" scrolling="no" style="left:0; top:0; position:absolute; display:none;z-index:90; background: transparent;"></IFRAME>')
this.shimobject=document.getElementById("iframeshim") //reference iframe object
this.shimobject.style.filter='progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)'
this.iframeshimadded=true
}
} //end startchrome

}