...

View Full Version : Parent DIV z-index on mouseover



gyzhor
08-19-2011, 07:15 PM
I have three images nested in three divs that I want to change size on mouseover, but since they're each in their own div, I can't effect their z-indexes relative to one another without targeting their parent divs.
I thought I'd be able to contain the images in an <a> tag with z-index style in a mouseover, but I can get it to work. What am I doing wrong here?

CSS:

.thumb img{
height: 75px;
}
.thumb img:hover{
height: 150px;
}

JS:

function thmbOver(){
this.style.zIndex = "1000";
}

HTML:

<div id="div1"><a onmouseover='thmbOver();'><span class='thumb'><img src='thmbs/image1.jpg'></span></a></div>

<div id="div2"><a onmouseover='thmbOver();'><span class='thumb'><img src='thmbs/image2.jpg'></span></a></div>

<div id="div3"><a onmouseover='thmbOver();'><span class='thumb'><img src='thmbs/image3.jpg'></span></a></div>


I've tried a few approaches to the function's targeting, like document.getElementById(this.parent.id).style.zIndex, etc, but still nothing.

Any ideas?

Thanks,
~gyz

Old Pedant
08-19-2011, 09:28 PM
Why do you need JavaScript?

What's wrong with something simple:


<html>
<head>
<style type="text/css">
.thumb {
height: 75px;
z-index: 10;
}
.thumb:hover {
height: 150px;
z-index: 20;
}
</style>
</head>
<body>
<div>
<img class="thumb" src="http://www.ClearviewArts.com/thumbnails/OldBlueEyes.jpg" />
</div>
<div>
<img class="thumb" src="http://www.ClearviewArts.com/thumbnails/Antidepressant.jpg" />
</div>
<div>
<img class="thumb" src="http://www.ClearviewArts.com/thumbnails/SignatureCalico.jpg" />
</div>
</body>
</html>

Are you trying to get the other two <div>s to stay positioned all the while the hovered over one expands??

Old Pedant
08-19-2011, 09:37 PM
I'm guessing this is more what you mean?


<html>
<head>
<style type="text/css">
div.thumb {
position: relative;
height: 75px;
overflow: visible;
z-index: 10;
}
img {
height: 75px;
}
img:hover {
height: 150px;
}
</style>
</head>
<body>
<div class="thumb" onmouseover="this.style.zIndex=20;" onmouseout="this.style.zIndex=10;">
<img src="http://www.ClearviewArts.com/thumbnails/OldBlueEyes.jpg" />
</div>
<div class="thumb" onmouseover="this.style.zIndex=20;" onmouseout="this.style.zIndex=10;">
<img src="http://www.ClearviewArts.com/thumbnails/Antidepressant.jpg" />
</div>
<div class="thumb" onmouseover="this.style.zIndex=20;" onmouseout="this.style.zIndex=10;">
<img src="http://www.ClearviewArts.com/thumbnails/SignatureCalico.jpg" />
</div>
</body>
</html>

gyzhor
08-19-2011, 09:41 PM
That was the very first thing I tired. But unless I'm mistaken, because the images are inside separate divs, changing their z-index only changes them within the context of the div itself, meaning the images will still display in the index order of their parent divs.

I thought that using javascript might let me target the z-indexes of their parent divs, letting me swap their levels, rather than the images' levels.

Old Pedant
08-19-2011, 09:46 PM
Heh! You just have to catch up with my postings!

You know, if the three <div>s are in the center of the page, then the other thing you might want to do is change the *position* of the <img> when it expands, so that it stays centered on its home <div>.

You want that?

gyzhor
08-19-2011, 10:00 PM
You are quick. ;)

Well, the trick is that I'm trying not to change the class of the parent divs. That may seem like an unnecessary limitation, but this page has a loooooooot of divs generated by a loop, and their being populated with images is just one short step in a series of other states (the divs rearrange themselves with every click).

Based on your suggestion, I just tried adding something to the div-writing loop that allows them to check if they're populated with an image, and if so, attempt a this.style.zIndex=20; script, but, well, that didn't work either.

I'll work in it a little more and see if I can get any better results.

The centering thing is an option, but the image is expanding significantly, and they're pretty close together.

Old Pedant
08-19-2011, 10:41 PM
If you show me the actual nesting, I can show you what to do. It's really not hard, but you have to know what the nesting looks like. Need to have *SOMETHING* that tells you how far "up" the chain the <div> you want to affect is. Could be a class name, could be the pattern of the ID, or could be just the number of "levels" up.

Old Pedant
08-19-2011, 10:49 PM
Here's what I meant re repositioning the images:


