PDA

View Full Version : DHTML Menu over PDF window



transit
05-13-2009, 12:51 PM
1) Script Title: Smooth Menu

2) Script URL (on DD): http://www.dynamicdrive.com/dynamicindex1/ddsmoothmenu.htm

3) Describe problem: We plan to use the smooth menu for a website we're making, but we've run into a problem in the form of the Acrobat Reader. DHTML menus won't display over the piece of crap plug-in that is Acrobat reader.

So, we've resorted to using IFrame shim to make sure the menu show. Currently, after stripping the animation and shadows from the smooth menu, it only works correctly in IE, the shim size is wrong in Chrome, firefox either works or not, depending of the location of the menu in the markup (can't figure out why) and nothing works in Opera.

The following code is where I'm currently stucked. I must admit that my javascript is very rusty and my knowledge of cross-browser compatibility is limited. So, if anyone has any idea on how to improve / make it fully functional, I'd appreciate the help before I go totally insane!

Claude




var iFrame = null;
var SKIP = "SkipLeftOffset"
var SKIPNOTOP = "SkipLeftOffsetAndTopOffset"

var ddsmoothmenu = {

//Specify full URL to down and right arrow images (23 is padding-right added to top level LIs with drop downs):
arrowimages: { down: ['downarrowclass', 'down.gif', 23], right: ['rightarrowclass', 'right.gif'] },

transition: { overtime: 0, outtime: 0 }, //duration of slide in/ out animation, in milliseconds
shadow: { enabled: false, offsetx: 5, offsety: 5 },

///////Stop configuring beyond here///////////////////////////

detectwebkit: navigator.userAgent.toLowerCase().indexOf("applewebkit") != -1, //detect WebKit browsers (Safari, Chrome etc)
detectie6: document.all && !window.XMLHttpRequest,

getajaxmenu: function($, setting) { //function to fetch external page containing the panel DIVs
var $menucontainer = $('#' + setting.contentsource[0]) //reference empty div on page that will hold menu
$menucontainer.html("Loading Menu...")
$.ajax({
url: setting.contentsource[1], //path to external menu file
async: true,
error: function(ajaxrequest) {
$menucontainer.html('Error fetching content. Server Response: ' + ajaxrequest.responseText)
},
success: function(content) {
$menucontainer.html(content)
ddsmoothmenu.buildmenu($, setting)
}
})
},


buildmenu: function($, setting) {
var smoothmenu = ddsmoothmenu
var $mainmenu = $("#" + setting.mainmenuid + ">ul") //reference main menu UL
$mainmenu.parent().get(0).className = setting.classname || "ddsmoothmenu"
var $headers = $mainmenu.find("ul").parent()

$headers.hover(function(e) { $(this).children('a:eq(0)').addClass('selected') }, function(e) { $(this).children('a:eq(0)').removeClass('selected') })

$headers.each(function(i) { //loop through each LI header
var $curobj = $(this).css({ zIndex: 20000 - i }) //reference current LI header
var $subul = $(this).find('ul:eq(0)').css({ display: 'block' })
this._dimensions = { w: this.offsetWidth, h: this.offsetHeight, subulw: $subul.outerWidth(), subulh: $subul.outerHeight() }

this.istopheader = $curobj.parents("ul").length == 1 ? true : false //is top level header?
$subul.css({ top: this.istopheader && setting.orientation != 'v' ? this._dimensions.h + "px" : 0 })
$curobj.children("a:eq(0)").css(this.istopheader ? { paddingRight: smoothmenu.arrowimages.down[2]} : {}).append( //add arrow images
'<img src="' + (this.istopheader && setting.orientation != 'v' ? smoothmenu.arrowimages.down[1] : smoothmenu.arrowimages.right[1])
+ '" class="' + (this.istopheader && setting.orientation != 'v' ? smoothmenu.arrowimages.down[0] : smoothmenu.arrowimages.right[0])
+ '" style="border:0;" />'

)
$curobj.hover(
function(e) {
var $targetul = $(this).children("ul:eq(0)")
this._offsets = { left: $(this).offset().left, top: $(this).offset().top }
var menuleft = this.istopheader && setting.orientation != 'v' ? 0 : this._dimensions.w
menuleft = (this._offsets.left + menuleft + this._dimensions.subulw > $(window).width()) ? (this.istopheader && setting.orientation != 'v' ? -this._dimensions.subulw + this._dimensions.w : -this._dimensions.w) : menuleft //calculate this sub menu's offsets from its parent
$targetul.css({ left: menuleft + "px", width: this._dimensions.subulw + 'px' })
$targetul.css({ display: 'block' })

var $block = $(this).children("ul")

for (i = 0; i < $block[0].children.length; i = i + 1) {
var $leftOff = getLeftOffset($block[0].children[i]);
var $topOff = getTopOffset($block[0].children[i]);

iFrameMenu($block[0].children[i].id, $leftOff, $topOff, $block[0].children[i].offsetWidth, $block[0].children[i].offsetHeight)
}
},
function(e) {
var $targetul = $(this).children("ul:eq(0)")
$targetul.css({ 'display': 'none', 'visibility': 'visible' })

var $block = $(this).children("ul")
for (i = 0; i < $block[0].children.length; i = i + 1)
hideIFrameMenu($block[0].children[i].id);
}
) //end hover
}) //end $headers.each()
$mainmenu.find("ul").css({ 'display': 'none', 'visibility': 'visible' })
},

init: function(setting) {
if (typeof setting.customtheme == "object" && setting.customtheme.length == 2) { //override default menu colors (default/hover) with custom set?
var mainmenuid = '#' + setting.mainmenuid
var mainselector = (setting.orientation == "v") ? mainmenuid : mainmenuid + ', ' + mainmenuid
document.write('<style type="text/css">\n'
+ mainselector + ' ul li a {background:' + setting.customtheme[0] + ';}\n'
+ mainmenuid + ' ul li a:hover {background:' + setting.customtheme[1] + ';}\n'
+ '</style>')
}
this.shadow.enabled = false
jQuery(document).ready(function($) { //ajax menu?
if (typeof setting.contentsource == "object") { //if external ajax menu
ddsmoothmenu.getajaxmenu($, setting)
}
else { //else if markup menu
ddsmoothmenu.buildmenu($, setting)
}
})
}

}


