Skip to content

Instantly share code, notes, and snippets.

@i-e-b
Created December 13, 2011 10:33
Show Gist options
  • Save i-e-b/1471596 to your computer and use it in GitHub Desktop.
Save i-e-b/1471596 to your computer and use it in GitHub Desktop.
Javascript defer by script file or script block (for MVC using Razor view engine)
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
using System.Web.WebPages;
namespace Web.Extensions {
public static class JavascriptIncludeExtensions {
private const string JscriptIncludeViewdata = "__jsrq";
private const string JscriptDeferRazorViewdata = "__jsdfrz";
/// <summary>
/// Include a javascript url to be written by the RenderScripts method.
/// Url will be included exactly once no matter how many times this method is called.
/// </summary>
public static void DeferScript (this HtmlHelper html, string scriptLocation) {
string jsTag = "<script type=\"text/javascript\" src=\"" + scriptLocation + "\"></script>";
var jscripts = html.ViewContext.TempData[JscriptIncludeViewdata] as List<string> ?? new List<string>();
if (!jscripts.Contains(jsTag)) jscripts.Add(jsTag);
html.ViewContext.TempData[JscriptIncludeViewdata] = jscripts;
}
/// <summary>
/// Defer a script block (or any other HTML string) until RenderScripts is called.
/// Defered blocks always render after included script sources.
/// Call like: @Html.Defer(@&lt;script&gt;...&lt;/script&gt;)
/// </summary>
public static IHtmlString Defer (this HtmlHelper html, Func<int, HelperResult> script) {
var jsActions = html.ViewContext.TempData[JscriptDeferRazorViewdata] as List<Func<int, HelperResult>> ?? new List<Func<int, HelperResult>>();
jsActions.Add(script);
html.ViewContext.TempData[JscriptDeferRazorViewdata] = jsActions;
return new HtmlString("");
}
/// <summary>
/// Render all defered scripts at this point. Defered scripts list will be reset.
/// </summary>
public static HelperResult RenderDeferred (this HtmlHelper html) {
var jscripts = html.ViewContext.TempData[JscriptIncludeViewdata] as List<string>;
var jsActions = html.ViewContext.TempData[JscriptDeferRazorViewdata] as List<Func<int, HelperResult>>;
html.ViewContext.TempData[JscriptDeferViewdata] = new List<Func<int, HelperResult>>();
html.ViewContext.TempData[JscriptIncludeViewdata] = new List<string>();
return new HelperResult(writer =>
{
if (jscripts != null) {
writer.Write(string.Join("\r\n", jscripts.ToArray()));
}
if (jsActions != null) foreach (var action in jsActions) { action(0).WriteTo(writer); }
});
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment