简体   繁体   中英

Mvc complete asynchronous scripts loading

I have a small problem with asynchronous loading scripts on my web page. I need to load all scripts of page asynchronously. I tried many procedures, which I found on google, but still it is not perfect.

Now I have it like this:

  1. Split all scripts from layout to one bundle including jquery.
  2. On bottom of the page call RenderFormat with async tag.
  3. Now this is where I get the problem: I need to solve the situation where the scripts are being rendered by @RenderFormat. The problem is that those scripts are being rendered earlier than I need.

For example I have this in Home/Index file:

@Scripts.RenderFormat("<script async type=\"text/javascript\" src=\"{0}\"></script>", "~/bundles/raphael")

or simply

...
$(".datapicker").datapicker();
...

Here we get error, " $ is not defined ", because jquery is not loaded yet.

After content, in Layout file I have:

...
@Scripts.RenderFormat("<script async type=\"text/javascript\" src=\"{0}\"></script>", "~/bundles/frontall")
...
@RenderSection("scripts", required: false)

If I take all of my scripts on page and give them to one bundle, everything is fine, but I don't want scripts to get rendered, I need to do that only in a specific section.

Next idea was to create a custom RenderSection method, that will do someting like this:

    function async(u, c) {
    var d = document, t = 'script',
        o = d.createElement(t),
        s = d.getElementsByTagName(t)[0];
    o.src = u;
    if (c) { o.addEventListener('load', function (e) { c(null, e); }, false); }
    s.parentNode.appendChild(o, s);
}

async("/bundles/jquery", function() {
    //here, load scripts from inner pages. Index, Detail...
});

Is there way, how to solve it? Thank you very much for your time.

Ok guys, solved.

There is my current scrips in layout:

...

 @RenderSection("scripts", required: false)

    <script>

    function async(u, c, css) {
        var t = 'script';
        var element = document.createElement(t);
        var s = document.getElementsByTagName(t)[0];
        element.src = u;

        if (css) {
            t = "link";
            element = document.createElement(t);
            element.href = u;
            element.rel = 'stylesheet';
            element.src = null;
            var head = document.getElementsByTagName('head')[0];
            head.appendChild(element, head);

            return;
        }

        if (c) { element.addEventListener('load', function (e) { c(null, e); }, false); }
        s.parentNode.appendChild(element, s);
    }

    function initScripts() {
        async("/content/css", null, true);
        async("/bundles/jquery", function () {
            @RenderSection("asyncScripts", required: false)
        });
    }

    if (window.addEventListener) {
        window.addEventListener("load", function () {
            initScripts();
        }, false);
    }
    else if (window.attachEvent) {
        window.attachEvent("onload", function () {
            initScripts();
        });
    } else {
        window.onload = function () {
            initScripts();
        };
    }

</script>

And in other files. (Index, Detail...)

@section scripts {
   <script type="text/javascript">
    var czech_republic = {};
    window.selectedRegions = [];

    czech_republic.regions = {
        @Html.Raw(string.Join(", ", regions.Select(r => string.Format("\"{0}\": \"{1}\"", r.RaphaelId, r.RaphaelCoordinates))))
    };

</script>
@section asyncScripts {
    @Scripts.RenderFormat("async(\"{0}\");", "~/bundles/raphael");
}

If you need call next scripts, for example after raphael, you simple create new callback in renderformat async a that's all.

Thanks to all

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM