Cycle Plugin - Dynamically Overlaying Prev/Next Links
I believe my question boils down to overlaying a "position: absolute;" div that is inside a "position: relative;" div in IE, but I'll give the whole context.
Inside a "position:absolute;" div are <div>s, <a>s, and <img>s that float previous/next links over a rotating image slideshow that is done using the jQuery Cycle plugin (
http://malsup.com/jquery/cycle/.
Here's a link to the whole thing (all resources are absolute URLs so you can download/open in browser):
http://www.mediafire.com/?myaywy1ndyz
I'm using jQuery to dynamically create and overlay the wrapper divs, links, and images, so that this kind of slideshow can easily be created (maybe the people over at Cycle can improve/clean-up and adapt into their library!).
Here's my JavaScript function that does the jQuery magic:
-
function cycleHoverNav(slideshowSelector, navWrapperId, prevImg, nextImg, cycleProperties) {
var slideshowElement = $(slideshowSelector);
// create navWrapper
var wrapper = $('<div></div>');
wrapper.attr('id', navWrapperId);
// clone slideshow element CSS
wrapper.attr('class', slideshowElement.attr('class'));
wrapper.attr('style', slideshowElement.attr('style'));
// clear positional CSS (invisible wrapper)
wrapper.css({ 'padding': '0px',
'margin': '0px',
'background-color': 'transparent',
'border': 'none',
'position': 'relative',
'height': slideshowElement.css('height'),
'width': slideshowElement.css('width'),
'z-index': (isNaN(parseInt(slideshowElement.css('z-index'))) ? '100' : parseInt(wrapper.css('z-index')) + 100 )});
// wrap slideshow element
slideshowElement.wrap(wrapper);
// append prev/next links inside wrapper (after slideshow)
slideshowElement.after('<div></div>' +
'<div id="navLinkWrapper">' +
'<div class="cycleNavDiv" id="cyclePrevDiv"><a href="#" class="cycleNavLink" id="cyclePrevLink"><img src="' + prevImg + '" border="0" /></a></div>' +
'<div class="cycleNavDiv" id="cycleNextDiv"><a href="#" class="cycleNavLink" id="cycleNextLink"><img src="' + nextImg + '" border="0" /></a></div>' +
'</div>');
// selector strings
var navWrapperIdSelector = '#' + navWrapperId;
var navLinkWrapperSelector = navWrapperIdSelector + ' ' + '#navLinkWrapper';
var prevNextLinkSelector = navWrapperIdSelector + ' a.cycleNavLink';
var prevLinkSelector = navWrapperIdSelector + ' a#cyclePrevLink';
var nextLinkSelector = navWrapperIdSelector + ' a#cycleNextLink';
var prevNextDivSelector = navWrapperIdSelector + ' div.cycleNavDiv';
var prevDivSelector = navWrapperIdSelector + ' div#cyclePrevDiv';
var nextDivSelector = navWrapperIdSelector + ' div#cycleNextDiv';
var prevNextImgSelector = prevNextDivSelector + ' img';
var prevImgSelector = prevDivSelector + ' img';
var nextImgSelector = nextDivSelector + ' img';
// navLinkWrapper style
$(navLinkWrapperSelector).css({ 'width': wrapper.css('width'),
'height': wrapper.css('height'),
'position': 'absolute',
'top': '0pt',
'left': '0pt',
'z-index': (isNaN(parseInt(wrapper.css('z-index'))) ? '200' : parseInt(wrapper.css('z-index')) + 200 )});
// prev/next link styles
$(prevNextLinkSelector).css({'width': '100%',
'height': $(navLinkWrapperSelector).css('height'),
'position': 'relative',
'display': 'none',
'padding': '0px 0px 0px 0'});
$(prevNextLinkSelector).focus(function() { $(prevNextLinkSelector).css({ 'outline': 'none',
'outline-width': '0px' }) });
// prev link style
$(prevLinkSelector).css({'float': 'left'});
// next link style
$(nextLinkSelector).css({'float': 'right'});
// prev/next div styles
$(prevNextDivSelector).css({'position': 'relative',
'width': '48%',
'height': $(navLinkWrapperSelector).css('height'),
'display': 'block'});
$(prevDivSelector).css({'float': 'left'});
$(nextDivSelector).css({'float': 'right'});
// prev/next img styles
$(prevNextImgSelector).css({'margin-bottom': '0px',
'margin-top': '80%',
'background-color':
'transparent',
'border': 'none',
'padding': '0px'});
// prev img style
$(prevImgSelector).css({'margin-left': '15%', 'margin-right': '0px'});
$(prevImgSelector).attr('align', 'left');
// next img style
$(nextImgSelector).css({'margin-left': '0px', 'margin-right': '15%'});
$(nextImgSelector).attr('align', 'right');
$(navWrapperIdSelector).mouseover(function() { $(slideshowSelector).cycle('pause'); });
$(navWrapperIdSelector).mouseout(function() { $(slideshowSelector).cycle('resume'); });
// add prev/next mouse events
$(prevDivSelector).mouseover(function() { $(prevLinkSelector).show(); });
$(prevDivSelector).mouseout(function() { $(prevLinkSelector).hide(); });
$(nextDivSelector).mouseover(function() { $(nextLinkSelector).show(); });
$(nextDivSelector).mouseout(function() { $(nextLinkSelector).hide(); });
// add cycle prev next properties
cycleProperties['prev'] = prevLinkSelector;
cycleProperties['next'] = nextLinkSelector;
// load cycle slideshow
$(slideshowSelector).cycle(cycleProperties);
}
What it generates is essentially:
-
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<title>JQuery Cycle Plugin - Example Slideshow</title>
<style type="text/css">
.slideshow { height: 232px; width: 232px; margin: auto; overflow: hidden; zoom: 1; }
.slideshow img { padding: 15px; border: 1px solid #ccc; background-color: #eee; }
</style>
<!--[if lte IE 7]>
<style type="text/css">
div, ul { zoom: 1; }
</style>
<![endif]-->
<!-- include jQuery library -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<!-- include Cycle plugin -->
<script type="text/javascript" src="http://cloud.github.com/downloads/malsup/cycle/jquery.cycle.all.2.73.js"></script>
[MY cycleHoverNav() JS FUNCTION HERE]
$(document).ready(function() { cycleHoverNav('#cycleDiv',
'cycleNavWrapper',
'http://i49.tinypic.com/1zlrbc2.png',
'http://i49.tinypic.com/34440mx.png',
{ fx: 'fade'}
) });
</script>
</head>
<body>
<center>
<div id="cycleNavWrapper" class="slideshow" style="border: medium none ; margin: 0px; padding: 0px; background-color: transparent; position: relative; height: 232px; width: 232px; z-index: 100;">
<div class="slideshow" id="cycleDiv" style="position: relative;">
<img width="200" height="200" src="http://cloud.github.com/downloads/malsup/cycle/beach1.jpg" />
<img width="200" height="200" src="http://cloud.github.com/downloads/malsup/cycle/beach2.jpg" />
<img width="200" height="200" src="http://cloud.github.com/downloads/malsup/cycle/beach3.jpg" />
<img width="200" height="200" src="http://cloud.github.com/downloads/malsup/cycle/beach4.jpg" />
<img width="200" height="200" src="http://cloud.github.com/downloads/malsup/cycle/beach5.jpg" />
</div>
<div/>
<div id="navLinkWrapper" style="width: 232px; height: 232px; position: absolute; top: 0pt; left: 0pt; z-index: 300;">
<div id="cyclePrevDiv" class="cycleNavDiv" style="position: relative; width: 48%; height: 232px; display: block; float: left;">
<a id="cyclePrevLink" class="cycleNavLink" href="#" style="padding: 0px 0px 0px 0pt; width: 100%; height: 232px; position: relative; float: left; display: none; outline-color: -moz-use-text-color; outline-style: none; outline-width: 0px;">
<img border="0" align="left" src="http://i49.tinypic.com/1zlrbc2.png" style="border: medium none ; margin: 80% 0px 0px 15%; padding: 0px; background-color: transparent;"/>
</a>
</div>
<div id="cycleNextDiv" class="cycleNavDiv" style="position: relative; width: 48%; height: 232px; display: block; float: right;">
<a id="cycleNextLink" class="cycleNavLink" href="#" style="padding: 0px 0px 0px 0pt; width: 100%; height: 232px; position: relative; float: right; display: none; outline-color: -moz-use-text-color; outline-style: none; outline-width: 0px;">
<img border="0" align="right" src="http://i49.tinypic.com/34440mx.png" style="border: medium none ; margin: 80% 15% 0px 0px; padding: 0px; background-color: transparent;"/>
</a>
</div>
</div>
</div>
</center>
</body>
</html>
... note that despite it not being shown here, jQuery has attached show()/hide() functions to the mouseover()/mouseout() events for the "cyclePrevDiv" and "cycleNextDiv" divs. Hovering over these divs causes the child "cyclePrevLink"/"cycleNextLink" to become visible and visa versa (again, see link above to whole thing to run it and see it in action).
This works great in FF and I can see (using the IE developer toolbar) that the divs/links/images are all positioned correctly in IE 7 & 8 (don't care about IE 6).
However with IE, there are two problems:
- Hovering over the "cyclePrevDiv"/"cycleNextDiv" divs doesn't cause anything to appear. If I throw in an "alert()" command into the mouseover()/mouseout() jQuery event handlers I can see that the event is being fired.
- If I manually set the "cyclePrevLink"/"cycleNextLink" links to be visible the link is only active over the image inside the link and not the dimensions specified by the link's CSS properties.
Any thoughts?