TheRealPir
TheRealPir

Reputation: 455

when does a dynamically loaded CSS into head get executed

If already answered somewhere, I would appreciate the link I just can't find it.

I load .php pages with either <?php include 'header.php'; ?> directly or on button/link action with

<a href="#" data-toggle="modal" role="button" data-target="#genericModal" onclick="loadModalContent(\'profil.php\',\'genericModal\')">.

Some of the loaded children need the same .css & other files as their parent, so I though I would use the following code to load

function loadStyleSheet(uri){
    //jquery might not be loaded yet, so do long form
    var ss = document.styleSheets;
    for (var i = 0, max = ss.length; i < max; i++) {
        if (ss[i].href.indexOf(uri) > -1){
            return;
        }
    }
    var styleSheet = document.createElement("link");
    styleSheet.href = uri;
    styleSheet.rel = "stylesheet";
    styleSheet.type = "text/css";
    document.getElementsByTagName("head")[0].appendChild(styleSheet);
};

and then I have i.e. two files:

parent.php

<html>
    <head>
        <link rel="stylesheet" href="css/bootstrap.css"/>
        <link....something else and more....
    </head>
    <body>
        load in one way or another the child.php
    </body>
</html>

and

child.php (no html, no head or body)

<script>
    loadStyleSheet("css/bootstrap.css");
    loadStyleSheet("css/child.css");
</script>
<div class="xyz">
    something more here
</div>

But my question is now, how the browsers react to it. Because basically the parent already went through his <head></head> and is building the page and somewhere in the middle I tell him to load some other code and oh by the way, append a .css with javascript to his <head> (I don't have <head>s in the child files). How do browsers react to this?

I understand I probably could use loaders, but would like to avoid them for now.

I also could add all children .css into the parents, but for clarity and load on demand design would like to keep them in the children .phps

Thanks in advance!

Upvotes: 2

Views: 433

Answers (3)

Daniel Salcedo
Daniel Salcedo

Reputation: 332

I would recommend to have all the css your parent and child need added at first. If you need clarity, you can split it in two files and add them both.

But if you can't perhaps you could load the style rules inside a <style> tag instead of a <link>

Of course if you put the css inside a <style> you're not taking advantage of the caching of the browser, but if you're worried about not using it, why not to load all the css in the first place

take a look at this site

Upvotes: 1

Mark Adelsberger
Mark Adelsberger

Reputation: 45759

The browser should respond to DOM changes - which would include adding a stylesheet - right away.

However, "right away" is limited because the browser runs things single-threaded, and because it needs to actually load the stylesheet (probably from a remote location).

Generally a re-render will occur when any script that modified the DOM ends. (That could mean essentially at the </script> tag for an inline script, or when the event handler returns if an event triggered the script...)

So if you were to step through with a debugger, you would see that the <link> element appears under head as soon as you execute the following line:

document.getElementsByTagName("head")[0].appendChild(styleSheet);

But the page won't have re-rendered yet.

But even when the DOM is re-rendered if the new stylesheet resource hasn't had time to load then the rendered page will not appear updated. To a user, it will appear that the stylesheet is applied at some unspecified time, no sooner than completion of the script that created the <link> element.

Upvotes: 3

J. Thompson
J. Thompson

Reputation: 521

I don't know if this is exactly what you're looking for, but it's a proof of concept that might work for your desired application.

<link rel="stylesheet" href="~/lib/font-awesome/css/font-awesome.css" media="none" onload="$_font_awesome_media = this; console.log($_font_awesome_media.media); $_font_awesome_media.media='all'" />

<button type="submit" onclick="$_font_awesome_media.media='none'">Send Emails</button>

The button will manipulate the media query to turn off the font-awesome.css file. You can use this technique to show the .css files you want to show inside your child modules.

Simply use the following javascript to enable it.

$_font_awesome_media.media='all'

Please take into consideration that this is probably a "hack" but, it gets the job done and in a very efficient manner. The css files will be downloaded in the background so it doesn't slow down the website from loading initially. If Javascript is disabled you will need to determine how to handle that separately.

Upvotes: 0

Related Questions