Forums

The forums ran from 2008-2020 and are now closed and viewable here as an archive.

Home Forums JavaScript Have JS do something only after CSS loads AND renders

  • This topic is empty.
Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #196236
    jaredcheeda
    Participant

    There are several ways to tell when the DOM is finished or when all files have been downloaded, but I need to run some code after the styles actually render. Specifically I’m in NW.js (Node-Webkit). So I only care about being able to do it in that environment.

    I’ve done my standard hour of googling and have not found any reliable answers. Who’s up for a challenge!

    #196251
    jaredcheeda
    Participant

    I’m working on a framework for other developers. The idea is that you can create your application in under five minutes. To prevent all of these applications from looking the same, one of the features of the framework is that it comes with several stylesheets to pick from.

    There is a dropdown menu that lets you try out all the stylesheets to see which one you like best and use that one. That works fine, it unloads the current stylesheet, then replaces it with the new one and 50-200ms later the styles are rendered (depending on your computer).

    I’m using some additional plugins that create elements that are not effected by these stylesheets. So I need to be update them to match the style of other elements whenever the stylesheets are swapped, or on page load. Without a way to reliably detect when the render completes, I’m having to use a set timeout at 71ms, which is either too quick and sometimes runs before the css gets applied, or is too slow and looks choppy and weird to have the elements updated so long after everything else renders.

    In animation 14 fps is the slowest you can go before your animation starts looking choppy to the human eye. 71ms is 1/14th of a second. So I don’t want to go any slower than that, but sometimes that’s too fast. Ideally I could just have it run immediately after the last style is applied.

    function swatchSwapper() {
        //Allow access to the filesystem
        var fs = require("fs");
        //Grab all the files in the ven.bootswatch folder and put them in an array
        var allSwatches = fs.readdir("_style/ven.bootswatch", function(err, files){
            //if that works
            if (!err)
                //check each file and put it in the dropdown box
                for (var i = 0; i < files.length; i++) {
                    var fileName = files[i];
                    var swatchName = files[i].split(".min.css")[0];
                    $("#swatchSwapper").append("<option value='_style/ven.bootswatch/" + fileName + "'>" + swatchName + "</option>");
                }
            else
                console.warn("Could not return list of style swatches.");
        });
    
        //When you change what is selected in the dropdown box, swap out the current swatch for the new one.
        $("#swatchSwapper").change(function (){
            $("head link[data-swatch]").attr( "href", $("#swatchSwapper").val() );
            //after the new one is swapped update page elements not effected by the swatch
            window.setTimeout(centerNavLogo, 71);
            window.setTimeout(sliderHandleColor, 71);
        });
    
    }
    

    One idea I had was to just add one line at the end of each css file that changes the width of an element that has a height of 0px. Then detect when that width changes as it should be the last thing to get rendered. But I’m not sure if that’s a good solution, or even feasible.

    #196266
    jaredcheeda
    Participant

    The project is called UGUI which stands for “The Universal GUI”. It allows people with very basic command line and HTML experience to give a command line executable a GUI. If the CLI is crossplatform then you can reuse your GUI and just repackage your project for each environment. So it’s universal in the sense that anyone can do it, that it works on Windows, Linux, and OSX, and that it doesn’t require specific knowledge of the programming language the CLI was written in or any of it’s GUI libraries for that language. It just requires you have about 10 minutes worth of training on CMD and HTML so you can abstract out the CLI arguments into HTML form elements.

    All of this is possible because of NW.js (formerly Node-Webkit). It took me about 6 hours to go start to finish with having never heard of it to having a custom designed application that sent arguments to a command line executable and returned information from the exe onto the page. Once I got that far I knew the process could be simplified for others. So my goal was to create a library and framework to make it as easy and quick as possible so that 6 hour process could be brought down to 5 minutes. Ultimately I’d like to make a desktop application that automates the process through a wizard so the whole thing will only take about 30 seconds. Of course if you have more knowledge than just basic CMD and HTML you can expand upon and customize your application however you want. And even if you don’t need to give a GUI to a CLI, you can just use UGUI as a jumping off point for creating any kind of NW.js application. It’s meant to have all the common stuff you’d want already set up, so you don’t have to do tedious stuff like create your own cut/copy/paste context menu.


    From some googling, I’ve found 3 different ways of waiting until content is ready. I went so far as to wrap my functions in all 3 of them and they still run instantaneously instead of waiting for the styles to render.

    $("#swatchSwapper").change(function (){
        $("head link[data-swatch]").attr( "href", $("#swatchSwapper").val() );
    
        $(window).bind("load", function() {
            $(document).ready( function() {
                window.addEventListener("pageshow", onEventProc, true);
                function onEventProc(aEvent) {
                    var win = aEvent.currentTarget;
                    var top_doc = win.frames[0].document;
                    var cur_doc = aEvent.target;
                    if (top_doc == cur_doc) {
                        centerNavLogo();
                        sliderHandleColor();
                    }
                }
            });
        });
    });
    

    So, just for some context, that “sliderHandleColor” function is grabbing the color from the navigation bar background and setting the color of that object to match it so it looks correct with that theme. The slider is a special plugin, so it isn’t something that could have been expected/targeted by the stylesheet creators. And I don’t want to manually edit the stylesheets as there is the potential for hundreds in the future, and any/all are subject to being updated in the future by the original creators.

    When I switch to a different stylesheet it runs instantly and gets the current style info, THEN the styles update and the content those functions were supposed to affect are incorrect.

    So I’m looking for a trick to use to trigger when the styles finish being applied.

Viewing 3 posts - 1 through 3 (of 3 total)
  • The forum ‘JavaScript’ is closed to new topics and replies.