// Created a iFrame because I want the menu pass over
// a SELECT or/and a IFRAME when the menu is used.
function iFrameMenu(menu, left, top, width, height) {

// Verified if the iFrame has been created.
var iFrameExist = document.getElementById("IFRAME" + menu);

if (!iFrameExist) { //Create the iframe
iFrame = document.createElement("IFRAME");
iFrame.id = "IFRAME" + menu;
iFrame.style.zindex = "1100";
iFrame.frameBorder = "no";
iFrame.scrolling = "no";
iFrame.style.filter = "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
iFrame.style.visibility = 'visible';
iFrame.style.display = "";
iFrame.style.position = "absolute";
iFrame.src = 'javascript:new String("<html></html>")';
iFrame.style.left = left + "px";
iFrame.style.top = top + "px";
iFrame.style.width = width;
iFrame.style.height = height;
var e = document.body.firstChild;
document.body.insertBefore(iFrame, e);
}
else { //If has already created, just changes these properties.
menu.iFrame.style.visibility = "visible";
menu.iFrame.style.display = "block";
}
}

// Hide the iFrame created by the JavaScript.
function hideIFrameMenu(menuId) {
var ifr = document.getElementById('IFRAME' + menuId);
if (ifr != null)
ifr.parentNode.removeChild(ifr);
}


//------------------------------------------------------------------
// Returns the x (Left) offset of the OffsetObj object relative to
// the main window.
function getLeftOffset(OffsetObj) {
var x;
var str;
var isThere;

str = OffsetObj.id;
skipIsThere = str.indexOf(SKIP);

//Verify if the string 'SkipLeftOffset' is in the ID. If yes, I don't
// have to calculated it in the getLeftOffset sum.
if (skipIsThere > -1)
x = 0;
else
x = OffsetObj.offsetLeft;

if (OffsetObj.offsetParent != null) {
x += getLeftOffset(OffsetObj.offsetParent);
}
return x;
}

//------------------------------------------------------------------
// Returns the y (Top) offset of the OffsetObj object relative to
// the main window.
function getTopOffset(OffsetObj) {
var y;
var str;
var isThere;

str = OffsetObj.id
skipIsThere = str.indexOf(SKIPNOTOP)

// Verify if the string 'SkipLeftOffsetAndTopOffset' is in the ID.
// If yes, We don't have to calculated it in the getTopOffset sum.
if (skipIsThere > -1)
y = 0;
else
y = OffsetObj.offsetTop;

if (OffsetObj.offsetParent != null)
y += getTopOffset(OffsetObj.offsetParent);
return y;
}

transit
05-13-2009, 02:00 PM
Just a quick update, it seems that Firefox is not generating the IFrame shims for some reason. Here's the error I get from the error console, unfortunately, I've got no idea on how to fix that one, afer all, I've been using JQuery for only a whole day...

Error: $block[0].children is undefined
Source File: http://localhost/WWzFTP/smooth/ddsmoothmenu.js
Line: 79

transit
05-13-2009, 05:47 PM
Managed to work all the kinks out. It works in all browsers save Opera... I've attached my final code.

pkirankmr
07-21-2009, 06:59 PM
The modified JS file does not work for me.

iframe.style is null or not an object is the error i get

any help on this