Как я могу сделать простой переход к части уже загруженной страницы в Blazor? Вот так в HTML:
<a href = "#contact">Contact us</a>
...
<section id = "contact">
В идеале я также хочу, чтобы он плавно прокручивался до этого раздела. Думал, что попытаюсь решить это с помощью CSS, но, может быть, это невозможно?
@BabakNaffas, этот метод обычно не работает с приложениями SPA, такими как Blazor.
Спасибо @KirkWoll. Хорошо знать.





Что вам нужно, так это функции хэшированных маршрутов Blazor. Но, увы, таких функций пока нет. Я предлагаю вам использовать JSIterop для выполнения этой задачи: создайте JavaScript, который выполняет навигацию, и передайте ему объект ElementRef.
Надеюсь это поможет...
Редактировать: Ниже приведена адаптация лучшего обходного решения, которое я нашел в Github...
Обычно, когда вы нажимаете ссылку на контакт, вы перенаправляетесь на маршрут http://локальный: 5000/моя страница#контакт, но окажетесь в верхней части страницы. Фрагмент маршрута не используется для выбора конкретного HTML-элемента.
Текущий обходной путь — написать явный код, который интерпретирует URL-адрес. В приведенном выше примере мы могли бы использовать немного JavaScript, а затем вызвать его из нашего кода Blazor:
моя страница.cshtml:
@page "/mypage"
@inject Microsoft.AspNetCore.Components.Services.IUriHelper UriHelper
<nav>
<a href = "#contact">contact</a>
</nav>
<section>
<h2 id = "contact">contact</h2>
</section>
@functions {
protected override void OnInit()
{
NavigateToElement();
UriHelper.OnLocationChanged += OnLocationChanges;
}
private void OnLocationChanges(object sender, string location) => NavigateToElement();
private void NavigateToElement()
{
var url = UriHelper.GetAbsoluteUri();
var fragment = new Uri(url).Fragment;
if (string.IsNullOrEmpty(fragment))
{
return;
}
var elementId = fragment.StartsWith("#") ? fragment.Substring(1) : fragment;
if (string.IsNullOrEmpty(elementId))
{
return;
}
ScrollToElementId(elementId);
}
private static bool ScrollToElementId(string elementId)
{
return JSRuntime.Current.InvokeAsync<bool>("scrollToElementId", elementId).GetAwaiter().GetResult();
}
}
индекс.html:
<script>
window.scrollToElementId = (elementId) => {
console.info('scrolling to element', elementId);
var element = document.getElementById(elementId);
if (!element)
{
console.warn('element was not found', elementId);
return false;
}
element.scrollIntoView();
return true;
}
</script>
Примечание. Если вы используете Blazor версии .9.0, вам следует внедрить IJSRuntime Пожалуйста, дайте мне знать, если это решение работает для вас...
Хороший Исаак, помните, что JSRuntime.Current больше не поддерживается. Теперь ( >= 0.9.0 ) вы должны создать экземпляр JSRuntime через DI. :)
Пробовал. Microsoft Edge прокручивается до нужной области, затем не реагирует, когда я нажимаю другие ссылки в навигации. Chrome и Firefox вообще не прокручиваются, и при переходе по другим ссылкам в навигации ничего не происходит. Тем не менее, действительно цените усилия! Было бы неплохо, если бы кто-то еще попробовал это, чтобы я знал, есть ли что-то еще на моем сайте, что вызывает проблемы. Обратите внимание, я использую Blazor 0.7.0.
Я попробовал это сейчас в Blazor 0.9.0. С проектом по умолчанию, который создается при создании нового проекта Blazor. Просто чтобы посмотреть, не было ли на моем сайте чего-то странного, что мешало ему работать. Там тоже не работал. На странице github, где вы ее нашли, я вижу, что он прокомментировал: «Предлагаемый обходной путь не работает, так как браузер дает сбой и предназначен только для иллюстрации». Так что нам просто придется подождать, я думаю.
Тот же ответ, что и ответ Исаака, но нужно изменить код.
Я обнаружил, что основная проблема заключается в том, что вам нужно, чтобы он был асинхронным. @johajan
@inject IJSRuntime JSRuntime
...
@functions {
protected override async Task OnInitAsync()
{
await base.OnInitAsync();
//NavigateToElement();
UriHelper.OnLocationChanged += OnLocationChanges;
}
private async Task OnLocationChanges(object sender, string location) => await NavigateToElement();
private async Task NavigateToElement()
{
var url = UriHelper.GetAbsoluteUri();
var fragment = new Uri(url).Fragment;
if (string.IsNullOrEmpty(fragment))
{
return;
}
var elementId = fragment.StartsWith("#") ? fragment.Substring(1) : fragment;
if (string.IsNullOrEmpty(elementId))
{
return;
}
await ScrollToElementId(elementId);
}
private Task<bool> ScrollToElementId(string elementId)
{
return JSRuntime.InvokeAsync<bool>("scrollToElementId", elementId);
}
}
Я решил эту проблему, используя button, а затем написав в разметке некоторый встроенный Javascript. Вы можете обобщить это на компонент Blazor для получения бонусных баллов!
<button type = "button" onclick = "document.getElementById('contact').scrollIntoView({behavior:'smooth'})">Contact us</button>
...
<section id = "contact">
Спасибо, это почти решило это для меня! Смотрите мое решение, чтобы добавить к этому.
Я не вижу, что отличается от вашего ответа, но рад, что вы на правильном пути
Я использовал ответ Аррона Хадона, и он все еще не работал. Однако, поиграв, я понял, что это не сработает с якорным элементом: <a id='star_wars'>Place to jump to</a>. Очевидно, у Blazor и других спа-фреймворков есть проблемы с переходом на якоря на той же странице. Чтобы обойти это, мне пришлось использовать вместо этого элемент абзаца (раздел тоже сработает): <p id='star_wars'>Some paragraph<p>.
Пример использования бутстрапа:
<button class = "btn btn-link" onclick = "document.getElementById('star_wars').scrollIntoView({behavior:'smooth'})">Star Wars</button>
... lots of other text
<p id = "star_wars">Star Wars is an American epic...</p>
Обратите внимание, что я использовал класс начальной загрузки btn-link, чтобы кнопка выглядела как гиперссылка.
Вы можете использовать 2 пакета Nuget, чтобы решить эту проблему:
IScrollHandler, который представляет собой инъекционный сервис. Вы можете попробовать это с демо-приложение. Вы можете видеть, что scrollIntoView() и другие функции JS обернуты, доступна плавная прокрутка. Намного проще использовать поддержку прокрутки JS...<a>, но вам не нужно беспокоиться об этом (обратите внимание, что даже демо-приложение имеет # URL-адреса). Также отображает компонент «ссылка» с интерактивным значком и действиями навигации/копирования. В настоящее время плавная прокрутка недоступна, но ее можно запросить. Вы можете попробовать это с демо-приложение.

Возможный дубликат Автофокус на элементе <a> без JavaScript