Rxjs, fromEvent to handle multiple events

南笙酒味 提交于 2019-12-04 17:42:05

问题


What is the best way to handle multiple events on the same DOM node in rxjs 5.1?

fromEvent($element, 'event_name') but I can specify only one event at a time.

I want handle scroll wheel touchmove touchend events.


回答1:


Note: This is for RxJS v5. See bottom of this answer for the v6 equivalent.


You can use the Rx.Observable.merge function to merge multiple observable streams into a single stream:

// First, create a separate observable for each event:
const scrollEvents$    = Observable.fromEvent($element, 'scroll');
const wheelEvents$     = Observable.fromEvent($element, 'wheel');
const touchMoveEvents$ = Observable.fromEvent($element, 'touchmove');
const touchEndEvents$  = Observable.fromEvent($element, 'touchend');

// Then, merge all observables into one single stream:
const allEvents$ = Observable.merge(
    scrollEvents$,
    wheelEvents$,
    touchMoveEvents$,
    touchEndEvents$
);

If that seems a little bloated, we might clean up a little by creating an array for the events, and then map that array to Observable objects. This works best if you do not need to reference the events their associated observables separately at some point:

const events = [
    'scroll',
    'wheel',
    'touchmove',
    'touchend',
];

const eventStreams = events.map((ev) => Observable.fromEvent($element, ev));
const allEvents$ = Observable.merge(...eventStreams);

You are now able to handle all events with one single subscription:

const subscription = allEvents$.subscribe((event) => {
    // do something with event...
    // event may be of any type present in the events array.
});

Update RxJS v6

In RxJS 6 you can import the standalone merge and fromEvent functions equivalent to the static methods in v5, and use them the same way:

import { fromEvent, merge } from 'rxjs';

const scrollEvents = fromEvent($element, 'scroll');
// creating other input observables...

const allEvents$ = merge(
    scrollEvents$,
    wheelEvents$,
    touchMoveEvents$,
    touchEndEvents$
);



回答2:


This is how I prefer to combine events:

fromEvents(dom, "scroll", "wheel", "touch", "etc...");
function fromEvents(dom, ...eventNames: string[]) {
    return eventNames.reduce(
        (prev, name) => Rx.merge(prev, fromEvent(dom, name)),
        Rx.empty()
    );
}



回答3:


This is how I would implement this in the newest version of RxJs

const events = ['scroll', 'resize', 'orientationchange']
from(events)
  .pipe(
    mergeMap(event => fromEvent($element, event))
  )
  .subscribe(
    event => // Do something with the event here
  )



回答4:


As mentioned above, Below hopefully is easier to read.

        import {fromEvent, merge} from "rxjs";
        
        
        const mousemoveEvent = fromEvent(document, 'mousemove');
        const wheelEvent = fromEvent(document, 'wheel');
        const leftclickEvent = fromEvent(document, 'auxclick');
        const rightclickEvent = fromEvent(document, 'click');
        const keyboardEvent = fromEvent(document, 'keydown');

        const allEvents = merge(
            mousemoveEvent, wheelEvent, leftclickEvent, rightclickEvent, keyboardEvent
        )
        
        


来源:https://stackoverflow.com/questions/45495188/rxjs-fromevent-to-handle-multiple-events

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!