loading

Document events

AddEventListener / SubscribeEvent / RemoveEventListener

Attach a handler to any DOM event raised on document. The Document overloads additionally let you call preventDefault or stopPropagation on every occurrence, and SubscribeEvent returns a disposable ButilSubscription.

C#
@implements IAsyncDisposable
@inject Bit.Butil.Document document

@code {
    private ButilSubscription? subscription;

    private async Task Subscribe()
    {
        subscription = await document.SubscribeEvent<ButilMouseEventArgs>(
            ButilEvents.Click,
            args => Console.WriteLine($"clicked at ({args.ClientX}, {args.ClientY})"));
    }

    public async ValueTask DisposeAsync()
    {
        if (subscription is not null) await subscription.DisposeAsync();
    }
}
Live sample

While subscribed, click anywhere on the page and watch the coordinates below.

document events output
Results will appear here when you interact with the samples.

Title and URL

GetTitle / SetTitle / GetUrl / GetDocumentURI / GetReferrer

Read or change the document title shown in the browser tab, and inspect the document's URL and the page that linked to it.

C#
string title = await document.GetTitle();
await document.SetTitle("New title from C#");

string url = await document.GetUrl();
string uri = await document.GetDocumentURI();
string referrer = await document.GetReferrer();
Live sample
New document title
title and URL output
Results will appear here when you interact with the samples.

Metadata

GetCharacterSet / GetContentType / GetCompatMode

Inspect how the browser parsed the document: its character encoding, MIME content type and whether it rendered in standards or quirks mode.

C#
string charset = await document.GetCharacterSet();   // "UTF-8"
string contentType = await document.GetContentType(); // "text/html"
CompatMode compatMode = await document.GetCompatMode(); // CSS1Compat | BackCompat
Live sample
metadata output
Results will appear here when you interact with the samples.

Text direction

GetDir / SetDir

Read or flip the directionality of the whole document between left-to-right and right-to-left - handy for runtime language switching. Auto hands the choice to the browser, which takes it from the first strongly directional character in the content - the right setting when the language is not known up front.

C#
DocumentDir dir = await document.GetDir();

await document.SetDir(DocumentDir.Rtl);
await document.SetDir(DocumentDir.Ltr);
await document.SetDir(DocumentDir.Auto);
Live sample
text direction output
Results will appear here when you interact with the samples.

Design mode

GetDesignMode / SetDesignMode

Design mode makes the entire document editable in place, the same switch developer tools use for quick copy tweaking.

C#
DesignMode mode = await document.GetDesignMode();

await document.SetDesignMode(DesignMode.On);
await document.SetDesignMode(DesignMode.Off);
Live sample

While on, every piece of text on this page can be edited by clicking into it.

design mode output
Results will appear here when you interact with the samples.

Visibility and focus

GetVisibilityState / IsHidden / HasFocus / WasDiscarded / SubscribeVisibilityChange

Query whether the page is currently visible, hidden or focused, detect tabs restored after being discarded under memory pressure, and react to visibility flips - the standard trigger for pausing timers and media.

C#
VisibilityState state = await document.GetVisibilityState();
bool hidden = await document.IsHidden();
bool focused = await document.HasFocus();
bool discarded = await document.WasDiscarded();

ButilSubscription sub = await document.SubscribeVisibilityChange(
    state => Console.WriteLine($"visibility: {state}"));
Live sample

Subscribe, then switch to another tab and back to see the change events.

visibility and focus output
Results will appear here when you interact with the samples.

Fullscreen

ExitFullscreen / SubscribeFullscreenChange / SubscribeFullscreenError

Exit the document's fullscreen element and observe fullscreen transitions. Entering fullscreen belongs to Butil's Element API (RequestFullScreen on an ElementReference); the document side handles the exit and the notifications.

C#
ButilSubscription sub = await document.SubscribeFullscreenChange(
    isFullscreen => Console.WriteLine($"fullscreen: {isFullscreen}"));

ButilSubscription errSub = await document.SubscribeFullscreenError(
    () => Console.WriteLine("entering fullscreen failed"));

await document.ExitFullscreen();
Live sample
fullscreen output
Results will appear here when you interact with the samples.

Pointer lock

ExitPointerLock / SubscribePointerLockChange / SubscribePointerLockError

Pointer lock hides the cursor and streams raw movement deltas - the input model used by first-person games. The document side releases the lock and reports lock transitions and failures.

C#
ButilSubscription sub = await document.SubscribePointerLockChange(
    isLocked => Console.WriteLine($"pointer lock: {isLocked}"));

ButilSubscription errSub = await document.SubscribePointerLockError(
    () => Console.WriteLine("acquiring pointer lock failed"));

await document.ExitPointerLock();

DOM content loaded

SubscribeDomContentLoaded