<html>
<head>
<style type="text/css">
div.thumb {
position: relative;
height: 75px;
overflow: visible;
z-index: 10;
}
img {
position: absolute;
top: 0px; left: 0px;
height: 75px;
width: 100px;
}
img:hover {
position: absolute;
top: -37px; left: -50px;
height: 150px;
width: 200px;
}
</style>
</head>
<body>
<div style="position: absolute; top: 200px; left: 200px;">
<div class="thumb" onmouseover="this.style.zIndex=20;" onmouseout="this.style.zIndex=10;">
<img src="http://www.ClearviewArts.com/thumbnails/OldBlueEyes.jpg" />
</div>
<div class="thumb" onmouseover="this.style.zIndex=20;" onmouseout="this.style.zIndex=10;">
<img src="http://www.ClearviewArts.com/thumbnails/Jowie.jpg" />
</div>
<div class="thumb" onmouseover="this.style.zIndex=20;" onmouseout="this.style.zIndex=10;">
<img src="http://www.ClearviewArts.com/thumbnails/SignatureCalico.jpg" />
</div>
</body>
</html>

gyzhor
08-19-2011, 11:05 PM
Well I managed to get it sort of working by adding the style to a script each generated div already uses to determine whether or not it's a link. Think is, it simply refused to work with an if condition (to check for the image) , which means every single div will jump up to the highest index when you mouse over it, regardless of what that div is. I guess I don't see much wrong with that, unless doing that too many times could cause lag issues.

There's a new issue now. The image will pop up over one another, but if you've visited one image more than once, that image will take a second to move back when overlayed with another image. What's with the delay?

Anyways, there the script I used (simplified a little):


