Sibling selectors and reordering elements

E

eefacm

I'm composing a simple page that consists largely of a series of
images. Many of the images appear in groups showing the successive
stages of a particular operation. I thought it might look nice to
stack up the images, so that clicking on the topmost image sends it to
the bottom of the stack, showing the image that had been just below
it. Here's my first crack at it, for the simplest case of just two
images:

<style type="text/css">
.cycle { position: relative }
.cycle img { position: absolute; z-index: 1 }
.cycle img + img { top: 2em; left: 2em; z-index: 0 }
</style>
<script type="text/javascript">
function mouseclick(event) {
var target = event.target;
var parent = target.parentNode;
if (target.tagName == "IMG" && parent.className == "cycle") {
parent.appendChild(target);
}
}
document.addEventListener("click", mouseclick, false);
</script>
....
<div class="cycle">
<img src="image1.png">
<img src="image2.png">
</div>

This gives the overlapping visual effect I was after. When I click on
the top image, it jumps down into the lower position, completely
obscuring the lower image, but the lower image does NOT move into the
upper position. I had been expecting that after the appendChild
operation, with the second child of the div now becoming the first
child, the third style rule would no longer be applied to it, but
something about my expectation is clearly incorrect. Anyone have any
idea what might that be?
 
T

Tom Cole

I'm composing a simple page that consists largely of a series of
images.  Many of the images appear in groups showing the successive
stages of a particular operation.  I thought it might look nice to
stack up the images, so that clicking on the topmost image sends it to
the bottom of the stack, showing the image that had been just below
it.  Here's my first crack at it, for the simplest case of just two
images:

<style type="text/css">
  .cycle { position: relative }
  .cycle img { position: absolute; z-index: 1 }
  .cycle img + img { top: 2em; left: 2em; z-index: 0 }
</style>
<script type="text/javascript">
  function mouseclick(event) {
    var target = event.target;
    var parent = target.parentNode;
    if (target.tagName == "IMG" && parent.className == "cycle") {
      parent.appendChild(target);
    }
  }
  document.addEventListener("click", mouseclick, false);
</script>
...
<div class="cycle">
  <img src="image1.png">
  <img src="image2.png">
</div>

This gives the overlapping visual effect I was after.  When I click on
the top image, it jumps down into the lower position, completely
obscuring the lower image, but the lower image does NOT move into the
upper position.  I had been expecting that after the appendChild
operation, with the second child of the div now becoming the first
child, the third style rule would no longer be applied to it, but
something about my expectation is clearly incorrect.  Anyone have any
idea what might that be?

You may find it easier to either keep an array of image paths and
change the src attribute of the image tag when clicked or (in your
example above) simply play with the style.display attribute of all the
img tags within your div, rather than choosing to keep adding nodes to
the dom. That could get a little excessive as you never seem to remove
them :)
 
S

SAM

Tom Cole a écrit :
rather than choosing to keep adding nodes to
the dom. That could get a little excessive as you never seem to remove
them :)

used this way appendChild adds nothing
it only moves the element in DOM hierarchy

And, Firefox's Dom Inspector shows their order has changed.

Quite mysterious,

a little as if CSS definitively attached rules on 2nd image in the html
flux.
 
P

pr

<style type="text/css">
.cycle { position: relative }
.cycle img { position: absolute; z-index: 1 }
.cycle img + img { top: 2em; left: 2em; z-index: 0 }
</style>
<script type="text/javascript">
function mouseclick(event) {
var target = event.target;
var parent = target.parentNode;
if (target.tagName == "IMG" && parent.className == "cycle") {
parent.appendChild(target);
}
}
document.addEventListener("click", mouseclick, false);
</script>
...
<div class="cycle">
<img src="image1.png">
<img src="image2.png">
</div>

This gives the overlapping visual effect I was after. When I click on
the top image, it jumps down into the lower position, completely
obscuring the lower image, but the lower image does NOT move into the
upper position. I had been expecting that after the appendChild
operation, with the second child of the div now becoming the first
child, the third style rule would no longer be applied to it, but
something about my expectation is clearly incorrect. Anyone have any
idea what might that be?

You haven't said which browser you're using to look at it in. It works
as you describe in Opera 9.5b and Firefox 3.0b4. If you're using Firefox
< 3.0, then its failure may be explained by <URL:
https://bugzilla.mozilla.org/show_bug.cgi?id=73586>.

You can still do what you want, but it's safest to steer clear of
adjacent sibling selectors, which are relatively recently implemented.
You can either swap the image src to achieve the effect or use class
selectors and swap the className property of the elements, which I
suspect is the more efficient option.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top