Skip to content
Lauri Rooden edited this page Mar 13, 2026 · 1 revision

Events

LiteJS provides event delegation and a gesture system.

Event Binding

Bind events in templates with @ shorthand or ;on binding.

button
    @click fn
    // Equal to
    ;on "click", fn

String handlers emit on app:

button
    @click "save", ["draft"]
app.on("save", function(e, el, type) {
    // e     = native event
    // el    = matched element
    // type  = "draft"
})

Delegated events with a CSS selector:

El.on(list, "click", handler, ".item")
// handler(e, target) where target matches ".item"

Gesture Events

Touch and pointer gestures are automatically initialized when any gesture event is bound on an element. The system sets touch-action: none on the element.

Available Events

Event Trigger
tap Touch and release without gesture
tap2 Double tap (within 400ms)
tap3 Triple tap
holdstart Touch held for 800ms without moving
hold Continuous updates during hold
holdend Hold released
panstart Moved more than 10px from start
pan Continuous updates during pan
panend Pan released
pinch Two-finger distance change
rotate Two-finger angle change

tap fires as fallback when tap2/tap3 has no listener.

Event Properties

Gesture data is attached directly to the event object:

Property Type Description Events
e.x0 number Initial pointer clientX pan, hold
e.y0 number Initial pointer clientY pan, hold
e.dx number Delta X from start position pan, hold
e.dy number Delta Y from start position pan, hold
e.ex number Element X (dx + initial CSS left) pan, hold
e.ey number Element Y (dy + initial CSS top) pan, hold
e.diff number Distance delta (px) or angle delta (deg) pinch, rotate
e.angle number Current angle (radians) pinch
e.count number Tap count (1, 2, 3...) tap

Wheel Gestures

Ctrl+wheel emits pinch, Alt/Shift+wheel emits rotate:

Property Value
e.diff deltaY / 20
e.angle 0

Examples

Draggable HTML element:

El.on(el, {
    holdstart: function(e) {
        El.cls(el, "is-dragging")
    },
    hold: function(e) {
        El.css(el, "top,left", [e.ey + "px", e.ex + "px"])
    },
    holdend: function(e) {
        El.cls(el, "is-dragging", 0)
    }
})

Draggable SVG element:

El.on(rect, {
    pan: function(e) {
        El.set(rect, { x: e.ex, y: e.ey})
    }
})

Pinch and rotate:

El.on(el, {
    pinch: function(e) {
        // e.diff = distance change in pixels
    },
    rotate: function(e) {
        // e.diff = angle change in degrees
    }
})

In templates:

.draggable
    ;$b!moveExample
El.$b.moveExample = function(el) {
    El.on(el, {
        pan: function(e) {
            El.css(el, "top,left", [e.ey + "px", e.ex + "px"])
        }
    })
}

Configuration

Setting Default Description
LiteJS.holdDelay 800 Hold detection delay (ms)
LiteJS.tapDelay 400 Max interval between multi-taps (ms)

Notes

  • Pan threshold is 10px in any direction.
  • e.ex/e.ey read the element's initial position from SVG attributes or CSS computed style, handling percentage values.
  • Only one gesture is active at a time per element.
  • Right-click and input/textarea/select elements skip gesture detection.

Clone this wiki locally