I was enhancing a
video element to run a special action whenever a user played the video:
This worked great! When a user played the video, my code was able to respond. I was ready to call it a day and go sit in the garden, but there were other enhancements we needed to make.
I needed to be able to programmatically play the video when a user performed certain actions. I wired that up:
This also seemed to be working great! I got my sun hat to head outside… but then I realized there was an issue. When the
play function was called, it triggered my event listener. But I only wanted to run my callback when the user manually played the video, not when my code triggered the
How could I differentiate a user playing the video from my code calling the video
If you’re not interested in the attempts that didn’t work, you can skip ahead to the working solution.
The first stop on my Dead End World Tour™ was the
event.isTrusted property. MDN says the following about this property:
isTrustedread-only property of the
Eventinterface is a boolean value that is
truewhen the event was generated by a user action, and
falsewhen the event was created or modified by a script or dispatched via
This sounds like exactly what I needed! I can use it to tell if the event was generated by user action! But, my testing told another story…
true whether a user pressed the “Play” button or my code ran
Looking at the official spec made this clearer:
isTrustedis a convenience that indicates whether an event is dispatched by the user agent (as opposed to using
isTrusted is only
false if the event was dispatched using
dispatchEvent or a similar function.
Are there other event properties we could use?
Some Stack Overflow posts suggested checking for special properties that would be present for user-triggered events. For example, pointer events have
screenY properties that tell you where the click occurred. If those are both
0 you could be pretty sure that it wasn’t a user-triggered click event.
Unfortunately, I couldn’t find any similar properties to use for the
Could we use a click event instead?
This raised an obvious question. Could we hook into click events instead? This also didn’t work out. The
video element embeds the browser’s video player widget, which captures click events which means they don’t bubble up to my event listener.
Could we build a custom video player?
I mean… I guess…
This might have been the right solution for another project, but it felt like overkill here.
The (hacky) solution
This can be a little confusing at first glance. Here are a couple of different scenarios and how this code would handle it.
A user-triggered event:
- A user presses “Play.”
playevent listener is triggered.
falseso our listener proceeds to respond to the user’s action.
A code-triggered event:
- Our code calls the
- This function sets
trueand then plays the video.
playevent listener is triggered.
trueso our listener knows this wasn’t a user-triggered action.
videoPlayedByCodeis reset to false.
Try playing the video below using the browser’s built-in play button and the custom play button to see how the demo responds.
See the Pen User vs. Code Events by Paul Hebert (@phebert) on CodePen.
Paul Hebert is a hybrid designer and developer at Cloud Four. When he's not designing and developing websites he enjoys bouldering, drawing, cooking, gardening, and eating too much cheese.