Everything Tether reads from your HTML, and everything it sets on it. Tether reads tether-*
attributes only; other attributes are yours. An unknown tether-* attribute, an invalid
modifier or a contradiction (passive with prevent) is a console.error in the browser.
| Attribute | On | Meaning | Details |
|---|---|---|---|
tether-on-<event>[.modifier]*="handler" |
any element | call a public method of the element's component when the DOM event happens; every DOM event type works, and so do intersect and elementresize |
Events |
tether-click tether-input tether-change tether-submit tether-keydown |
any element | short for tether-on-click and so on; take the same modifiers: tether-keydown.key-enter="add" |
Events |
tether-args="[1, \"x\"]" |
an element with a binding | JSON array passed to the handler before the field's value and the event | Events |
tether-args-<event> |
the same | like tether-args, for that event only; wins over it |
|
tether-event="shiftKey target.dataset.id" |
an element with a binding | more event data in EventArgs::$data: dotted paths, at most 32 |
Events |
$this->bind('prop') |
a field | writes value or checked and the tether-input/tether-change (with its own tether-args-input/-change) that sets a #[Bind] property; other bindings on the field are unaffected |
Components |
tether-hook="Name" |
any element | the JavaScript object registered with Tether.hook('Name', ...) lives as long as the element |
Hooks |
tether-ref="name" |
any element | a name the server finds the element by: $this->browser()->ref('name') |
JavaScript interop |
tether-ignore |
any element | a render never touches the element, its attributes or its content | tether-ignore |
tether-keep="class style" |
any element | attributes a render never overwrites once the element is on the page | Components |
tether-reload |
an <a> |
below an App, follow the link with a full page load | Apps |
tether-boost |
an <a>, or an element above links |
on a from() page, follow the links inside without a reload (="off" turns it off below) |
Navigation |
tether-id |
the root of a component | set by Tether, not by you: the component's id in the tab | Components |
Set by Tether on <html>, for your styles: tether-live while connected, tether-offline
while a lost connection is being restored, tether-crashed after the server crashed the tab, and tether-navigating while a boosted link is being fetched.
The document gets the DOM events tetherconnection and, on the element, tetherrefused
(Events).
A tether-click button inside a <form> needs type="button", or it also submits the form.
A click on a link with tether-click does not follow the link.
A modifier is a .name after the attribute: tether-on-pointermove.throttle-50.passive.
| Modifier | Meaning |
|---|---|
prevent / passive |
always / never call preventDefault(). Without either: a click on a link, a submit, a drop and a key matched by key-/code- are prevented, but only when the handler is not empty |
stop |
this binding handles the event and nothing further out does. tether-click.stop="", with no handler, sends nothing and prevents nothing: a link or checkbox inside a clickable row |
self |
only when the event's target is this element |
once |
the first time only |
capture |
also fires when an inner binding handles the event, outermost first |
window / document |
listen there instead of on the element |
outside |
the event came from outside the element: close a menu on a click elsewhere |
nofield |
not when the target is an input, a select, a textarea or editable |
held |
only while a mouse button is down |
norepeat |
key events: not the auto-repeat of a held key |
key-<k> / code-<c> |
key events: key (key-enter, key-k, key-escape) or physical code (code-keyw); several allowed. key-space, plus, minus, dot, comma, slash, equals name the punctuation |
shift ctrl alt meta mod |
the modifier keys held (mod is Cmd on macOS, Ctrl elsewhere). With key-/code- filters exactly these, so key-enter is Enter alone and ctrl.key-k not ctrl+shift+k; without a filter they are required, others ignored |
mouse pen touch |
the pointer type |
left middle right |
the button |
send latest serial drop throttle-N debounce-N |
how events leave the browser: Events. One at most |
delay-N |
for events that have an end (mouseover/mouseout, focus/blur, touchstart/touchend, pointerdown/pointerup): sent only if N ms pass before the end: hover intent, long press |
threshold-P margin-N |
intersect: percent visible, and pixels of margin |
Where each event is listened for: resize, online, offline and the other window events on
the window, visibilitychange and selectionchange on the document, so those need no .window
or .document. Every other event is listened for on the element, and the innermost matching
binding handles it.
- No DOM event object on the server: a handler gets the typed
EventArgsfor the event's type, plus whattether-eventadds. Anything else is read from the browser with$this->browser(). - No file content: a file input's chosen files arrive as
{name, size, type}, andtether-submitleaves files out. - One handler per event: the innermost binding handles it, unless an outer one says
capture.