References

Beginner-friendly references for web development, with live, editable examples.

The HTML onpause event

Event All modern browsers
In short

The HTML onpause attribute runs JavaScript when an <audio> or <video> element pauses, as in <video onpause="saveTime(this)">. It fires after pause() returns, when the user presses pause, and when media that doesn't loop reaches its end.

Overview

The HTML onpause attribute handles the pause event of an <audio> or <video> element. The event fires once the element is in its paused state, so this.paused is already true inside the handler. The pause event doesn't bubble, and calling preventDefault() on it doesn't undo the pause.

A call to pause() sets paused right away and fires the event after the method returns. Pressing pause in the video's built-in controls fires it too. Removing a playing element from the page also pauses it, and the event fires once the script that removed it has finished.

The end of playback counts as well. When media without the loop attribute reaches its end, paused turns true and pause fires right before ended, so this.ended reads true in that handler.

Pause also explains a familiar console error. The play() method returns a promise, and when pause() runs before a still-loading video can start, that promise rejects with an AbortError. Chrome words it as The play() request was interrupted by a call to pause().

Syntax

<video src="clip.mp4" controls onpause="saveTime(this)"></video>

Example

Live example
<video id="clip" src="https://codeshack.io/web/example.mp4" controls muted width="240" onpause="logPause(this)"></video>
<p id="msg" role="status">Play the video, then pause it.</p>
<script>
let pauses = 0;
function logPause(video) {
  pauses++;
  const where = video.ended ? 'at the end' : 'at ' + video.currentTime.toFixed(1) + ' s';
  document.getElementById('msg').textContent = 'Paused ' + where + ' (pause ' + pauses + ')';
}
</script>

Best practices

  • Check this.ended inside the onpause handler when a finished video needs different handling from a manual pause.
  • Update a custom play button's label from onpause and onplay, not from the button's own click handler. Pauses from the built-in controls or the end of the media then show up too.
  • Don't restart playback from inside onpause. A pause usually means the person wanted it to stop.
  • Give the function that onpause calls a name the element doesn't use, such as logPause rather than paused.

Accessibility

Keep a visible pause control on any media that starts by itself. WCAG 2.2 success criterion 1.4.2 asks for a way to pause or stop audio that plays automatically for more than three seconds, or a separate volume control, and onpause is where a page can react once someone pauses.

Frequently asked questions

What does onpause do?
The onpause attribute runs JavaScript when an audio or video element pauses. Inside the handler, the element's paused property is already true.
Does onpause fire when a video ends?
Yes, the pause event fires right before ended when a video without loop reaches its end. A video with the loop attribute fires neither event and plays again.
Why does play() fail when pause() runs on a video that is still loading?
When pause() runs before a still-loading video starts playing, the play() promise rejects with an AbortError. The pause event still fires, and a catch() on that promise keeps the rejection from showing up as an uncaught error.
Is onpause the same as onended?
No, the pause event fires when playback pauses, while ended fires only when playback reaches the end. Pausing in the middle of a video fires pause but not ended.
How do I save the playback position with onpause?
In the onpause handler, store the element's currentTime, or clear the stored value when its ended property is true. On the next visit, read the stored value, for example from localStorage, and set currentTime to it.
Can one listener catch the pause event from every video on a page?
Yes, for media in the document itself, but only in the capture phase, since pause doesn't bubble. Use document.addEventListener('pause', handler, true), which won't see media inside iframes or shadow roots.
Why does onpause say paused is not a function?
Inline onpause code looks up names on the element first, so paused finds the video's own paused property. Rename the function, for example to logPause, and the call reaches it.