Javascript 单击事件在 Blazor 客户端应用程序中不起作用
Javascript click event not working in Blazor client side app
我是 Blazor 的新手,我创建了一个非常简单的 Webassembly 应用程序。我希望 href link 在我单击它时转到页面下方的 div,但是 Javascript 单击事件不起作用。在 Index.razor 页面中,JsRuntime.InvokeVoidAsync("clicker")
正在工作,并且 alert("In clicker")
在页面加载时发生,但是点击 / href 转到 "intro" div 将不起作用为了爱和金钱 :-/
index.html
<!DOCTYPE html>
<html>
<head>
<title>My Blazor App</title>
<!--script type='text/javascript' src='./scripts/app.js'-->
</head>
<body>
<app>Loading...</app>
<script src="_framework/blazor.webassembly.js"></script>
<script>
function clicker() {
alert("In clicker"); // this works
document.getElementById('skip').onclick = function(e){
alert("clicked"); // this works but the page still won't scroll to the "intro" div :(
}
}
//clicker();
</script>
</body>
</html>
Index.razor(@code 部分在页面顶部)
@page "/"
@code {
[Inject]
protected IJSRuntime JsRuntime { get; set; }
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
JsRuntime.InvokeVoidAsync("clicker");
}
}
}
// This link won't go to the intro div when clicked :(
<a id="skip" class="skip" href="#intro">skip this bit</a>
...
<div id="intro" class="home">
...
</div>
Startup.cs
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
}
public void Configure(IComponentsApplicationBuilder app)
{
app.AddComponent<App>("app");
}
}
如果有人能对此有所了解,那将节省我一周的时间。
这里不需要JavaScript
如果您将特定目标添加到您的标记中,它就会起作用。
您可以使用 target="_top" 来避免 Blazor 导航拦截。
<a class="skip" href="#intro" target="_top">skip this bit</a>
...
<div id="intro" class="home">
...
</div>
请注意,target="_top"
只是指示浏览器在 window 中的最顶部框架内导航,并不意味着您将滚动到顶部!
页面不会滚动到您在 link.This 中指定的元素,这与 Blazor 和大多数其他 SPA 应用程序中的路由处理方式有关。一个简单的解决方案是您可以创建自己的 AnchorLink 组件并使用一些 JavaScript 互操作魔法。
1.Create AnchorLink.razor
在 Pages/Shared
@code {
public AnchorLink()
{
this.Attributes = new Dictionary<string, object>();
}
private string targetId = null;
private bool preventDefault = false;
/// <summary>
/// This parameter supports arbitrary attributes.
/// </summary>
/// <remarks>
/// Any attribute specified on the component, which is not defined as a parameter, whill be added to this dictionary.
/// It is then uses as the source for attributes rendered onto the resulting HTML element below in the markup section
/// of this component.
/// For details, refer to <see cref="https://docs.microsoft.com/en-us/aspnet/core/blazor/components#attribute-splatting-and-arbitrary-parameters"/>.
/// </remarks>
[Parameter(CaptureUnmatchedValues = true)]
public IDictionary<string, object> Attributes { get; set; }
/// <summary>
/// Supports child content for the component.
/// </summary>
/// <see cref="https://docs.microsoft.com/en-us/aspnet/core/blazor/components#child-content"/>
[Parameter]
public RenderFragment ChildContent { get; set; }
[Inject]
protected IJSRuntime JsInterop { get; set; }
protected override void OnParametersSet()
{
string href = null;
if (this.Attributes.ContainsKey("href"))
{
// If the href attribute has been specified, we examine the value of it. If if starts with '#'
// we assume the rest of the value contains the ID of the element the link points to.
href = $"{this.Attributes["href"]}";
if (href.StartsWith("#"))
{
// If the href contains an anchor link we don't want the default click action to occur, but
// rather take care of the click in our own method.
this.targetId = href.Substring(1);
this.preventDefault = true;
}
}
base.OnParametersSet();
}
private async Task AnchorOnClickAsync()
{
if (!string.IsNullOrEmpty(this.targetId))
{
// If the target ID has been specified, we know this is an anchor link that we need to scroll
// to, so we call the JavaScript method to take care of this for us.
await this.JsInterop.InvokeVoidAsync("anchorLink.scrollIntoView", this.targetId);
}
}
}
<a href="" @onclick="this.AnchorOnClickAsync" @onclick:stopPropagation="false" />
<a @attributes="this.Attributes" @onclick="this.AnchorOnClickAsync" @onclick:preventDefault="this.preventDefault">Hello @this.ChildContent</a>
2.Add wwwroot/Index.html
中的 js
<script src="_framework/blazor.webassembly.js"></script>
<script>
window.anchorLink = {
scrollIntoView: function (elementId) {
// This function is called from the AnchorLink component using JavaScript interop.
// It will try to find an element using the ID given to the function, and scroll that
// element into view, if an element is found.
var elem = document.getElementById(elementId);
if (elem) {
elem.scrollIntoView();
window.location.hash = elementId;
}
}
}
</script>
3.Index.razor
<AnchorLink class="skip" href="#intro">skip this bit</AnchorLink>
参考https://mikaberglund.com/2019/12/28/creating-anchor-links-in-blazor-applications/
我是 Blazor 的新手,我创建了一个非常简单的 Webassembly 应用程序。我希望 href link 在我单击它时转到页面下方的 div,但是 Javascript 单击事件不起作用。在 Index.razor 页面中,JsRuntime.InvokeVoidAsync("clicker")
正在工作,并且 alert("In clicker")
在页面加载时发生,但是点击 / href 转到 "intro" div 将不起作用为了爱和金钱 :-/
index.html
<!DOCTYPE html>
<html>
<head>
<title>My Blazor App</title>
<!--script type='text/javascript' src='./scripts/app.js'-->
</head>
<body>
<app>Loading...</app>
<script src="_framework/blazor.webassembly.js"></script>
<script>
function clicker() {
alert("In clicker"); // this works
document.getElementById('skip').onclick = function(e){
alert("clicked"); // this works but the page still won't scroll to the "intro" div :(
}
}
//clicker();
</script>
</body>
</html>
Index.razor(@code 部分在页面顶部)
@page "/"
@code {
[Inject]
protected IJSRuntime JsRuntime { get; set; }
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
JsRuntime.InvokeVoidAsync("clicker");
}
}
}
// This link won't go to the intro div when clicked :(
<a id="skip" class="skip" href="#intro">skip this bit</a>
...
<div id="intro" class="home">
...
</div>
Startup.cs
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
}
public void Configure(IComponentsApplicationBuilder app)
{
app.AddComponent<App>("app");
}
}
如果有人能对此有所了解,那将节省我一周的时间。
这里不需要JavaScript
如果您将特定目标添加到您的标记中,它就会起作用。
您可以使用 target="_top" 来避免 Blazor 导航拦截。
<a class="skip" href="#intro" target="_top">skip this bit</a>
...
<div id="intro" class="home">
...
</div>
请注意,target="_top"
只是指示浏览器在 window 中的最顶部框架内导航,并不意味着您将滚动到顶部!
页面不会滚动到您在 link.This 中指定的元素,这与 Blazor 和大多数其他 SPA 应用程序中的路由处理方式有关。一个简单的解决方案是您可以创建自己的 AnchorLink 组件并使用一些 JavaScript 互操作魔法。
1.Create AnchorLink.razor
在 Pages/Shared
@code {
public AnchorLink()
{
this.Attributes = new Dictionary<string, object>();
}
private string targetId = null;
private bool preventDefault = false;
/// <summary>
/// This parameter supports arbitrary attributes.
/// </summary>
/// <remarks>
/// Any attribute specified on the component, which is not defined as a parameter, whill be added to this dictionary.
/// It is then uses as the source for attributes rendered onto the resulting HTML element below in the markup section
/// of this component.
/// For details, refer to <see cref="https://docs.microsoft.com/en-us/aspnet/core/blazor/components#attribute-splatting-and-arbitrary-parameters"/>.
/// </remarks>
[Parameter(CaptureUnmatchedValues = true)]
public IDictionary<string, object> Attributes { get; set; }
/// <summary>
/// Supports child content for the component.
/// </summary>
/// <see cref="https://docs.microsoft.com/en-us/aspnet/core/blazor/components#child-content"/>
[Parameter]
public RenderFragment ChildContent { get; set; }
[Inject]
protected IJSRuntime JsInterop { get; set; }
protected override void OnParametersSet()
{
string href = null;
if (this.Attributes.ContainsKey("href"))
{
// If the href attribute has been specified, we examine the value of it. If if starts with '#'
// we assume the rest of the value contains the ID of the element the link points to.
href = $"{this.Attributes["href"]}";
if (href.StartsWith("#"))
{
// If the href contains an anchor link we don't want the default click action to occur, but
// rather take care of the click in our own method.
this.targetId = href.Substring(1);
this.preventDefault = true;
}
}
base.OnParametersSet();
}
private async Task AnchorOnClickAsync()
{
if (!string.IsNullOrEmpty(this.targetId))
{
// If the target ID has been specified, we know this is an anchor link that we need to scroll
// to, so we call the JavaScript method to take care of this for us.
await this.JsInterop.InvokeVoidAsync("anchorLink.scrollIntoView", this.targetId);
}
}
}
<a href="" @onclick="this.AnchorOnClickAsync" @onclick:stopPropagation="false" />
<a @attributes="this.Attributes" @onclick="this.AnchorOnClickAsync" @onclick:preventDefault="this.preventDefault">Hello @this.ChildContent</a>
2.Add wwwroot/Index.html
<script src="_framework/blazor.webassembly.js"></script>
<script>
window.anchorLink = {
scrollIntoView: function (elementId) {
// This function is called from the AnchorLink component using JavaScript interop.
// It will try to find an element using the ID given to the function, and scroll that
// element into view, if an element is found.
var elem = document.getElementById(elementId);
if (elem) {
elem.scrollIntoView();
window.location.hash = elementId;
}
}
}
</script>
3.Index.razor
<AnchorLink class="skip" href="#intro">skip this bit</AnchorLink>
参考https://mikaberglund.com/2019/12/28/creating-anchor-links-in-blazor-applications/