Sdk: Add support for Passive Event Listeners

Created on 26 May 2016  路  15Comments  路  Source: dart-lang/sdk

I just learned about it by watching a Google I/O video.

Here is the spec: https://github.com/WICG/EventListenerOptions

It's already supported in Chrome 51, so it would be great to have this option too in Dart.

P2 area-web library-html type-enhancement web-libraries

Most helpful comment

Has any progress been made on this issue?

All 15 comments

+1 for support

+1 is spam. Please stop it. Use add reaction instead.

In Chrome 56 and newer touch events are passive by default: see https://www.chromestatus.com/features/5093566007214080

We need a way to use this feature or even restore the previous behavior (for example for touch drag and drop things like the dnd package).

Does anyone see a workaround as long as the standard listener methods do not support this?

I am user of Dart 1.24.3 and found that I see hundreds of verbose log in Chrome 67+ telling to convert the listener to passive. It may be dart2js is not compiling to javascript and making use of passive mode.

Any solutions ?

Now trying to prevent a wheel event in the latest version of chrome (73.0.3683.86) throws a console error, and does not work.

[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive.

https://www.chromestatus.com/features/6662647093133312

Now trying to prevent a wheel event in the latest version of chrome (73.0.3683.86) throws a console error, and does not work.

[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive.

https://www.chromestatus.com/features/6662647093133312

See:
https://www.chromestatus.com/features/6662647093133312

I searched and found that a lot of bugs are arising on too many projects written in JavaScript, because of this new change made in chrome 73+ to make document level scroll events as passive by default to improve performance.

But we can not call e.preventDefault(); from a passive event listener, so at the moment if you want to implement scroll disable utility function using dart:html it will not work in chrome 73+ because event listener being marked as passive by default.

I can not find any example that shows use of non-passive events using dart:html.

CC @vsmenon @terrylucas 鈥撀爏ounds like something we should get on soon!

Just to clarify, is the need here to add/extend the addEventListener API to allow this option to be passed?

@vsmenon would be good to get it for both, like this: document.onMouseWheel.listen((ev){}, passive: false); and document.addEventListener("wheel", (ev){}, passive: false);

Has any progress been made on this issue?

This seems to be trivial but could be a good performance improvement? Is there any hack or alternative?

This seems to be trivial but could be a good performance improvement? Is there any hack or alternative?

I guess you can use JS interop, something like

JS()
library window;

JS('document.addEventListener')
eventListener(eventName, Function(ev) fn, {bool passive});

I do have a window.dart file to expose some stuff with JS interop that you may find useful.
Here is a snippet

@JS('window')
library window;

import 'package:js/js.dart';

// to expose more arguments than the dart:html version
@JS('console.log')
external consoleLog(a, [b, c, d, e, f, g, h]);

@JS()
external dynamic get undefined;

@JS('NaN')
external dynamic get nan;

@JS('Infinity')
external dynamic get infinity;


I had to make this work on a project because we needed to prevent a PathElement from being clicked, here is how I did it:

anywhere in your index.html file:

  <script type="text/javascript">
  window._listen = function(target, type, listener, options) {
    target.addEventListener(type, listener, options);
  }
  </script>

in a file that should be used to js interop the window

@JS()
library browserhtml;

import 'package:js/js.dart';
import 'dart:html' as html;

@JS('_listen')
external listenToEvent(
    html.Element target, String type, Function(html.Event) listener,
    [EventListenerOptions options]);

extension AdvancedElement on html.Element {
  void eventListen(String type, Function(html.Event) listener,
          [EventListenerOptions options]) =>
      listenToEvent(this, type, listener, options);
}

now you can use eventListen in any Element, eg:

var el = PathElement()..eventListen('mousedown', (Event ev) {
      print('Preventing default');
      ev.preventDefault();
    }, EventListenerOptions(passive: false));

fyi - @sigmundch - relabeled this as area-web just now.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

DartBot picture DartBot  路  3Comments

DartBot picture DartBot  路  3Comments

jmesserly picture jmesserly  路  3Comments

Hixie picture Hixie  路  3Comments

55555Mohit55555 picture 55555Mohit55555  路  3Comments