Включить файл JavaScript в частичные представления
Мне интересно, что лучше всего использовать для включения файлов javascript в частичные представления. После рендеринга это закончится как тег JS include в середине html моей страницы. С моей точки зрения это не хороший способ сделать это. Они принадлежат тегу head и как таковые не должны препятствовать браузеру отрисовывать html за один раз.
пример: Я использую плагин jQuery picturegallery внутри частичного представления "PictureGallery" как этот частичный представление будет использоваться на нескольких страницах. Этот плагин должен быть загружен только при использовании этого представления и Я не хочу, чтобы нужно было знать, какие плагины использует каждый частичный вид...
Спасибо за ваши ответы.
8 ответов:
очень похоже на этот вопрос:связывание библиотек JavaScript в пользовательских элементах управления
Я повторю свой ответ, что этот вопрос здесь.
Я бы определенно не советовал помещать их внутрь частичных по той причине, о которой Вы упомянули. Существует высокая вероятность того, что одно представление может вытащить два партиала, которые оба имеют ссылки на один и тот же файл js. У вас также есть хит производительности загрузки js перед загрузкой остальной части формат html.
Я не знаю о лучшей практике, но я решил включить любые общие JS-файлы внутри главной страницы, а затем определить отдельный ContentPlaceHolder для некоторых дополнительных JS-файлов, специфичных для определенного или небольшого количества представлений.
вот пример главной страницы - это довольно понятны.
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %> <head runat="server"> ... BLAH ... <asp:ContentPlaceHolder ID="AdditionalHead" runat="server" /> ... BLAH ... <%= Html.CSSBlock("/styles/site.css") %> <%= Html.CSSBlock("/styles/ie6.css", 6) %> <%= Html.CSSBlock("/styles/ie7.css", 7) %> <asp:ContentPlaceHolder ID="AdditionalCSS" runat="server" /> </head> <body> ... BLAH ... <%= Html.JSBlock("/scripts/jquery-1.3.2.js", "/scripts/jquery-1.3.2.min.js") %> <%= Html.JSBlock("/scripts/global.js", "/scripts/global.min.js") %> <asp:ContentPlaceHolder ID="AdditionalJS" runat="server" /> </body>
Html.CSSBlock & Html.JSBlock, очевидно, мои собственные расширения, но опять же, они сами объясняют, в чем они делать.
затем в сказать Регистрация.aspx вид у меня был бы
<asp:Content ID="signUpContent" ContentPlaceHolderID="AdditionalJS" runat="server"> <%= Html.JSBlock("/scripts/pages/account.signup.js", "/scripts/pages/account.signup.min.js") %> </asp:Content>
HTHs, Чарльз
Ps. Вот следующий вопрос, который я задал о минимизации и объединении файлов js: конкатенация и минимизация JS на лету или во время сборки - ASP.NET MVC
EDIT: как и просил на мой другой ответ, моя реализация .JSBlock (a, b) по запросу
public static MvcHtmlString JSBlock(this HtmlHelper html, string fileName) { return html.JSBlock(fileName, string.Empty); } public static MvcHtmlString JSBlock(this HtmlHelper html, string fileName, string releaseFileName) { if (string.IsNullOrEmpty(fileName)) throw new ArgumentNullException("fileName"); string jsTag = string.Format("<script type=\"text/javascript\" src=\"{0}\"></script>", html.MEDebugReleaseString(fileName, releaseFileName)); return MvcHtmlString.Create(jsTag); }
и потом, где происходит волшебство...
public static MvcHtmlString MEDebugReleaseString(this HtmlHelper html, string debugString, string releaseString) { string toReturn = debugString; #if DEBUG #else if (!string.IsNullOrEmpty(releaseString)) toReturn = releaseString; #endif return MvcHtmlString.Create(toReturn); }
причина, по которой вы поместили бы скрипт в нижней части страницы, заключается в том, чтобы убедиться, что dom был загружен перед попыткой каких-либо манипуляций. Это также может быть достигнуто в чем-то вроде $(документ).ready (обратный вызов); метод jQuery.
Я разделяю мнение о том, чтобы не помещать встроенный JavaScript в html. Вместо этого я использую HTML-помощник для создания пустого div для использования в качестве инструкции сервера. Вспомогательный sig-это Html.ServerData (имя строки, данные объекта);
Я использую этот Метод ServerData для инструкций от сервера к клиенту. Тег div сохраняет его чистым, а атрибут" data - " является допустимым html5.
для инструкции loadScript я могу сделать что-то вроде этого в моем ascx или aspx:
<%= Html.ServerData("loadScript", new { url: "pathTo.js" }) %>или добавить еще один помощник, чтобы сделать это, который выглядит немного чище:
<%= Html.LoadScript("~/path/to.js") %>вывод html будет:
<div name="loadScript" data-server="encoded json string">тогда у меня есть метод jQuery, который может найти любые данные сервера метка: $(containingElement).serverData ("loadScript"); / / возвращает jQuery как массив декодированных объектов json.
клиент может выглядеть примерно так:
var script = $(containingelement").serverData("loadScript"); $.getScript(script.url, function () { // script has been loaded - can do stuff with it now });этот метод отлично подходит для пользовательских элементов управления или скриптов, которые должны быть загружены в ajax загруженного контента. Версия, которую я написал, немного больше связана с обработкой сценариев кэширования, поэтому они загружаются только один раз на полную загрузку страницы и содержат обратные вызовы и триггеры jQuery, поэтому вы можете подключиться к ней, когда она есть готовый.
если кто-то заинтересован в полной версии этого (от MVC до расширения jQuery), я был бы рад показать эту технику более подробно. В противном случае-надеется, что это дает кому-то новый способ подхода к этой сложной проблеме.
сегодня я создал свое собственное решение, которое идеально подходит для счета. Является ли это хороший дизайн или нет, это для вас всех, чтобы решить, но думал, что я должен поделиться в любом случае!
Ниже приведен мой класс HtmlExtensions, который позволяет вам сделать это в вашей главной странице:
<%=Html.RenderJScripts() %>
мой класс HtmlExtensions:
public static class HtmlExtensions { private const string JSCRIPT_VIEWDATA = "__js"; #region Javascript Inclusions public static void JScript(this HtmlHelper html, string scriptLocation) { html.JScript(scriptLocation, string.Empty); } public static void JScript(this HtmlHelper html, string scriptLocationDebug, string scriptLocationRelease) { if (string.IsNullOrEmpty(scriptLocationDebug)) throw new ArgumentNullException("fileName"); string jsTag = "<script type=\"text/javascript\" src=\"{0}\"></script>"; #if DEBUG jsTag = string.Format(jsTag, scriptLocationDebug); #else jsTag = string.Format(jsTag, !string.IsNullOrEmpty(scriptLocationRelease) ? scriptLocationRelease : scriptLocationDebug); #endif registerJScript(html, jsTag); } public static MvcHtmlString RenderJScripts(this HtmlHelper html) { List<string> jscripts = html.ViewContext.TempData[JSCRIPT_VIEWDATA] as List<string>; string result = string.Empty; ; if(jscripts != null) { result = string.Join("\r\n", jscripts); } return MvcHtmlString.Create(result); } private static void registerJScript(HtmlHelper html, string jsTag) { List<string> jscripts = html.ViewContext.TempData[JSCRIPT_VIEWDATA] as List<string>; if(jscripts == null) jscripts = new List<string>(); if(!jscripts.Contains(jsTag)) jscripts.Add(jsTag); html.ViewContext.TempData[JSCRIPT_VIEWDATA] = jscripts; } #endregion }
что происходит?
Класс выше расширит HtmlHelper с помощью методов для добавления ссылок javascript в коллекцию, которая хранится вHtmlHelper.ViewContext.TempData
коллекция. В конце главной страницы я поставил<%=Html.RenderJScripts() %>
который будет цикл jscripts коллекции внутриHtmlHelper.ViewContext.TempData
и визуализировать их на выходе.однако есть и обратная сторона,.. Вы должны убедиться, что вы не визуализируете сценарии, прежде чем добавить их. Если вы хотите сделать это для ссылок css, например, это не будет работать, потому что вы должны поместить их в
<head>
тег вашей страницы и htmlhelper будет отображать вывод раньше вы даже добавили ссылку.
Это похоже на аналогичный (хотя и не совсем) вопрос. это плохая практика, чтобы вернуть частичные представления, которые содержат javascript?
мое предпочтение будет заключаться в создании плагина.главная страница, которая наследуется от вашего основного сайта.мастер. Идея заключается в том, что вы набиваете эти плагины в плагин.Мастер и сделать 8 или около того страниц, которые будут использовать это частичное представление для наследования от плагина.мастер.
рекомендуется поместите скрипты внизу, однако, если вы не можете избежать этого, то разумно поместить их в середине.
браузеры обычно загружают различные элементы страницы параллельно, однако, пока браузер загружает файл Javascript, он не будет загружать любые другие элементы страницы параллельно, пока Javascript не будет загружен. Это означает, что ваши изображения и то, что не придется ждать, так что это вообще считается лучше переместите скрипты внизу, но если ваш скрипт маленький, я бы не беспокоился об этом.
hejdig.
играя с Aspnetmvc3 я решил, на данный момент, просто включить мой файл javascript в частичный
этот файл js затем специфичен для моего /пользователя/списка.файл schtml.
/ OF
дизайнеры MVC прошли через много проблем, чтобы помешать нам использовать code-behinds, но создав файл с именем
.aspx.cs и измените атрибут inherits страницы aspx соответственно, их все еще можно получить. Я бы сказал, что лучшее место для размещения include будет в обработчике Page_Load в codebehind (используя страницу.ClientScript.RegisterClientScriptInclude).