View Finished Example
One of the most frequent questions raised is how to have elements over the top of active content such as flash or select boxes. There are a few implementations of this on the internet, but none quite fit all my needs as they either weren't a cross browser solution or didn't handle flash very well. So let's deal with each problem in turn.
Flash has a parameter called wmode that can be used to allow it to stack elements over the top of it. Most frequently the wmode=”transparent” which not only allows us to stack elements but also makes the background of the flash movie transparent. In a lot of situations this is ok, but sometimes we may not want our flash movie to be transparent. To work around this, we can use the wmode=”opaque” parameter. This will give the flash movie a stacking order. Some simple code that you can use as a base to work of is below:
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0" width="500" height="300">
<param name="movie" value="matrix.swf" />
<param name="quality" value="high" />
<param name="wmode" value="opaque" />
<embed src="matrix.swf" width="500" height="300" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" wmode="opaque"></embed>
</object>
This will work quite well on most modern browsers, including Mozilla based browsers and Internet Explorer.
Opera 7 however does not support the wmode parameter so we need to find a different way to handle Opera. What we can do for Opera is dynamically resize the movie to fit. In order to do this we need to place the flash object and embed tags within a layer like so;
<div id="flashLYR" style="position:absolute; width:200px; height:115px; z-index:11; left: 438px; top: 17px;">
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0" width="500" height="300">
<param name="movie" value="matrix.swf" />
<param name="quality" value="high" />
<param name="wmode" value="opaque" />
<embed src="matrix.swf" width="500" height="300" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" wmode="opaque"></embed>
</object>
</div>
We do this for a number of reasons, but the main one is we want to overwrite the object and embed tag contained within the layer dynamically so we gain some control over its height and width values. The other advantage is if the user has JavaScript turned off, then the original movie will be shown, it just won't have the ability to be resized dynamically.
To dynamically write a flash movie to a layer we can use this function:
function loadFlash(id,theurl,width,height) {
document.getElementById(id).innerHTML ='<embed src="'+ theurl + '" width="'+ width + '" height="'+ height + '" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" scale="exactfit" /><\/embed>';
}
The loadFlash function has four parameters that will need to be defined later on a mouse event. These parameters are:
- id = The id value of the layer in which the flash movie is contained.
- theurl = the src value of where the movie resides.
- width = the width of the movie.
- height = the height of the movie.
So let us assume that our original movies width and height are 500 * 300 respectively and we want to resize the height value down so that another element is completely visible. We would call the loadFlash function like so;
onmouseover = “loadFlash('flashLYR','matrix.swf',500,161)”
To resize the movie back to its original size we would use this;
onmouseout =”loadFlash('flashLYR','matrix.swf',500,161)”
Now you have a solution that works on all major modern browsers. All we will need to do is condition the function to trigger for only opera. For example we could use some simple functions like so;
function sizedownMatrix() {
if (window.opera) {
loadFlash('flashLYR','matrix.swf',500,161)”
}
}
function sizeupMatrix() {
if (window.opera) {
loadFlash('flashLYR','matrix.swf',500,300)”
}
}
And then just call those functions with mouse events:
onmouseover="sizedownMatrix()"
onmouseout = "sizeupMatrix()"
Thats it for the flash side of things lets move on to other elements.
When dealing with select lists, the main problem browser is Internet Explorer. For Internet Explorer we can create an IFrame element which then gives us a windowed control that we can place between active content and other elements. In order to do this we can dynamically create an IFrame that will automatically adjust itself to be placed between active content and other elements;
function activecontentHider(id) {
if (ie) {
el = document.getElementById(id);
ifrm = document.createElement("IFRAME");
ifrm.setAttribute("id", "dummyFRM");
ifrm.setAttribute("src", "#");
ifrm.setAttribute("scroll", "no");
ifrm.setAttribute("frameborder", "0");
ifrm.style.setAttribute("position", "absolute");
ifrm.style.setAttribute("visibility", "hidden");
ifrm.style.filter='Alpha(opacity=0)';
ifrm.style.width = el.offsetWidth + "px";
ifrm.style.height = el.offsetHeight + "px";
ifrm.style.left = el.offsetLeft + "px";
ifrm.style.top = el.offsetTop + "px";
ifrm.style.zIndex = el.style.zIndex-1;
document.body.appendChild(ifrm);
}
}
The above function does a number of things. First it creates an iframe element and appends it to document body. We can set the iframe's attributes by using the W3C DOM method of setAttribute. You will notice in the above code that a number of the iframes attributes are set in this manner.
The other important thing we want our function to do, is to find the element that we want to be placed over the active content, and resize and reposition our iframe accordingly. For example;
ifrm.style.width = el.offsetWidth + "px";
ifrm.style.width = el.offsetHeight + "px";
This statement sets the IFrame element's width and height to match an elements width and height. All that happens here is we capture an elements dimension with offsetWidth and offsetHeight and use those values to set the IFrame's width and height.
Exactly the same procedure is used for the IFrame's top and left value, only we use offsetTop and offsetLeft respectively.
ifrm.style.left = el.offsetLeft + "px";
ifrm.style.top = el.offsetTop + "px";
Then all we have to do is target an element id attribute for example assuming we have a div element with an id attribute of testLYR then we would call it like so;
<body onload="activecontentHider('testLYR')">
The script takes care of the rest for us.
Hope you enjoyed this tutorial on elements, stacking order and active content.
Download Example Here