XRSession: squeezeend event

Secure context

This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.

The WebXR event squeezeend is sent to an XRSession when one of its input sources ends its primary action or when an input source that's in the process of handling an ongoing primary action is disconnected without successfully completing the action. Primary squeeze actions include things like users pressing triggers or buttons, tapping a touchpad, speaking a command, or performing a recognizable gesture when using a video tracking system or handheld controller with an accelerometer.

Bubbles Yes
Cancelable No
Interface XRInputSourceEvent
Event handler property onsqueezeend

For details on how the squeezestart, squeeze, and squeezeend events work, and how you should react to them, see Primary squeeze actions in Inputs and input sources.


The following example uses addEventListener() to establish handlers for the squeezeion events: squeezestart, squeezeend, and squeeze. This snippet is the core of an event handler to allow the user to grab objects in the scene and move them around.

In this case, a single function is used to handle all three events, allowing them to share certain code that's the same regardless of which of the three events is received. Only after completing those tasks does the onSqueezeEvent() function below dispatch the action out to a specialized function to handle things.

After checking to ensure that the received event is a tracked-pointer event (the only kind we handle here), the target ray's pose is obtained using getPose().

If the target ray pose was fetched successfully, the code then uses the value of Event property type to route control to an appropriate function to handle the event which arrived:

  • For squeezestart events, a myBeginTracking() function is called with the target ray pose's matrix. The myBeginTracking() function would presumably start the presentation of the object-dragging process, using the transform to perform a hit test, determining which object to pick up. myBeginTracking() returns an object representing the object the user has begun to drag.
  • Upon receiving a squeeze event, the myDropObject() function is called with the target object and the current target ray pose transform as inputs. This places the object into its new position in the world and triggers any effects that may arise from doing so (like scheduling an animation of a splash if dropped in water, etc).
  • The squeezeend event results in a myStopTracking() function being called with the object being dragged and the final target ray pose's transform.
xrSession.addEventListener("squeezestart", onSqueezeEvent);
xrSession.addEventListener("squeeze", onSqueezeEvent);
xrSession.addEventListener("squeezeend", onSqueezeEvent);

function onSqueezeEvent(event) {
  let source = event.inputSource;
  let targetObj = null;

  if (source.targetRayMode != "tracked-pointer") {

  let targetRayPose = event.frame.getPose(source.targetRaySpace, myRefSpace);
  if (!targetRayPose) {

  switch(event.type) {
    case "squeezestart":
      targetObj = myBeginTracking(targetRayPose.matrix);
    case "squeeze":
      myDropObject(targetObj, targetRayPose.matrix);
    case "squeezeend":
      myStopTracking(targetObj, targetRayPose.matrix);

You can of course also set up a handler these events by setting the XRSession object's onsqueezeend event handler property to a function that handles the event:

xrSession.onsqueezestart = onSqueezeEvent;
xrSession.onsqueeze = onSqueezeEvent;
xrSession.onsqueezeend = onSqueezeEvent;


Specification Status Comment
WebXR Device API
The definition of 'squeezeend event' in that specification.
Working Draft Initial definition.

Browser compatibility

No compatibility data found for api.XRSession.squeezeend_event.
Check for problems with this page or contribute missing data to mdn/browser-compat-data.