11. Подключение JavaScript
Подключение JavaScript.
Подключить JavaScript к компоненту
Для обычной сторонней библиотеки есть IJsPoeBlazorUtils.LoadScript(string scriptPath). Он загружает классический скрипт и возвращает Task; это не импорт ES-модуля и не регистрация с автоматической очисткой. Если библиотека требует собственных файлов, глобальных объектов или завершения работы, это отдельный контракт самой библиотеки.
Для собственного поведения удобнее ES-модуль. Создадим кнопку, которая через JavaScript меняет текст соседнего элемента. Код не требует глобальных функций или подписок на DOM-события.
Файлы C# Overlay v3
Создайте ауру с C# Overlay v3. Добавьте файл Status.js в ресурсы проекта (см. встроенные ресурсы). Его полный manifest-путь зависит от пространства имён: ниже используется MyScript.Status.js. Замените его фактическим именем своего ресурса; отладочный журнал подготовки скрипта перечисляет manifest-имена. При папках имя включает и их: MyScript.UI.Status.js. Простое окончание имени не является универсальным путём.
Замените UserOverlay.razor целиком; в UserOverlay.cs не должно быть прежних одноимённых полей или методов. Хост предоставляет файловый провайдер проекта и внедряет JsRuntime в BlazorReactiveComponent.
Status.js
export function setStatus(element, text) {
element.textContent = text;
}
UserOverlay.razor
@using System.Threading.Tasks
@using Microsoft.AspNetCore.Components
@using Microsoft.JSInterop
@using Microsoft.AspNetCore.Components.Web
@using PoeShared.Blazor
@inherits BlazorReactiveComponent
<button class="btn btn-primary" disabled="@(module == null)" @onclick="ShowStatus">
Изменить текст через JS
</button>
<span @ref="statusElement">Ожидание</span>
@code {
private ElementReference statusElement;
private IJSObjectReference module;
protected override async Task OnAfterFirstRenderAsync()
{
await base.OnAfterFirstRenderAsync();
module = await JsRuntime.InvokeAsync<IJSObjectReference>(
"import", "./MyScript.Status.js");
await Refresh("module-loaded");
}
private async Task ShowStatus()
{
await module.InvokeVoidAsync("setStatus", statusElement, "Готово");
}
public override async ValueTask DisposeAsync()
{
try
{
if (module != null)
{
await module.DisposeAsync();
}
}
finally
{
await base.DisposeAsync();
}
}
}
После первого рендера загружается модуль и становится доступна кнопка. Нажмите её: вместо «Ожидание» появится «Готово». Импорт и вызовы нужно ожидать через await; отсутствие ресурса проверяйте по полному пути и ошибкам WebView2. Пример рассчитан на хост, который раздаёт этот ресурс по указанному URL.
При уничтожении компонента освобождается IJSObjectReference. Если вы добавите в JS таймеры, обработчики событий или экземпляры библиотеки, одного DisposeAsync ссылки недостаточно: экспортируйте метод очистки и вызовите его перед освобождением модуля. DOM этого примера меняется только в выделенном span, дочерним содержимым которого Razor не управляет.
Загрузить классический скрипт
Для уже существующей интеграции внедрите в компонент PoeShared.Blazor.Services.IJsPoeBlazorUtils через [Inject] и в OnAfterFirstRenderAsync вызовите await PoeBlazorUtils.LoadScript("MyScript.Library.js"), указав реальный полный путь ресурса. Для CSS есть await PoeBlazorUtils.LoadCss("MyScript.Styles.css"). Это дополнение к примеру выше, а не код для импорта Status.js: у него экспортируемые функции ES-модуля.
В старом примере из набора этой серии так подключались rgba.js с CDN, локальный Script.js и CSS для canvas. Следующая иллюстрация показывает тот вариант анимации; простой пример выше меняет только текст. Доступность CDN и контракт сторонней библиотеки нужно проверять отдельно.
