2

I have one linked css file for default properties and a second one for the news that it changes when the wiewport is changed. At the end of the JS script I puted an element's offsetWidth in the global value NavW. So JS seems to returns the wrong value, it doesn't compute only in the dom but based of the first default css properties not the new one. However, the target element rendered correctly. Notice that the value '2' in the condition is because there is a Link element which is not a css file but an icon.

    function switchTheme(newHref)
    {
        var newIndex;

        newIndex = document.getElementsByTagName("link").length;

        var newTheme = document.createElement("link");

            newTheme.setAttribute("rel", "stylesheet");
            newTheme.setAttribute("type", "text/css");
            newTheme.setAttribute("href", newHref);

        if ( newIndex == 2 )
            {
                document.getElementsByTagName("head").item(newIndex - 2).appendChild(newTheme);
            }

        else if ( newIndex > 2 )
            {
                var themeToReplace = document.getElementsByTagName("link").item(2);

                document.getElementsByTagName("head").item(0).replaceChild(newTheme, themeToReplace);
            }

        NavW = document.getElementById("wrap").offsetWidth;

    }
4
  • 1
    So what is your question?
    – morkro
    Commented Jul 24, 2014 at 8:47
  • I need to know, in the present case, if it is possible to obtain the actual value of an item without interfering with a style sheet. It is strange to see that my rendered element in the dom has the correct size and can not be calculated correctly.
    – FlowHoa
    Commented Jul 24, 2014 at 8:52
  • Then edit your question with your code and/or a link to jsFiddle. Nobody can help you like without that.
    – morkro
    Commented Jul 24, 2014 at 8:54
  • @morkro Is it clear for you ?
    – FlowHoa
    Commented Jul 24, 2014 at 9:06

1 Answer 1

1

Several points:

  • Your code replacing the style sheet seems quite unnecessarily complex.
  • Further more it seems to append/replace the new link element inside an existing link element, which means you are generating invalid HTML - you are lucky that this works at all. Something like: <link src="..."><link src="..." /></link>
  • You have the number of link elements (2) hard coded. You'll have big problems when you need to change your code every time the number of link elements changes (and don't say that won't happen).

You could solve all this by having your function for the first time simply create the link element, append it to the end of the head and store a reference to it. Then the next time use that reference and don't delete the link but simple change its src.

To your problem: Loading a style sheet like this is asynchronous, meaning that after creating the link element the script continues to execute (including the part getting the offsetWidth) without waiting for the style sheet to be loaded.

You'll need to attach an load event handler to the link and place everything that relies on the offsetWidth into that handler:

newTheme.addEventListener("load", function() {
  var NavW = document.getElementById("wrap").offsetWidth;
  // get and USE width here
}, false);
1
  • Thx you for taking the trouble to analyze my problem. Yes I grant you, it is too complex for the few that should happen, I would actually replace the SRC rather than completely remove the tag and create a new one instead. It should be noted however that my script replacement caused no conflict escalation since my tests ran successfully. What you probably disturbed it's value, but I mentioned that there was a link tag that is not absolutely related to a CSS file, but an icon. In any case thank you you did confirm that the source of the problem was that there was something asynchronous.
    – FlowHoa
    Commented Jul 24, 2014 at 12:05

Not the answer you're looking for? Browse other questions tagged or ask your own question.