Easy fix for: Unable to preventDefault inside passive event listener due to target being treated as passive

In this short blog, I explain what’s causing this violation and how you can easily fix it.

Easy fix for: Unable to preventDefault inside passive event listener due to target being treated as passive
Photo by Jason Rosewell / Unsplash

We often receive this Report API Intervention report at URIports:

Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/feature/5093566007214080

Intervention violations can cause unwanted behavior and are visible in the visitors' developer console. Additionally, browsers can send violation reports to alert website administrators using the Reporting API. This allows web developers to resolve these violations proactively and monitor how frequently they occur.

💙
Get clear, real-time insight into the health and performance of your website with URIports
Monitor violations, network errors, certificate issues, deprecated code, and more without installing additional scripts or software.
Read more

What is the intervention violation about?

This violation is about the javascript Event Listeners. Since Chrome 51, an event listener can be set as "passive". Passive event listeners were introduced to optimize scrolling performance on a device. When you use a passive event listener on your site, you promise not to use a preventDefault() in that listener to disable scrolling. This frees the browser up to respond to scrolling immediately without waiting for JavaScript, thus ensuring the user's reliably smooth scrolling experience. A passive event listener is mainly used in touchstart, touchmove or wheel listeners.

⚠️
Since Chrome 56, all touch event listeners are passive by default.
▶️
Check this in-depth video if you want to learn more about passive event listeners and scrolling smoothness.

How to fix this violation

There are two ways to solve this violation. We recommend the first option.

1. Remove the need for preventDefault() in the event listener

The correct way to fix this issue is by finding the event listener responsible for generating the intervention violation and removing the preventDefault() call in that event listener. The preventDefault() call can't be used in a passive event listener. For example, a touchstart, touchmove, or wheel event listener is passive as default. Removing a preventDefault() call can be easy, but test what happens when removing the call from the listener.

window.addEventListener('touchstart', function(event) {
    // some logic
    event.preventDefault(); // <-- that should not be used in passive
    // some other magic
});

Find the event listener that is causing the violation to trigger. A passive event listener is primarily used in touchstart, touchmove, or wheel listeners. It is probably something like:

window.addEventListener('touchstart', function() {
    // some logic
});

Change that listener to:

window.addEventListener('touchstart', function() {
    // some logic
}, {passive:false}); // <-- mark the event listerner as NOT passive

We discourage this option because this could have scrolling performance implications. So test your site or app on slower (mobile) devices to check if there is a performance drop in scrolling behaviour. Also, be aware you will have to feature detect if the User Agent supports EventListenerOptions.

Monitor this and many other violations on your site

If you want to monitor these violations, check out our monitoring platform URIports. With our service, you can monitor network traffic, network disruptions, content security policy violations, and much much more!

If you have any questions about this subject, please drop me a line at @roelandkuiper or @uriports