blazor - Blazor Server:仅在某些页面上加载 js 脚本,而不是在所有页面上
问题描述
建议在 _Host.cshtml 中加载 JS 库,而不是在布局中(也不在不允许的组件中)
但是这样做,怎么可能为一个页面加载一些脚本而为另一个页面加载一些脚本?例如。我只想要在我使用它们的页面中使用 googlemaps 的东西或数据表的东西,而不是全部(浪费空间/内存/加载时间)。
谢谢
解决方案
正如评论中所讨论的,Blazor 是一个 SPA,因此任何加载的脚本都可以在 Blazor 页面上使用,因为它是同一个页面。
但是,您不必将它们全部列在 中_Host.cshtml
,实际上您可能只想在需要时加载特定脚本(例如,并非所有用户都使用需要脚本的特定页面/组件)。
可以使用 JS Interop 动态加载脚本。我创建了以下scriptLoader.js
库并将其包含在_Host.cshtml
:
// loadScript: returns a promise that completes when the script loads
window.loadScript = function (scriptPath) {
// check list - if already loaded we can ignore
if (loaded[scriptPath]) {
console.log(scriptPath + " already loaded");
// return 'empty' promise
return new this.Promise(function (resolve, reject) {
resolve();
});
}
return new Promise(function (resolve, reject) {
// create JS library script element
var script = document.createElement("script");
script.src = scriptPath;
script.type = "text/javascript";
console.log(scriptPath + " created");
// flag as loading/loaded
loaded[scriptPath] = true;
// if the script returns okay, return resolve
script.onload = function () {
console.log(scriptPath + " loaded ok");
resolve(scriptPath);
};
// if it fails, return reject
script.onerror = function () {
console.log(scriptPath + " load failed");
reject(scriptPath);
}
// scripts will load at end of body
document["body"].appendChild(script);
});
}
// store list of what scripts we've loaded
loaded = [];
这将创建一个script
元素并附加到body
文档的元素。它返回一个承诺,因为脚本将异步加载,因此您需要await
在 C# 代码中。
该loaded
数组是为了避免再次重新加载脚本。任何脚本一旦加载,就会保持加载状态,除非用户刷新页面。所以负载只发生一次。
在我需要确保加载库的页面/组件上,我需要注入IJSruntime
...
@inject IJSRuntime jsRuntime
然后叫它..
protected override async Task OnAfterRenderAsync(bool firstRender)
{
// invoke script loader
Console.WriteLine("Loading jQuery");
await jsRuntime.InvokeVoidAsync("loadScript", "https://code.jquery.com/jquery-3.4.1.js");
await jsRuntime.InvokeVoidAsync("loadScript", "myJQueryTest.js");
Console.WriteLine("Invoking jQuery");
await jsRuntime.InvokeVoidAsync("setH1", "Hello world!");
Console.WriteLine("Invoked JQuery");
await base.OnAfterRenderAsync(firstRender);
}
myJQueryTest.js
很简单:
window.setH1 = function (message) {
$('h1').text(message);
}
创建的演示仓库:https ://github.com/conficient/BlazorDynamicScriptLoad
推荐阅读
- typescript - Visual Studio Code 中的自动导入仅在 TypeScript 中提供带有 Lerna 子包的绝对路径
- java - 如何为 selenium webdriver 检索元素的文本值
- oracle - Execute multiple Oracle SQL statements simultaneously
- bash - Bash如何减去用户每次输入的猜测次数?
- javascript - 用户停止输入后运行函数
- python - Python 包和方法未导入
- android - 减少安卓应用程序内存消耗的好处
- c# - Acumatica - 另一个进程已添加/更新记录 - 使用 DAC 和图形扩展创建库存项目
- haskell - 野外 LTS 的发病率是多少?
- c# - C# 上的简化 LDAP/AD 服务器