1

I have index page with a container to which I load content obtained with ajax requests. These subpages can contain js specific especially to them that needs to be loaded only once. I would like to achieve the following:
If the subpage is loaded for the first time it loads the javascript, but if it is the second or n'th time, then javascript should not be loaded (because it is already in memory).

I could achieve that with some variable and checking its value before executing, but I am asking here if there is a proper, tested and used-by-many way of doing that. I am using MVC3 and jQuery if that's important.

Michal B.
  • 5,676
  • 6
  • 42
  • 70

6 Answers6

3

here's a little helper that i use for exactly that purpose:

public static MvcHtmlString Script(this HtmlHelper html, string path)
{
    var filePath = VirtualPathUtility.ToAbsolute(path);
    HttpContextBase context = html.ViewContext.HttpContext;
    // don't add the file if it's already there
    if (context.Items.Contains(filePath))
        return MvcHtmlString.Create("");
    return MvcHtmlString.Create(
        string.Format("<script type=\"text/javascript\" src=\"{0}\"></script>", filePath));
}

usage:

@Html.Script("~/calendar.js")

this MAY work a treat in the scenario that you describe - trial and (hopefully not) error.

jim tollan
  • 22,305
  • 4
  • 49
  • 63
1

Caching the script with jQuery.ajax seems to work for me.

Source: http://api.jquery.com/jQuery.getScript/

jQuery.cachedScript = function(url, options) {
    // allow user to set any option except for dataType, cache, and url
    options = $.extend(options || {}, {
        dataType: "script",
        cache: true,
        url: url
    });
    // Use $.ajax() since it is more flexible than $.getScript
    // Return the jqXHR object so we can chain callbacks
    return jQuery.ajax(options);
};

// Usage
$.cachedScript("ajax/test.js").done(function(script, textStatus) {
    console.log( textStatus );
});

For example, I have a form view to place in the DOM that uses some custom javascript:

<script type="text/javascript">
    $.cachedScript("/js/my_form_script.js");
</script>
<form action="/Ajax/saveSomething" method="POST">
    ...        
</form>

Each time the form is loaded, my console shows the get request for the script, but I have confirmed the request only hits the server on the first load.

Nickro
  • 31
  • 4
1

Have you tried something like YepNope?

It's one of the best things for this type of task.

Ricardo Souza
  • 16,030
  • 6
  • 37
  • 69
0

You must use the cache manifest.

More information from here: https://developer.mozilla.org/en/Using_Application_Cache

The idea is to explicitly tell the browser what files to cache for your application.

rjmateus
  • 26
  • 3
0

In the JavaScript code that loads the content pages using AJAX, load the page-specific JavaScript using a dynamically-generated <SCRIPT> element. You can then detect the presence of that element by giving it a unique ID and trying to find it in the DOM, in order to avoid loading it twice. Alternatively, set a global JavaScript variable.

var scriptLoaded=false;

function loadContent() {
    loadPageWithAJAX();
    if(!scriptLoaded) {
        var script = document.createElement('SCRIPT');
        script.setAttribute("type","text/javascript")
        script.setAttribute("src", 'path/to/page-specific.js');
        document.getElementsByTagName('head')[0].appendChild(script);
        scriptLoaded=true;
    }
}
Anthony Williams
  • 66,628
  • 14
  • 133
  • 155
-2

Answer from here.

You could make small script to check if jQuery is present on the page, and only if is not present, load it:

// 'load-jquery.js'
window.onload = function () {
  if (window.jQuery === undefined) {
    var script = document.createElement('script');
    script.src = 'path/to/jquery.min.js';
    document.getElementsByTagName('head')[0].appendChild(script); // load jQuery
  }
};

UPDATE:

You can use this function whenever you include the file:

var included_files = new Array();

function include_once(script_filename) {
    if (!in_array(script_filename, included_files)) {
        included_files[included_files.length] = script_filename;
        include_dom(script_filename);
    }
}

function in_array(needle, haystack) {
    for (var i = 0; i < haystack.length; i++) {
        if (haystack[i] == needle) {
            return true;
        }
    }
    return false;

}
Community
  • 1
  • 1
Pulkit Goyal
  • 5,604
  • 1
  • 32
  • 50
  • 1
    this only checks for jquery. he needs to know about any javascript file – Henesnarfel Feb 14 '12 at 14:36
  • If I am correct this checks for the jQuery. jQuery is loaded because I load it when the page loads. When I load the subpages I load some other content that also makes use of jQuery (but not necessarily). I want to check if *that* js is loaded or not. – Michal B. Feb 14 '12 at 14:37
  • I'm not sure, but some browsers may not accept to add elements to the head. – Ricardo Souza Feb 14 '12 at 14:39
  • I am not adding to the head. js is loaded into body, but it's not a problem. – Michal B. Feb 14 '12 at 14:57