ASP.NET Core的“ asp-fallback-*” CDN标记助手如何工作?

时间:2018-07-16 13:42:39

标签: c# asp.net-core razor asp.net-core-2.1 asp.net-core-tag-helpers

我了解asp-fallback-*标签助手的作用。我不明白是怎么回事。

例如:

<link rel="stylesheet"
      href="//ajax.aspnetcdn.com/ajax/bootstrap/3.3.5/css/bootstrap.min.css"
      asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
      asp-fallback-test-class="sr-only"
      asp-fallback-test-property="position"
      asp-fallback-test-value="absolute" />

这将从CDN加载引导程序,如果CDN处于关闭状态,则加载本地副本。

但是它如何决定这样做呢?我假设它检查asp-fallback-test-classasp-fallback-test-propertyasp-fallback-test-value。但是这些属性是什么意思?

如果我想从CDN上连接其他库,则需要为它们提供一些东西,但是我不确定该放在哪里。

有很多这样的例子,但是我找不到关于它如何工作的解释。

更新
我并不是真的想了解标签助手的工作方式-它们如何呈现等等。我试图了解如何为这些属性选择值。例如,jQuery后备脚本通常具有asp-fallback-test="window.jQuery",这很有意义-这是一项测试以查看jQuery是否已加载。但是,我上面显示的内容完全不同。如何选择它们?如果我想使用其他CDN提供的库,则需要为这些属性指定值...我将使用什么?为什么选择那些作为引导程序?

更新2
要了解回退过程本身如何工作以及如何编写这些标签,请参阅@KirkLarkin的答案。要了解为什么使用这些测试值,请参阅我的答案。

2 个答案:

答案 0 :(得分:8)

TL; DR

  • <meta>标签添加到CSS类为sr-only的DOM中。
  • 将其他JavaScript写入DOM,该DOM:
    1. 找到所说的<meta>元素。
    2. 检查所述元素是否具有设置为position的CSS属性absolute
    3. 如果未设置此类属性值,则会将<link>href的{​​{1}}元素写入DOM。

针对您的~/lib/bootstrap/dist/css/bootstrap.min.css元素运行的LinkTagHelper类在输出HTML中插入一个<link>元素的<meta>元素。元素最终看起来像这样:

sr-only

生成元素的代码如下所示(源):

<meta name="x-stylesheet-fallback-test" content="" class="sr-only" />

毫不奇怪,builder .AppendHtml("<meta name=\"x-stylesheet-fallback-test\" content=\"\" class=\"") .Append(FallbackTestClass) .AppendHtml("\" />"); 的值是从FallbackTestClass的{​​{1}}属性中获得的。

在插入此元素之后,还将插入相应的<link>块(source)。该代码的开始像这样:

asp-fallback-test-class

这里有一些有趣的事情:

  • 注释的最后一行,它指向占位符<script>// Build the <script /> tag that checks the effective style of <meta /> tag above and renders the extra // <link /> tag to load the fallback stylesheet if the test CSS property value is found to be false, // indicating that the primary stylesheet failed to load. // GetEmbeddedJavaScript returns JavaScript to which we add '"{0}","{1}",{2});' builder .AppendHtml("<script>") .AppendHtml(JavaScriptResources.GetEmbeddedJavaScript(FallbackJavaScriptResourceName)) .AppendHtml("\"") .AppendHtml(JavaScriptEncoder.Encode(FallbackTestProperty)) .AppendHtml("\",\"") .AppendHtml(JavaScriptEncoder.Encode(FallbackTestValue)) .AppendHtml("\","); {0}
  • {1},代表输出到HTML中的JavaScript资源。
  • {2}FallbackJavaScriptResourceName,分别从属性FallbackTestPropertyFallbackTestValue获得。

因此,让我们看一下JavaScript资源(source),它归结为具有以下签名的函数:

asp-fallback-test-property

将其与我之前提到的注释的最后一行以及asp-fallback-test-valuefunction loadFallbackStylesheet(cssTestPropertyName, cssTestPropertyValue, fallbackHrefs, extraAttributes) 的值结合起来,我们可以得出这样的理由:

asp-fallback-test-property

我不会深入研究asp-fallback-test-valueloadFallbackStylesheet('position', 'absolute', ...) 参数,因为它们应该很明显并且很容易自己探索。

fallbackHrefs的实现不算什么-我鼓励您自己探索完整的实现。这是来自来源的实际检查:

extraAttributes

该脚本获取相关的loadFallbackStylesheet元素(假定它直接位于if (metaStyle && metaStyle[cssTestPropertyName] !== cssTestPropertyValue) { for (i = 0; i < fallbackHrefs.length; i++) { doc.write('<link href="' + fallbackHrefs[i] + '" ' + extraAttributes + '/>'); } } 上方),并简单地检查它是否具有设置为{{1 }}。如果不是,则将每个备用URL的其他<meta>元素写入输出。

答案 1 :(得分:4)

好吧,我想我现在通过结合@KirkLarkin的回答和常识来理解它。

sr-only应用于隐藏的meta元素。如果加载了引导程序,则该元素将获得position:absolute的css值。这样就进行了测试,如果是这样,则表明Bootstrap已加载。

因此,对于任何库,您都需要选择一个仅库可以执行的操作的良好示例,并为隐藏的<meta>标签设置样式,然后指定要测试的CSS样式以及期望的值。

对于javscript来说,它甚至更容易,因为您可以测试库本身,该库通常在window或DOM中添加一些众所周知的变量。因此,对于jQuery,它是window.jQuery,对于Bootstrap,它可以被测试为window.jQuery && window.jQuery.fn && window.jQuery.fn.modal,依此类推。