IE and adjacent sibling selector

Can somebody please tell me why IE (7/8) wont play nicely with all the other browsers in the playground… again…


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html lang=en>
<head>
<meta http-equiv="Content-type" content="text/html;charset=utf-8">

<script type="text/javascript">

	function collapser(x){  // alert(x.className);

		// close existing open block by locating and removing the 'open' class'
		var re = new RegExp('\\\\b' + "open" + '\\\\b');
		var els = x.parentNode.getElementsByTagName("*");
		for(var i=0,j=els.length; i<j; i++){
			if(re.test(els[i].className)){
				els[i].className=els[i].className.replace(/\\bopen\\b/,"");
			};
		};

		// now open the clicked section by adding open class
		x.className=x.className+" open"; // alert(x.className);
	};

</script>

<style type="text/css">
dd {display:none;}
.open + * {display:block;}

/* find way to revert to default rather than block */

dd div {
	width:100px;
	height:100px;
	background:#223344;
}
</style>
</head>

<body>

<div>
	<dl>
		<dt onclick="collapser(this);">Banner</dt>
		<dd >
			<div></div>
		</dd>
		<dt onclick="collapser(this);">Banner</dt>
		<dd >
			<div></div>
		</dd>
		<dt onclick="collapser(this);">Banner</dt>
		<dd >
			<div></div>
		</dd>
		<dt onclick="collapser(this);">Banner</dt>
		<dd >
			<div></div>
		</dd>
	</dl>
</div>
<p></p>
<div>
	<dl>
		<dt onclick="collapser(this);">Banner</dt>
		<dd>
			<div></div>
		</dd>
		<dt onclick="collapser(this);">Banner</dt>
		<dd>
			<div></div>
		</dd>
		<dt onclick="collapser(this);">Banner</dt>
		<dd>
			<div></div>
		</dd>
		<dt onclick="collapser(this);">Banner</dt>
		<dd>
			<div></div>
		</dd>
	</dl>
</div>

</body>
</html>

(To clarify the DD DIV block associated with a DT tag should appear when clicking on the DT tag, and collapse any other open DD DIV within that DL)

The javascript is not the problem (for example change the color style for the .open class you’ll see the colors change on the DT tag in IE as expected - also uncomment the alerts to see classes being changed as per expectations).

The Universal selector is not the problem (change the .open+* to .open+dd and IE still misbehaves when all others behave).

In fact, with a bit of frantic clicking around I can occasionally get IE to pop open one of the blocks. But that’s it.

Spent hours trying to locate the issue here. Any help much appreciated.

Furthermore…

It is not a problem with the dd display:none definition over-riding the class+selector definition, add class=“open” to any DT tag and IE will display the block on page load…

Think I have found some kind of IE updating bug I’m unaware of?

When I open the developer tools and toggle the CSS rule for the .open+* on/off the browser behaves - click on different DT items and switch the rule on/off and it does what it’s meant to.

Way over my knowledge of browser tech. Really could use some help here.

edit - sorry that should be off/on
edit2: and you have to switch off/on for every click to see results

OK, some really freaky stuff discovered.

Keep clicking on a DT tag until the IE ‘Accelerators’ icon appears near your mouse.

Hover over that Icon (don’t click)

Click on another DT tag in the same block.

The first click block appears.

Sorry to bore you all with this cr*p but this is weird.

edit:in fact the clicked box appears if you just click away from the accelerators icon anywhere
edit2: also! after doing the above procedure clicking in the other DL list and the first click you make will make the new click behave as it should do, but not subsequent clicks :-s
edit3: note the other boxes don’t disappear as they should either!

Right it’s definitely (imho) some kind of interference by the accelerator button:

  1. Do above steps until you have all boxes open

  2. Tools->Internet options -> Advanced -> Disable Accelerator button on selection

All boxes except the valid ones you last clicked will disappear. No further click behaviour works.

edit: or maybe not. Have tried script in ietester and no results of any kind on any version, though I have no idea about the reliability of this app
edit2: I’ll bet this is something to do with bubbling/capturing and some kind of browser-wide event they’ve implemented for the accelerator

Obviously, your JS code is not working for IE7/8. I suggest you request this thread be moved to JS forum.

That’s the thing - the javascript does work even in IE (it changes the class on clicked elements) and that’s all it’s meant to do.

It’s just that IE wont update (in this particular case) the display of the css class change without being nudged (and even then not fully).

So I thought since it was a css change not being executed by IE the css forum would be the most apropriate place to ask… but if Forum mods think Javascript forum is more appropriate for thread would be very happy if they did shift it… I just want an answer somewhere! :slight_smile:

Hi,

I think its a bug with the adjacent selector and the dynamically added class as adding a class manually works as expected.

The class is being added correctly because as you say you can change the color of the element holding the class with no problem (or indeed a child element). However the adjacent or general sibling selector don’t seem to work with this routine so I guess that IE hasn’t updated the dom for that to work properly.

It looks like you’ll have to walk the dom and find the adjacent elements by javascript instead and hide them that way.

I couldn’t see any css fixes although there may still be one :slight_smile:

Reduced example showing that it doesn’t work in IE.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style>
.open{background:red}
.open + p{background:blue}
</style>
</head>
<body>
<p onclick="this.className='open'">Click Me! - This is a test that will turn red onclick</p>
<p>This should turn blue? when above is clicked</p>
</body>
</html>


Not just me then… :slight_smile:

Will have to, as you say script my way round it… was trying to avoid that, and I would have got away with it if it wasn’t for those pesky kids…

Be interesting to know exactly what the difficulty IE has with it though.

Thanks for taking a look anyway…

I thought I’d found a fix but it doesn’t quite work.

The problem seems to be that the page doesn’t update so if you cause a reflow with hover then the element will show.

This works but the element doesn’t show until you move your mouse off the element.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style>
div{background:blue;display:none}
.open{background:red}
.open + div{display:block}
.open:hover {visibility:visible;}
</style>
</head>
<body>
<p onclick="this.className='open'">Click Me! - This is a test that will turn red onclick</p>
<div>This should turn blue? when above is clicked</div>
</body>
</html>

Well done :slight_smile:

Actually I should have thought of that because what you have above is also a fix for IE when it misplaces absolute elements after dynamic content has been inserted. That’s a very old bug without a css fix also.

Yes it would be nice to squash the bug completely and I never say never because someone will come along and say “just do this” :slight_smile:

Damn sight closer than I ever got, that’s almost perfect! :slight_smile:

I’ll have a play with a few JS-similar events tomorrow - or just look up if I can force this reflow you mention, at the end of the existing function. At least I got something to work with now, thanks! :smiley:

woohoo!

simply add:

x.parentNode.className=x.parentNode.className;

to the JS at the end of the function!

I love you man

edit (of course now the temptation is to try and find a pure css solution… The JS solution works well enough ofc… but it would be nice to css it)

Man, you saved me hours of work! I have come across this IE7/8 bug where the browser doesn’t correctly apply the adjacent sibling selector + when I insert or remove html elements with javascript. I have a script which rearranges (swaps positions of) list items and IE would not update the + style rule correctly after using insertBefore() and removeChild(). All I had to do was apply the above nonsensical code to the moved item and the problem is gone! I wouldn’t have come up with such a weird and simple fix myself…