var urlArray = ["none", "none", "none", "none", "image", "image", "image"];
var textArray = ["one", "two", "three", "four",
"<div class='thumbWide'><img src='thmbs/gyzhor1.jpg'></div>";
"<div class='thumbWide'><img src='thmbs/gyzhor2.jpg'></div>";
"<div class='thumbWide'><img src='thmbs/gyzhor3.jpg'></div>";


var divName;
var divNum;

function checkOver(divName){
divNum = divName.replace("div", "");
if (urlArray[divNum] != "none"){
document.getElementById(divName).style.cursor="pointer";
document.getElementById(divName).style.zIndex = "1000";
}
}
function checkOut(divName){
divNum = divName.replace("div", "");
if (urlArray[divNum] != "none"){
document.getElementById(divName).style.cursor="default";
document.getElementById(divName).style.zIndex="1";
}
}


function writeDivs(){
var i = 0;
while (i<=447){
document.write("<div class='posDiv' id='div"+i+"' onclick='checkClick(this.id)' onmouseover='checkOver(this.id);' onmouseout='checkOut(this.id)'>"+textArray[i]+"</div>");
i++;
}
}


And when you say you want to look at the nesting, you mean you want to see the page itself? It's not live yet and is pretty convoluted ... it might take be a bit to put it up, but I can if you' like.

gyzhor
08-19-2011, 11:15 PM
okay, I finally got the image-check condition to work, but the index-change lag persists.

I though it might have something to do with the fact I have css3 opacity delays set elsewhere on the page, but deleting them changes nothing.

Old Pedant
08-20-2011, 12:06 AM
Is it possibly because you have to move off of the *larger* image before the onmouseout triggers??

But honest, we could have done it without numbering the <div>s. Not that I think that's really a wrong way to do it.

gyzhor
08-20-2011, 01:00 AM
It could be c something like that, I guess - it's hard to tell. If you mouse up all of them, once you get pretty well past the last one, the next one will expand, but leave the previous (now smaller) on top for about half a sec. If you approach the next image top-down (avoiding any hot spots for th last one) it still kinda does it, but faster and less noticably.

I'll IM you a link if you wanted to see it yourself.

Yeah, it would have been nice doing something simpler than what I did, but what the heck - the divs were already numbered anyways.

Thanks for the help, Old Pedant! I don't believe this is the first time you've helped me out of a scrape! :D
~gyz

Old Pedant
08-20-2011, 11:50 PM
Here: Latest try, allowing you put the onmouseover on the <img> to keep the rest of the page simple.


<html>
<head>
<style type="text/css">
div.posDiv {
position: relative;
z-index: 1;
width: 200px;
}

div.thumbWide {
text-align: left;
}
div.thumbWide img {
height: 75px;
}
div.thumbWide img:hover {
height: 150px;
}

span.caption {
display: none;
}
</style>
<script type="text/javascript">
function thumbIt(image,isOver)
{
var div = image;
while ( div.className != "posDiv" )
{
div = div.parentNode;
if ( div == null ) return; // oops! not found
}
div.style.zIndex = isOver ? 1000 : 1;
div.getElementsByTagName("span")[0].style.display = isOver? "block" : "none";
}
</script>
</head>
<body>
<div style="position: absolute; top: 200px; left: 200px;">
<div class="posDiv">
<div class="thumbWide">
<img src="http://www.ClearviewArts.com/thumbnails/OldBlueEyes.jpg"
onmouseover="thumbIt(this,true);" onmouseout="thumbIt(this,false);" />
<span class="caption">Old Blue Eyes</span>
</div>
<div>
<div class="posDiv">
<div class="thumbWide">
<img src="http://www.ClearviewArts.com/thumbnails/Jowie.jpg"
onmouseover="thumbIt(this,true);" onmouseout="thumbIt(this,false);" />
<span class="caption">Jowie</span>
</div>
</div>
<div class="posDiv">
<div class="thumbWide">
<img src="http://www.ClearviewArts.com/thumbnails/SignatureCalico.jpg"
onmouseover="thumbIt(this,true);" onmouseout="thumbIt(this,false);" />
<span class="caption">Kalico Kat</span>
</div>
</div>
</div>
</body>
</html>

gyzhor
08-22-2011, 02:39 AM
That appears to do the trick, OP, thanks! The layer-swapping lag still persists, unfortunately, but I can live with that.

gyzhor
08-22-2011, 07:07 AM
I do have another problem in the same project that should be a quick resolve, I'm just not finding it. I'm storing the names of functions in an array, like so:


var myFunctions = ["func1", "func2", "func3", "func4"]

Then calling them like this:

window[myFunctions[i]]()

Trouble is, this is keeping me from attaching variables to the function. I've tried it like this:

var myFunctions = ["func1()", "func2(myVariable)", "func3()", "func4()"]

window[myFunctions[i]]

But that doesn't work at all. How to I write the way I call the string as a function in a way that includes the parentheses and variable within them?

Old Pedant
08-22-2011, 07:54 AM
Well, if you did *NOT* need to pass arguments, you'd simply do:


var myFunctions = [func1, func2, func3, func4];
...
myFunctions[i]( );

By far the cleanest way.

But if you really need to pass arguments, you could do:


var myFunctions = ["func1()", "func2(myVariable)", "func3()", "func4()"]
...
eval( myFuntions(i) );

I don't really recommend it, but it should work.

If only one or two of the functions in a long list need arguments passed, you might do this:


var myFunctions = [func1, function() { func2(myVariable); }, func3, func4];
...
myFunctions[i]( );

gyzhor
08-22-2011, 08:00 AM
Nah, they pretty much all need to pass a different argument.
So why do you not recommend the "eval" approach? I mean, should it work cross-browsers?

gyzhor
08-22-2011, 08:30 AM
Hmm. Actually doesn't look like eval's working for me anyways.
I've got dozens and dozens of these strings to call at functions, but I may have to write them all out like your third options anyways.

gyzhor
08-24-2011, 10:56 PM
Actually, I can't seem to get either one to work.

gyzhor
08-24-2011, 11:11 PM
Ah, no wait - eval works when the parentheses are changed to brackets.

So again, why does everyone seem hesitant to use eval? I've heard it described as "not very safe" but no explanation beyond that.

Trying to see what I did wrong in the other method now...

Old Pedant
08-24-2011, 11:38 PM
Sorry! Idiocy on my part. Yes, of course it needs to be

eval( myFunctions[i] );


eval isn't as evil as it is made out to be when used for something like this. It *can* be a tremendous performance hog, as it has to create a new context for the code to execute in, etc., etc. Older versions of MSIE were notorious for horrendous performance of eval.

If it's not over-used, and if you are just using it to, essentially, call a function, I wouldn't worry too much about it.

gyzhor
08-24-2011, 11:46 PM
Yeah, I really should have caught that earlier. :)

It shouldn't be too much of a memory hog? Even if it's used for every single link on a site? Seems like calling a compiler an awful lot.

I mean, if I understand correctly, I shouldn't be susceptible to injection attacks if I'm supplying the arguments myself, and not getting them from user input or pulling the data from elsewhere, but i'm still hesitant to generate maybe a hundred instances of a method people tell me to "use sparingly, if at all".

But if you think using it to call a string as a function is fairly innocuous in this case, it would solve me little argument-passing problem.

~gyz

Old Pedant
08-25-2011, 01:07 AM
?? why a memory hog? Once the eval() call has been made, presumably all the memory used by it will be released back to the system for re-use. And 100 calls would be nothing. Think about it: even if each call used, say, 10K bytes of memory, that's only 1MB of memory total, even if none of it were re-used (which I think it would be).

gyzhor
08-25-2011, 01:30 AM
Sounds good to me. I've already been replacing my old calls with it, and it looks good so far.

Thanks again (and again and again!), Old Pedant!

~gyz



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum