世界のやまさ

SEKAI NO YAMASA

jQuery.flickSimple.js で a タグじゃない要素のクリックイベントを拾いたい

ページ全体じゃなくて div で区切ったテーブルとかリストだけスクロールさせたいときに jQuery.flickSimple.js というのを使っている。これはタッチで任意の要素をフリックでスクロールできるからすごく便利なんだけど、とある要素をクリックしたというイベントが a タグが入っていないと発生しなくて困った。

例えば、$('#verticaly').on('click', 'li', function(){ alert("test"); }); っていうのを無理やり追加してリストにクリックイベントを追加したとしても、フリック時もクリックと判定されてしまうのでうまくいかない。 デモは以下。
ちょっと見にくいですが、縦にフリックでスクロールが出来ます。


jQuery.flickSimple.js は onClick イベントが用意されていて以下のように書くことでクリックイベントを拾えるようになる。


ところが上記の onClick イベントは a タグがある場合のみ有効となっているようで、上記HTML から a を取り除いてしまうと以下のようにクリックイベントが起きない。


GitHub のソースを見ると下記のようになっていて、意図的にはじいている。

touchend: function(e) {
			var o = this;
			if ( o.disabled || o.startX === null || o.startY === null ) { return; }
			o.startX = null;
			o.startY = null;
			if ( o.anc && ! o.touchhold ) {
				if ( o.onClick ) {
					o.onClick( o.anc );
				}

ちょっと見づらいですが、以下のように改造してみました。//+としているのが追加したところです。

    touchend: function(e) {
        var o = this;
        if ( o.disabled || o.startX === null || o.startY === null ) { return; }
// chg アンカー以外のクリックイベントに対応させる
        var te = o.touchable ? e.originalEvent.touches[0] : e; //+
        var nowX = te.clientX; //+
        var nowY = te.clientY; //+

        var click = false; //+
        if ( Math.abs( o.startX - nowX ) < 5 && Math.abs( o.startY - nowY ) < 5 ) { //+
            click = true; //+
        } //+
        o.startX = null; //+
        o.startY = null; //+
//-         if ( o.anc && ! o.touchhold ) {
        if ( click && ! o.touchhold ) { //+
            if ( o.onClick ) {
//-                 o.onClick( o.anc );
                o.onClick( e ); //+
            }
            if ( ! o.anc ) {    //+
                return;         //+
            }                   //+

普通にやると押したときと離した時の座標がピッタリ一致しないといけないので、タッチの検出ができなくなります。人間の指はそんなに正確じゃないので、Math.abs でアソビを持たせています。この処理はおそらくフリックかどうかの判定につかっている touchmove という箇所で入っていたので、16だったしきい値をとりあえず5にしてみました。


この改造を取り込んだのが以下です。


これでMacのsafariではやった動いたーと思って、iphone で確認したらフリック自体出来なくなってしまいダメダメでした。もう少し調整が必要そうで次回に続きます。