Reputation: 3264
I'd like to create a steam that toggles based on keyup
and keydown
. The key code is emitted once on a keydown
event and emitted again on the keyup
event. I used distinctUntilChanged
to prevent multiple key codes from being sent while keydown
fires. The problem with my code is that I can't do successive keydown
and keyup
on the same key code because of the distinctUntilChanged
.
Currently, pressing and releasing 'a' followed by 'b' works, but not 'a' followed by 'a'.
What I want to achieve is:
keypress
event)var getKeyCode = function(e) { return e.which; }
var target = document.querySelector('body');
var keyDownStream = Rx.Observable.fromEvent(target, 'keydown')
.distinctUntilChanged(getKeyCode);
var keyUpStream = Rx.Observable.fromEvent(target, 'keyup')
.distinctUntilChanged(getKeyCode);
var toggleStream = Rx.Observable.merge(keyDownStream, keyUpStream);
toggleStream.subscribe(function(e) {
console.log(e.which);
});
Upvotes: 0
Views: 1286
Reputation: 3264
Found the solution was to move the distinctUntilChanged
to the merged observable and filter by event type and keycode. This would ensure that the subscribers are notified once for the keydown
event and once for the keyup
event for the same key.
var filterByTypeAndKeyCode = function(e) { return e.type + e.which; }
var target = document.querySelector('body');
var keyUpStream = Rx.Observable.fromEvent(target, 'keyup');
var keyDownStream = Rx.Observable.fromEvent(target, 'keydown');
Rx.Observable.merge(keyDownStream, keyUpStream)
.distinctUntilChanged(filterByTypeAndKeyCode)
.subscribe(function(e) {
console.log(e.which);
});
Upvotes: 1
Reputation: 18665
I used:
var toggleStream = Rx.Observable.fromEvent(document.body, 'keydown').filter(function ( e, index ) {
return index < 1;
}).takeUntil(Rx.Observable.fromEvent(document.body, 'keyup')).repeat();
toggleStream.subscribe(function ( e ) {
// the task should go here
console.log("key down :" + e.which);
});
You can find a jsbin here : http://jsbin.com/xuqasawese/edit?html,js,console,output
Currently, pressing and releasing 'a' followed by 'b' works, and also 'a' followed by 'a'. However, you can imagine that you press key 'a' and without releasing that key, press another one 'b' and release 'b'. Then press another key 'c', and your action will be executed. It's kind of an edge case, but do you have any intended behaviour should that happen?
Upvotes: 1