Question

In a ASP.NET Masterpage I am using YepNope to unconditionally and asynchronously load jQuery (from the Google CDN, with local fallback) and some scripts which are used on all pages in the site. In the MasterPage I have created a ContentPlaceHolder before the closing body tag (and below the YepNope script that loads those used on all pages) which is used for scripts used on individual page. As jQuery should be available on every page in the site it should not be loaded individually on those pages where there are specific scripts that use it.

The problem I have is that I can't use the callback or complete functions in the yepnope script where jQuery is loaded, as this is on the MasterPage and these are individual page scripts which are only used or added on that page, yet I need to be able to delay the execution of the individual page scripts until yepnope (which appears above the page scripts) has finished loading any dependencies (such as jQuery) used in them.

I can think of two options-

1- Make the script used on the page an external file and load that using the syntax -

yepnope('/url/to/your/script.js'); 

or

yepnope({ load: '/url/to/your/script.js' });

I'm not sure I like this idea as it introduces an extra HTTP request for a few lines of javascript which isn't going to be used on any other page.

2- Load jQuery again in another yepnope test object block, with the complete function wrapping up the page scripts (calling complete without a test seems to execute the function immediately, before the previous scripts are loaded) and relying on the following-

I am requesting a file twice and it's only loading once? By popular demand, in yepnope 1.5+ we added the feature that scripts that have already been requested not be re-executed when they are requested a second time. This can be helpful when you are dealing with less complex serverside templating system and all you really care about is that all of your dependencies are available.

In the page I could presumably load the same version of jQuery from the Google CDN, which based on the above would not actually be loaded twice, and then load the page scripts in an anonymous function called from the complete function of the yepnope test object.

On the plus side this would mean that the page is no longer dependent on jQuery being loaded from the MasterPage, but a negative would be that (even assuming YepNope does not load the script twice now) we would be loading multiple versions of jQuery should the version in the MasterPage be changed without the same happening in the page in the future. From a maintenance point of view I don't feel this is a good idea, especially on the assumption (which I feel you should always make) that another developer would be the one making the changes.

It also does not seem especially elegant.

On balance I will almost certainly use the first option but I would like to know if there is a way to delay or defer scripts on a page until asynchronous loading is completed, and this cannot be done as part of the YepNope test object loading the resources.

How do other developers approach this problem?

Was it helpful?

Solution

I have come up with this as a solution I rather like.

In the MasterPage YepNope test object add the code-

complete: function() {
                if (window.pageFunctions !== null && typeof (window.pageFunctions) === "function") {
                    window.pageFunctions();
                }
            }

If I want to add any JavaScript code or functions that rely on the dependencies loaded in the MasterPage I just wrap them in a function named "pageFunctions" like so-

<script type="text/javascript">
    function pageFunctions() {
        $(document).ready(function () {
            ...
        });
    }
</script>

I'm still interested in other (possibly better) solutions so I'm going to leave the question open for a couple of days.

I'd also appreciate comments on this as a solution.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top