フルスタックJSフレームワーク「Meteor」で、ボタン長押しイベントを実装する際に戸惑ったので、メモ。
Meteorでボタン長押しイベントを実装するには、
Meteor.setTimeout()
というものを利用します。素のJSにも存在するAPIですね。
他にも、同じ分類に属する
Meteor.clearTimeout()
Meteor.setInterval()
Meteor.clearInterval()
を使って長押しイベントを実装できますが、実際setTimeout()
のみで実装できるので、今回はそちらに絞って書こうと思います。
実装
サンプルとして、下のようなシンプルなカウントアップを作ります。
HTML
longPressというテンプレートを作ります。
<head>
<title>longPress</title>
</head>
<body style="text-align: center">
<h1>Long Press Counter</h1>
{{> longPress}}
</body>
<template name="longPress">
<button class="plus">+</button>
<p>{{counter}}</p>
<button class="minus">ー</button>
</template>
JS(通常のクリックの書き方)
まずは比較のために通常のクリック書き方から。
Template.longPress.onCreated( function () {
this.counter = new ReactiveVar(0);
});
Template.longPress.helpers({
counter() {
return Template.instance().counter.get();
},
});
Template.longPress.events({
'click .plus'(event, instance) {
instance.counter.set(instance.counter.get() + 1);
},
'click .minus'(event, instance) {
instance.counter.set(instance.counter.get() - 1);
}
});
JS(長押しイベントでの実装方法)
click
をmouseup
、mousedown
に変更し、setCount()
というメソッドを追加。
setTimeoutを利用することで、再帰的にメソッドを呼び出すようにします。
Template.longPress.onCreated( function () {
this.counter = new ReactiveVar(0);
this.holding = new ReactiveVar(false);
this.setCount = (count) => {
if(this.holding.get()) {
this.counter.set(this.counter.get() + count);
return Meteor.setTimeout(() => this.setCount(count), 100);
}
};
});
Template.longPress.helpers({
counter() {
return Template.instance().counter.get();
},
});
Template.longPress.events({
'mousedown .plus'(event, instance) {
instance.holding.set(true);
return instance.setCount(1);
},
'mousedown .minus'(event, instance) {
instance.holding.set(true);
return instance.setCount(-1);
},
'mouseup .plus'(event, instance) {
instance.holding.set(false);
},
'mouseup .minus'(event, instance) {
instance.holding.set(false);
}
});
これで完成です。
Meteor.setTimeout()
は返り値としてIDを返します。
これをMeteor.clearInterval(id)
の引数に渡してあげることで止めることもできますが、上の方法でも止めれるのでこっちの方がいい気がします。
同様にして、マウスオーバーしている間といったイベントもmouseenter
、mouseleave
に変えてあげれば可能です。