PDA

View Full Version : Image Maps and Drop Down Menu - compatability issues (FF/IE)



pmzine
05-22-2006, 02:21 PM
AnyLink Drop Down Menu
http://www.dynamicdrive.com/dynamicindex1/dropmenuindex.htm

I'm attempting to use the above script to implement two dropdown menus on my site. It seems to be working well with IE after a bit of adjusting the positions. In Firefox though it displays the two individual menus at the same position on the page, and even that position isn't ideal as I'd like them under the link heading. Here is the page I'm refering to:

http://www.pmzine.co.uk/Updates/reviews.php

The two menus appear when hovering over 'Reviews' and 'Info'. Could anyone offer help as to how I could get it working effectively in both browsers? Or, if not, offer any recommendations for similar scripts that work better with both browsers.

Thanks! :)

P.S. please ignore the any other non-working features, it's very much a work in progress.

jscheuer1
05-22-2006, 06:35 PM
For image maps to work well with this script cross browser, an entirely different method of determining the position for the drop downs must be added. I've done this before. So, working from the original script -

This only works with rect shaped area tags and the image map must immediately follow the image that uses it and be in the same container. The main change is to get the actual position of the image map's area tag. To do that, replace:


function getposOffset(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;
}

with:


function getposOffset(what, offsettype){
if (what.parentNode&&typeof what.parentNode.tagName!=='undefined'&&what.parentNode.tagName.toLowerCase()=='map'){
mapflag=1;
var ocoords=what.coords.split(',')
var totaloffset=(offsettype=="left")? ocoords[0]*1 : ocoords[3]*1;
var mapIm=what.parentNode.parentNode.getElementsByTagName('img')
for (var i_tem = 0; i_tem < mapIm.length; i_tem++)
if (mapIm[i_tem].getAttribute('usemap', 0)&&mapIm[i_tem].getAttribute('usemap', 0).replace(/^.*(#.*)/g,'$1')=='#'+what.parentNode.name)
var parentEl=mapIm[i_tem];
}
else {
mapflag=0;
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;
}

A little more tweaking and a variable need to be added, in the variable declarations, add this (in red):


/////No further editting needed

var ie4=document.all
var ns6=document.getElementById&&!document.all
var mapflag=0

Finally the tweak, find this line:


dropmenuobj.style.top=dropmenuobj.y-clearbrowseredge(obj, "bottomedge")+obj.offsetHeight+10+"px"

Change it to this:


var oHeight=mapflag? obj.offsetHeight+10 : obj.offsetHeight+46
dropmenuobj.style.top=dropmenuobj.y-clearbrowseredge(obj, "bottomedge")+oHeight+"px"

That red 46 may need to be adjusted for your map.

pmzine
05-23-2006, 12:02 AM
Thanks for the reply, you certainly know your stuff!

The adjustments you offered fixed the horizontal position perfectly, the menu's now appear successfully under each heading (thanks!). Sadly the verticle position is still converted differently under the two browsers, if I position the dropdowns in the correct position in FireFox they appear too high up the page in IE. Or vice-versa, if I position them correctly in IE, they appear too low down the page in Firefox. Is there any fix for this? I've had a mess with certain positioning numbers using a trial and error method to no avail.

jscheuer1
05-23-2006, 04:38 AM
I may know my stuff but, I was in a rush and gave you the wrong tweak lines. I gave you:


var oHeight=mapflag? obj.offsetHeight+10 : obj.offsetHeight+46
dropmenuobj.style.top=dropmenuobj.y-clearbrowseredge(obj, "bottomedge")+oHeight+"px"

They actually should be:


var oHeight=mapflag? 0 : obj.offsetHeight+46
dropmenuobj.style.top=dropmenuobj.y-clearbrowseredge(obj, "bottomedge")+oHeight+"px"

And, I was also in error as it is the 0 that can be adjusted for the image map but, in your case, no adjustment should be needed.

I notice that you have, just above where the tweaks go:


dropmenuobj.style.left=dropmenuobj.x-clearbrowseredge(obj, "rightedge")+10+"px"

That +10 was added by you. I like -1 for that value and the original script has no added or subtracted value there. In any case, that only affects the horizontal positioning.

Just to be as clear as possible, here is the entire script from the 'No further editing needed' on down that I have working here for your page in FF, IE and Opera:


/////No further editing needed

var ie4=document.all
var ns6=document.getElementById&&!document.all
var mapflag=0

if (ie4||ns6)
document.write('<div id="dropmenudiv" style="visibility:hidden;width:'+menuwidth+';background-color:'+menubgcolor+'" onMouseover="clearhidemenu()" onMouseout="dynamichide(event)"></div>')

function getposOffset(what, offsettype){
if (what.parentNode&&typeof what.parentNode.tagName!=='undefined'&&what.parentNode.tagName.toLowerCase()=='map'){
mapflag=1;
var ocoords=what.coords.split(',')
var totaloffset=(offsettype=="left")? ocoords[0]*1 : ocoords[3]*1;
var mapIm=what.parentNode.parentNode.getElementsByTagName('img')
for (var i_tem = 0; i_tem < mapIm.length; i_tem++)
if (mapIm[i_tem].getAttribute('usemap', 0)&&mapIm[i_tem].getAttribute('usemap', 0).replace(/^.*(#.*)/g,'$1')=='#'+what.parentNode.name)
var parentEl=mapIm[i_tem];
}
else {
mapflag=0;
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;
}


function showhide(obj, e, visible, hidden, menuwidth){
if (ie4||ns6)
dropmenuobj.style.left=dropmenuobj.style.top=-500
if (menuwidth!=""){
dropmenuobj.widthobj=dropmenuobj.style
dropmenuobj.widthobj.width=menuwidth
}
if (e.type=="click" && obj.visibility==hidden || e.type=="mouseover")
obj.visibility=visible
else if (e.type=="click")
obj.visibility=hidden
}

function iecompattest(){
return (document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body
}

function clearbrowseredge(obj, whichedge){
var edgeoffset=0
if (whichedge=="rightedge"){
var windowedge=ie4 && !window.opera? iecompattest().scrollLeft+iecompattest().clientWidth-15 : window.pageXOffset+window.innerWidth-15
dropmenuobj.contentmeasure=dropmenuobj.offsetWidth
if (windowedge-dropmenuobj.x < dropmenuobj.contentmeasure)
edgeoffset=dropmenuobj.contentmeasure-obj.offsetWidth
}
else{
var topedge=ie4 && !window.opera? iecompattest().scrollTop : window.pageYOffset
var windowedge=ie4 && !window.opera? iecompattest().scrollTop+iecompattest().clientHeight-15 : window.pageYOffset+window.innerHeight-18
dropmenuobj.contentmeasure=dropmenuobj.offsetHeight
if (windowedge-dropmenuobj.y < dropmenuobj.contentmeasure){ //move up?
edgeoffset=dropmenuobj.contentmeasure+obj.offsetHeight
if ((dropmenuobj.y-topedge)<dropmenuobj.contentmeasure) //up no good either?
edgeoffset=dropmenuobj.y+obj.offsetHeight-topedge
}
}
return edgeoffset
}

function populatemenu(what){
if (ie4||ns6)
dropmenuobj.innerHTML=what.join("")
}


function dropdownmenu(obj, e, menucontents, menuwidth){
if (window.event) event.cancelBubble=true
else if (e.stopPropagation) e.stopPropagation()
clearhidemenu()
dropmenuobj=document.getElementById? document.getElementById("dropmenudiv") : dropmenudiv
populatemenu(menucontents)

if (ie4||ns6){
showhide(dropmenuobj.style, e, "visible", "hidden", menuwidth)
dropmenuobj.x=getposOffset(obj, "left")
dropmenuobj.y=getposOffset(obj, "top")
dropmenuobj.style.left=dropmenuobj.x-clearbrowseredge(obj, "rightedge")-1+"px"
var oHeight=mapflag? 0 : obj.offsetHeight+46
dropmenuobj.style.top=dropmenuobj.y-clearbrowseredge(obj, "bottomedge")+oHeight+"px"
}

return clickreturnvalue()
}

function clickreturnvalue(){
if (ie4||ns6) return false
else return true
}

function contains_ns6(a, b) {
while (b.parentNode)
if ((b = b.parentNode) == a)
return true;
return false;
}

function dynamichide(e){
if (ie4&&!dropmenuobj.contains(e.toElement))
delayhidemenu()
else if (ns6&&e.currentTarget!= e.relatedTarget&& !contains_ns6(e.currentTarget, e.relatedTarget))
delayhidemenu()
}

function hidemenu(e){
if (typeof dropmenuobj!="undefined"){
if (ie4||ns6)
dropmenuobj.style.visibility="hidden"
}
}

function delayhidemenu(){
if (ie4||ns6)
delayhide=setTimeout("hidemenu()",disappeardelay)
}

function clearhidemenu(){
if (typeof delayhide!="undefined")
clearTimeout(delayhide)
}

if (hidemenu_onclick=="yes")
document.onclick=hidemenu

</script>

pmzine
05-23-2006, 11:21 AM
That works a treat, I cannot thank you enough :D

It's great to see scripts so strongly supported by it's community.