1

I wonder if anyone has encountered this and what they did to fix it. IE, is not applying a style for a class I added at runtime (jQuery). The weird thing is that the Developer Tools is showing it should be applied. See picture below.

The "fa-bars" element has a parent with "blue" class. In this case, I added the "blue" class within $(document).ready(). If I add the "blue" class on the HTML markup (instead of doing it at run-time), it applies the style correctly. But that is not what I want to do.

I only have this problem on IE (I use IE8), but Chrome and FF both render the page as I expect (correctly). Any ideas on how to solve this?

It appears to be a problem only when rendering pseudo content (eg, FontAwesome). If I replace the element with plain text, it works.

enter image description here

ADDED:

Here's my full HTML with links to CDNs for FontAwesome and jQuery:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width" />
        <title>Test</title>
        <link href="http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
        <script src="http://code.jquery.com/jquery-1.10.2.min.js" type="text/javascript"></script>
        <script type="text/javascript">
            $(document).ready(function () {
                $('.nav-toc').addClass('blue');
            });
        </script>
        <style type="text/css">
            .fa {font-size: 1.5em;}
            .nav-toc {color: red;}
            .blue {color: blue;}
        </style>
    </head>

    <body class="pson-green">
        <div id="master-body">
            <!-- Top banner (Menu) -->
            <div id="master-header">
                <div class="content-wrapper">
                    <div id="nav-grp-toc" class="nav-container">
                        <div class="nav-btn nav-toc" title="Contents Menu"><i class="fa fa-bars"></i></div>
                    </div><div id="nav-grp-help" class="nav-container">
                        <div class="nav-btn nav-help" title="Help"><i class="fa fa-question"></i></div>
                    </div><div id="nav-grp-counters" class="nav-container">
                        <div id="page-counter" class="nav-page counter-panel">
                            <div id="current-page" class="current-count" title="Current page number"></div>
                            <div id="total-pages" class="max-count" title="Total number of pages"></div>
                        </div>
                        <div id="question-counter" class="nav-quiz counter-panel">
                            <div id="current-question" class="current-count" class="Current question number"></div>
                            <div id="total-questions" class="max-count" title="Total number of questions"></div>
                        </div>
                    </div><div id="nav-grp-steppers" class="nav-container">
                        <div class="nav-btn nav-page nav-prev" title="Back"><i class="fa fa-chevron-left"></i></div>
                        <div class="nav-btn nav-page nav-next" title="Next"><i class="fa fa-chevron-right"></i></div>
                    </div><div id="nav-grp-exit" class="nav-container">
                        <div class="nav-btn nav-page nav-exit" title="Exit Course"><i class="fa fa-sign-out"></i></div>
                    </div>
                </div>
                <div id="dimmer-for-header" class="dimmer"></div>
            </div>
        </div>
    </body>   
</html>
Frank Fajardo
  • 7,034
  • 1
  • 29
  • 47
  • @crush, what do you mean? – Frank Fajardo Jan 31 '14 at 00:43
  • 1
    He means post your code – Deryck Jan 31 '14 at 00:48
  • Ok, "content" was too general. But thanks for clarifying – Frank Fajardo Jan 31 '14 at 01:09
  • Got a feeling your jQuery isn't even running. Check your script debugger/console and see if there's something like `$ is undefined` – Deryck Jan 31 '14 at 01:12
  • @Deryck, it is running on mine, using this code I posted (which I copied and pasted and re-tested). – Frank Fajardo Jan 31 '14 at 01:17
  • It may be a delay at your end in getting jquery from the CDN, IMHO. It should work with a local jquery copy. – Frank Fajardo Jan 31 '14 at 01:19
  • it does work with local. it works perfectly actually but I'm in linux running chrome lol. Even though I can't give you the cause, you could always use `.removeClass('nav-toc').addClass('blue');` – Deryck Jan 31 '14 at 01:24
  • @Deryck, It also does not work. But thanks for trying to help. – Frank Fajardo Jan 31 '14 at 02:40
  • Only other thing (besides avoiding IE 8 at all costs) might be putting your scripts at the end of your `` tag and see if it changes it. – Deryck Jan 31 '14 at 02:59
  • @Deryck, that does not work either. That's how my actual work is. The function that adds the class is in a script tag below the page (as I call the function after load. I simply changed it here for simplicity. I now officially want to bury IE8 alive. – Frank Fajardo Jan 31 '14 at 03:24
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/46478/discussion-between-deryck-and-frank-fajardo) – Deryck Jan 31 '14 at 03:42
  • Hi Deryck, thanks for the offer to chat. I've decided to go with the solution I posted below... for now at least :) – Frank Fajardo Jan 31 '14 at 04:08

1 Answers1

0

I think I may have found an answer. It appears from my searches for similar posts, the problem is with IE's handling of pseudo elements. Unfortunately, I number of answers/suggestions on these posts don't appear to work in my case, except for this SO item. Basically, it suggests forcing IE to redraw the pseudo element by temporarily adding to the DOM a style tag which removes all pseudo content, and then removing that style tag immediately afterwards. It seems to work, when combined with a check for IE8 based on this SO item. I added this to my script:

var ie = (function () {
    var undef,
    v = 3,
    div = document.createElement('div'),
    all = div.getElementsByTagName('i');
    while (
        div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
                        all[0]
                        );
   return v > 4 ? v : undef;
 } ());

 function redrawPseudos() {
    var head = document.getElementsByTagName('head')[0],
    style = document.createElement('style');
    style.type = 'text/css';
    style.styleSheet.cssText = ':before,:after{content:none !important;}';
    head.appendChild(style);
    setTimeout(function () {
        head.removeChild(style);
    }, 0);
 }

So when I have to add/remove a class, which I expect to impact the styling of a pseudo element, I have to do this:

 $('.class1').addClass('newclass');   
 if (ie === 8) {
    redrawPseudos();
 }

It is probably an expensive way of doing it. But I only have less than a dozen of pseudo elements.

ADDED:

You can improve this by passing a selector to redrawPseudos() and including it to the style. This will limit the redraw to the elements identified by your selector.

function redrawPseudos(sel) {
    ...
    style.styleSheet.cssText = sel + ':before, ' + sel + ':after, ' + sel + ' *:before, ' + sel + ' *:after ' + '{content:none !important;}';
    ...
}
Community
  • 1
  • 1
Frank Fajardo
  • 7,034
  • 1
  • 29
  • 47