JavaScript
RxJS

RxJS Observableの作成 (3)  Observable.fromEvent の使い方

More than 1 year has passed since last update.


用途

Observable.fromEventは、DOMイベントから新しいObservableを作成します。


基本的な使い方

マウスクリックやマウスオーバー、入力フォーム等のイベントからObservableを作成します。

ユーザーの操作に対してObservableを作れるので使用頻度が高いオペレータになります。

fromEventから作られたObservableはcompleteを発火しません。


クリックイベントからObservableを作成


some.html

<button id="btn">click me</button>



some.js

const btn = document.getElementById('btn');

Rx.Observable.fromEvent(btn, 'click').subscribe(e => {
console.log(e.target.innerHTML);
})

// 結果
// click me


ES6 stackblitz

TypeScript stackblitz


インプットイベントからObservableを作成


some.html

<input type="text" id="input">



some.js

const input = document.getElementById('input')

Rx.Observable.fromEvent(input, 'input').subscribe(e => {
console.log(e.target.value);
})

// 結果 入力(hoge)
// h
// ho
// hog
// hoge


ES6 stackblitz

TypeScript stackblitz


他のオペレーターとの組み合わせ

Observable.fromEventは非常に多くのオペレーターとの組み合わせが考えられます。


bufferTime、filterを使ったダブルクリック判定


some.html

<button id="btn">click me</button>



some.js

const btn = document.getElementById('btn');

Rx.Observable.fromEvent(btn, 'click')
.bufferTime(500)
.filter(arr => {
return arr.length > 1
})
.subscribe(x => {
console.log('ダブルクリック!');
});


window.resizeやmousemoveなどの連続するイベントで、リサイズやマウスマウスの移動を止めたときにイベントを流す。


some.js

const input = document.getElementById('input')

Rx.Observable.fromEvent(window, 'resize')
.debounceTime(100)
.subscribe(e => {
console.log('リサイズ終わり!');
})


bufferTime、filter、mapを使った押し順判定

2,3,1の順でボタンを押せば正解。


some.html

<div>

<button id="btn1">1</button>
<button id="btn2">2</button>
<button id="btn3">3</button>
</div>


some.js

const btn1 = document.getElementById('btn1');

const btn2 = document.getElementById('btn2');
const btn3 = document.getElementById('btn3');

const btn1Observable = Rx.Observable.fromEvent(btn1, 'click');
const btn2Observable = Rx.Observable.fromEvent(btn2, 'click');
const btn3Observable = Rx.Observable.fromEvent(btn3, 'click');

const checkList = ['2','3','1'];

Rx.Observable.merge(btn1Observable, btn2Observable, btn3Observable)
.bufferTime(2000)
.filter(arr => {
return arr.length === 3
})
.map(arr => {
return arr.map(x => {
return x.target.innerHTML
})
}).subscribe(x => {
if(JSON.stringify(x) === JSON.stringify(checkList)){
console.log('正解!')
}else{
console.log('不正解!')
}
})


ES6 stackblitz

TypeScript stackblitz