Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 2 of 2
  1. #1
    Regular Coder
    Join Date
    Nov 2002
    Location
    Bristol, UK
    Posts
    932
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Exclamation IE7 CSS update problem when changing attributes and using selector-based rules

    I have some code that relies upon the manipulation of element attributes. A very simple example is to use mousedown to set a "state" attribute to "down", and then mouseup to set it back to "default". The CSS rules would then use [state=down] to make specific differences for the down state.

    Probably best if I produce some example code:

    Code:
    <!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>
    <style type="text/css">
    .thing {
    	cursor: default;
    	background-color: #eeeeee;
    	border: 2px solid #000000;
    	height: 20px;
    	width: 150px;
    	padding: 2px 8px;
    	display: block;
    	position: relative;
    }
    .thing[state=down] {
    	background-color: #bbbbcc;
    }
    </style>
    </head>
    
    <body>
    <div id="thing" class="thing">Click me!</div>
    <div class="thing" state="down">Don't click me.</div>
    <script type="text/javascript">
    var thing = document.getElementById("thing");
    thing.onmousedown = function() {
    	if (thing.setAttribute) thing.setAttribute("state", "down");
    	else thing.state = "down";
    }
    thing.onmouseup = function() {
    	if (thing.setAttribute) thing.setAttribute("state", "default");
    	else thing.state = "default";
    }
    </script>
    </body>
    </html>
    The code above is a very simplified version of what's happening in my code. We're only bothered with one element here, so I've hard-coded a reference to that element being clicked, in order to keep everything to a minimum, rather than handle the event in a more sophisticated way.

    The code works fine in Firefox, and the div's background colour changes.

    However, in IE7, nothing happens.

    I included a second element with the state attribute pre-set to "down", to show that IE7 is indeed properly applying the rules. It just doesn't seem to be doing so when I change the attribute dynamically.

    A point of interest - if I attach the behaviour to the mouseover and mouseout events, the same thing happens (i.e. nothing!). However, if I include a rule anywhere that uses :hover - even if no elements exist to match the rule - then it will suddenly work. To see what I mean, change "onmousedown" to "onmouseover", and "onmouseup" to "onmouseout" in the JavaScript code above - no behavioural change. Then add a CSS rule - ".something:hover {}" - and suddenly it works.

    This has led me to believe that IE7 has some code somewhere under the hood that only recalculates styles on mouseover/mouseout if one or more :hover selectors are used. Bizarre, but that's Microsoft!

    The question therefore seems to be, how can I force IE7 to recalculate the CSS being applied? I don't really mind if I have to call some function every time I change an attribute - although it would be a bit of a pain, I just want this stuff to work. I've been Googling about this for over a week, on and off, and not found anything. I've also not come up with any fixes or alternatives.

    Otherwise, if I'm doing something wrong, please could someone point it out!

    [EDIT:] I just want to point out that I'm aware I could add/remove a class to the element's class/className attribute to achieve the effect that way. It's just that using attribute selectors is less messy, and more semantic.
    Last edited by krycek; 10-28-2006 at 01:42 AM.
    ithium | SOAPI | SDP | PTPScript manual
    "ithium is a non-profit webhost, which is pretty much unique. The mission of ithium is to provide free hosting resources for worthwhile and needy non-profit projects, which otherwise may not be able to obtain such facilities. The money from commercial customers goes to maintain ithium's servers and further development."

  • #2
    Regular Coder
    Join Date
    Nov 2002
    Location
    Bristol, UK
    Posts
    932
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Okay, for anyone who's interested (and for anyone else who runs into this problem in the future!) I'm found the solution.

    All that is required is:

    Code:
    if (thing.className) thing.className = thing.className;
    By setting the class to, uhhh, exactly the same value (yeah, I know it seems silly!), IE updates the applied styles. So, this can be called after each change that will require an update.

    I went one further and put "this.className = this.className" in a function called "refresh", which I attached to every element using an HTC behaviour. Additionally, since I already use a modified setAttribute function, I put a call to the new refresh function in there. I'm sure it's not the most efficient thing ever, as it's bound to introduce some uncessary recalculation, but it works - and works well. On a scale of ugly to elegant, I'd rank this fix as fairly elegant

    Damn Microsoft and their weird ways... how many more hours am I destined to spend debugging in IE and searching for obscure information!
    ithium | SOAPI | SDP | PTPScript manual
    "ithium is a non-profit webhost, which is pretty much unique. The mission of ithium is to provide free hosting resources for worthwhile and needy non-profit projects, which otherwise may not be able to obtain such facilities. The money from commercial customers goes to maintain ithium's servers and further development."


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •