FlowHoa
FlowHoa

Reputation: 75

offsetWidth returns unknown value (JS)

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;

    }

Upvotes: 2

Views: 310

Answers (1)

RoToRa
RoToRa

Reputation: 38400

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);

Upvotes: 1

Related Questions