Fires when the DOMContentLoaded event is raised - useful when bootstrapping post-render work after a circuit reconnect in Blazor Server.

C#
ButilSubscription sub = await document.SubscribeDomContentLoaded(
    () => Console.WriteLine("DOM is ready"));
Warning:
Design mode affects the whole page Turning design mode on makes every element on this site editable, including the navigation. Changes are only in-memory and disappear on reload, but remember to turn it back off.
Note:
State read-back on change events The visibility, fullscreen and pointer-lock events carry no payload, so Butil reads the new state back with a follow-up interop call. Under very rapid toggles treat the reported value as latest-known rather than a strictly ordered log.

API reference

Member
Signature
Description
AddEventListener
Task AddEventListener<T>(string domEvent, Action<T> listener, bool useCapture = false, bool preventDefault = false, bool stopPropagation = false)
Attaches a handler to a DOM event on document, optionally calling preventDefault/stopPropagation on each occurrence.
RemoveEventListener
Task RemoveEventListener<T>(string domEvent, Action<T> listener, bool useCapture = false)
Detaches a previously added handler (matched by delegate identity).
SubscribeEvent
Task<ButilSubscription> SubscribeEvent<T>(string domEvent, Action<T> listener, bool useCapture = false, bool preventDefault = false, bool stopPropagation = false)
AddEventListener variant returning a disposable subscription. An overload accepts ButilEventListenerOptions (capture, passive, once, minInterval).
ButilEventListenerOptions.MinInterval
TimeSpan? MinInterval { get; set; }
Shortest time between two calls into the handler. Null or Zero (the default) forwards every event. Applied in JavaScript before the round trip, leading-edge with a trailing send - worth setting on mousemove, pointermove, scroll and selectionchange.
GetCharacterSet
Task<string> GetCharacterSet()
The character set being used by the document.
GetCompatMode
Task<CompatMode> GetCompatMode()
Whether the document rendered in standards (CSS1Compat) or quirks (BackCompat) mode.
GetContentType
Task<string> GetContentType()
The Content-Type from the MIME header of the current document.
GetDocumentURI
Task<string> GetDocumentURI()
The document location as a string.
GetDesignMode / SetDesignMode
Task<DesignMode> GetDesignMode() / Task SetDesignMode(DesignMode mode)
Reads or toggles whole-document editability.
GetDir / SetDir
Task<DocumentDir> GetDir() / Task SetDir(DocumentDir dir)
Reads or sets the document's text directionality (Ltr/Rtl/Auto). An unset dir reads as Ltr.
GetReferrer
Task<string> GetReferrer()
The URI of the page that linked to this page.
GetTitle / SetTitle
Task<string> GetTitle() / Task SetTitle(string title)
Reads or sets the document title.
GetUrl
Task<string> GetUrl()
The document location (document.URL) as a string.
ExitFullscreen
Task ExitFullscreen()
Stops the document's fullscreen element from being displayed fullscreen.
ExitPointerLock
Task ExitPointerLock()
Releases the pointer lock.
GetVisibilityState
Task<VisibilityState> GetVisibilityState()
Whether the document is currently Visible or Hidden.
IsHidden
Task<bool> IsHidden()
True when the document is currently hidden.
HasFocus
Task<bool> HasFocus()
True when the document or any element inside it has focus.
WasDiscarded
ValueTask<bool> WasDiscarded()
True when the page was restored after the browser discarded it under memory pressure.
SubscribeVisibilityChange
Task<ButilSubscription> SubscribeVisibilityChange(Action<VisibilityState> handler)
Fires with the new state whenever visibility flips.
SubscribeFullscreenChange
Task<ButilSubscription> SubscribeFullscreenChange(Action<bool> handler)
Fires with true when the document currently has a fullscreen element.
SubscribeFullscreenError
Task<ButilSubscription> SubscribeFullscreenError(Action handler)
Fires when entering fullscreen fails.
SubscribePointerLockChange
Task<ButilSubscription> SubscribePointerLockChange(Action<bool> handler)
Fires with true when an element currently holds pointer lock.
SubscribePointerLockError
Task<ButilSubscription> SubscribePointerLockError(Action handler)
Fires when acquiring pointer lock fails.
SubscribeDomContentLoaded
Task<ButilSubscription> SubscribeDomContentLoaded(Action handler)
Fires when the DOMContentLoaded event is raised.
DisposeAsync
ValueTask DisposeAsync()
Detaches every event listener this instance registered.
GetReadyState
Task<string> GetReadyState()
loading, interactive, or complete. In Blazor this is nearly always complete by the time a component can call it, since the framework has to have booted first.
GetLastModified
Task<string> GetLastModified()
When the document was last modified, in the browser's locale format - there is no ISO-8601 form. Falls back to the current time when the server sent no Last-Modified header, so it cannot distinguish just-modified from unknown.
An unhandled error has occurred. Reload 🗙