aspnetcore: @onevent:preventDefault does not trigger when event is not already registered
When using the new @onevent:preventDefault directive to prevent the default event behavior for events, I noticed that in order for this to work, there needs to be a @onevent handler registered anywhere on the page.
Apparently, server-side Blazor registers every event just once on the document instead of on individual elements. So e.g. @onclick="…" causes the click event to be subscribed on the document. Just using @onclick:preventDefault on the page does not appear to register this global event handler on document, so the preventDefault() call is also never made in the handler.
My use case for this is managing focus with buttons: When you click a button, then the button stays focused after clicking it, causing the focused style to be applied. In order to avoid this, you can subscribe to the mousedown event in JavaScript and just prevent the default behavior:
<button id="test">Test</button>
<script>
var button = document.getElementById('test')
button.addEventListener('click', () => console.log('Clicked'));
button.addEventListener('mousedown', (evt) => evt.preventDefault());
</script>
Doing the same in Blazor would look like this:
<button @onclick="Click" @onmousedown:preventDefault>Test</button>
@code {
void Click() => Console.WriteLine("Click");
}
This however does not work if there isn’t also some mousedown handler registered somewhere. As soon as you add one literally anywhere, it works:
<button @onclick="Click" @onmousedown:preventDefault>Test</button>
<div @onmousedown="() => { }"></div>
@code {
void Click() => Console.WriteLine("Click");
}
This is using server-side Blazor on ASP.NET Core 3.1.
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 10
- Comments: 15 (12 by maintainers)
There’s been a bit of confusion here. I think there is a bug to be addressed here.
That’s not how this was designed - see #14517:
I do agree there are valid use cases for using preventDefault/stopPropagation independently of handlers for the same event on the same element; that’s something we always intended to support and in fact do support today. The bug is when you happen not to have any handlers for a given event type anywhere in the document.
@danroth27 Let’s discuss it with the team. I don’t think the risk is particularly high though if we implemented a fix we’d have a more precise sense of how disruptive the change is.
Thanks for contacting us.
We’re moving this issue to the
.NET 9 Planningmilestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it’s very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.This is still the issue. I was trying to make sure that event is not propagated outside of some element, e.g. Google Maps, using the mouse scroll user can scale the map, but the page that contains this map should not scroll. In case of Blazor, everything is scrollable, no matter how I try to stop the propagation outside of the element.
In JS, simple
preventDefaultdoes the trick. http://jsfiddle.net/eXQf3/371/@SteveSandersonMS @javiercn Is this something we think we can still address for .NET 7? Or is the risk too high at this point?
any updates? It’s been
2 years + 1 dayexactly now 😀Facing the same issue )":
But that’s not what is the case here. Please note that in my example, I use
@onmousedown:preventDefaulton a button element while I have to apply@onmousedownon literally any other element.Your statement makes it sound as if you would need to put both on the same element like this:
If that was the case, I would probably accept this (although I would really dislike it). But the thing is that you do not need
@onmousedownon the element. You just need it somewhere throughout the whole app to make Blazor’s client side runtime register the event once on the document element.The fact that this is so disconnected from the
@onmousedown:preventDefaultmakes this very confusing, and definitely not “simpler to understand and explain”. And considering that this ispreventDefaultit is also very common to put this on events that you will usually not care about, so requiring an empty event handler just to make Blazor realize that the event handler is needed feels very redundant.I understand the desire to keep the
attribute:modifierhandling simple but it shouldn’t be too problematic to make@event:modifieralso trigger an empty registration of@event.