使用 ASP.NET Core Razor Pages 中的 JavaScript 更改活动导航栏 link
Change active navbar link using JavaScript in ASP.NET Core Razor Pages
我在 Razor-Pages
中导航时需要更改导航栏 link 颜色。我尝试使用 JavaScript
,但似乎每次我转到另一个页面时页面都会重新呈现,我无法 toggle
我的元素。
这是我目前尝试过的方法:
导航栏links
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between ml-5">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link active-link" asp-area="" asp-page="/Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" asp-area="" asp-page="/Privacy">Privacy</a>
</li>
<li class="nav-item">
<a class="nav-link" asp-page="/Movies/Index">Movies</a>
</li>
<li class="nav-item">
<a class="nav-link" asp-page="/Genres/Index">Genres</a>
</li>
</ul>
</div>
site.js
const links = document.querySelectorAll('.nav-link');
let currentActive = document.querySelector('.active-link');
const changeClass = (e) => {
//e.preventDefault();
currentActive.classList.remove('active-link');
e.target.classList.add('active-link');
};
links.forEach((el) => el.addEventListener('click', changeClass));
在这里,我将当前 active link
保存在我的 js
中,当我导航到另一个页面时,该页面会重新呈现并且我的 js
文件会再次重新加载,以便值我之前是设置回默认的active link
.
我有:
我想要的:
我找到了一个 ,但它似乎有点硬编码和变通,我相信应该有更好的方法。
P.S。理想情况下,使用 JavaScript
的解决方案是最好的,但是,我不坚持这里的任何内容。
使用 DOMContentLoaded
事件而不是点击事件。这样,更改将在呈现后应用于实际页面。目前,您正在将更改应用于您正在导航的页面上的链接:
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('.nav-link').forEach(link => {
if (link.getAttribute('href').toLowerCase() === location.pathname.toLowerCase()) {
link.classList.add('active-link');
} else {
link.classList.remove('active-link');
}
});
})
不一定需要javascript。
TagHelpers 可用于服务器端解决方案,请参阅我在类似问题上的回答 。
例如,标签助手在导航栏元素上使用自定义属性来描述每个 link 对应的页面。然后tag helper在处理这个属性的时候,会把这个值和当前地址进行比较,如果匹配,就加上active
class.
它还会删除该属性,使其在响应中对用户不可用 HTML。在服务器端执行此操作还可以确保禁用 javascript 的用户可以使用突出显示。
我遇到了同样的问题并开始使用这种方法:为每个页面创建不同的布局。每个布局都突出显示了感兴趣的 link。问题是你有很多布局,只有导航栏 links.
所以,我决定改进解决方案,我终于比预期简单得多:
这里是第二种方法的片段:
// _Layout.cshtml
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-page="/Index">VS22Netcore01</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul id="mainMenu" class="navbar-nav flex-grow-1">
<li class="nav-item">
**<a id="linkHome"** class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
</li>
<li class="nav-item">
**<a id="linkPrivacy"** class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
</li>
<li class="nav-item">
**<a id="linkAbout"** class="nav-link text-dark" asp-area="" asp-page="/About">Acerca de</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody() <!-- inserta la pagina en el container} -->
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2021 - VS22Netcore01 - <a asp-area="" asp-page="/Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
**@await RenderSectionAsync("Scripts", required: true)**
</body>
请注意双星号之间的代码。
然后,在每个内容页面中我添加了如下内容:
//Privacy.cshtml, a sample page
@page
@model PrivacyModel
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p>
@section Scripts
{
<script>
**$('#linkPrivacy').removeClass('text-dark');
$('#linkPrivacy').addClass('text-info');**
</script>
}
如您所见,每个内容页面中的脚本都会更改 link 的样式。
这样你就有了不同的“轻微”页面。
此致
我在 Razor-Pages
中导航时需要更改导航栏 link 颜色。我尝试使用 JavaScript
,但似乎每次我转到另一个页面时页面都会重新呈现,我无法 toggle
我的元素。
这是我目前尝试过的方法:
导航栏links
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between ml-5">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link active-link" asp-area="" asp-page="/Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" asp-area="" asp-page="/Privacy">Privacy</a>
</li>
<li class="nav-item">
<a class="nav-link" asp-page="/Movies/Index">Movies</a>
</li>
<li class="nav-item">
<a class="nav-link" asp-page="/Genres/Index">Genres</a>
</li>
</ul>
</div>
site.js
const links = document.querySelectorAll('.nav-link');
let currentActive = document.querySelector('.active-link');
const changeClass = (e) => {
//e.preventDefault();
currentActive.classList.remove('active-link');
e.target.classList.add('active-link');
};
links.forEach((el) => el.addEventListener('click', changeClass));
在这里,我将当前 active link
保存在我的 js
中,当我导航到另一个页面时,该页面会重新呈现并且我的 js
文件会再次重新加载,以便值我之前是设置回默认的active link
.
我有:
我想要的:
我找到了一个
P.S。理想情况下,使用 JavaScript
的解决方案是最好的,但是,我不坚持这里的任何内容。
使用 DOMContentLoaded
事件而不是点击事件。这样,更改将在呈现后应用于实际页面。目前,您正在将更改应用于您正在导航的页面上的链接:
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('.nav-link').forEach(link => {
if (link.getAttribute('href').toLowerCase() === location.pathname.toLowerCase()) {
link.classList.add('active-link');
} else {
link.classList.remove('active-link');
}
});
})
不一定需要javascript。
TagHelpers 可用于服务器端解决方案,请参阅我在类似问题上的回答
例如,标签助手在导航栏元素上使用自定义属性来描述每个 link 对应的页面。然后tag helper在处理这个属性的时候,会把这个值和当前地址进行比较,如果匹配,就加上active
class.
它还会删除该属性,使其在响应中对用户不可用 HTML。在服务器端执行此操作还可以确保禁用 javascript 的用户可以使用突出显示。
我遇到了同样的问题并开始使用这种方法:为每个页面创建不同的布局。每个布局都突出显示了感兴趣的 link。问题是你有很多布局,只有导航栏 links.
所以,我决定改进解决方案,我终于比预期简单得多:
这里是第二种方法的片段:
// _Layout.cshtml
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-page="/Index">VS22Netcore01</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul id="mainMenu" class="navbar-nav flex-grow-1">
<li class="nav-item">
**<a id="linkHome"** class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
</li>
<li class="nav-item">
**<a id="linkPrivacy"** class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
</li>
<li class="nav-item">
**<a id="linkAbout"** class="nav-link text-dark" asp-area="" asp-page="/About">Acerca de</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody() <!-- inserta la pagina en el container} -->
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2021 - VS22Netcore01 - <a asp-area="" asp-page="/Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
**@await RenderSectionAsync("Scripts", required: true)**
</body>
请注意双星号之间的代码。
然后,在每个内容页面中我添加了如下内容:
//Privacy.cshtml, a sample page
@page
@model PrivacyModel
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p>
@section Scripts
{
<script>
**$('#linkPrivacy').removeClass('text-dark');
$('#linkPrivacy').addClass('text-info');**
</script>
}
如您所见,每个内容页面中的脚本都会更改 link 的样式。 这样你就有了不同的“轻微”页面。
此致