自作でスワイプ処理を作成していた時に、スワイプさせる要素内にリンクがあった場合の処理に手間取ったので、対応方法をメモしておきます。
サンプルコード1
まずは普通にスワイプ処理を組み込んでみます。
HTML
<div id="sample"> <ul> <li><a href="https://cly7796.net/blog/">リンク1</a></li> <li><a href="http://ad-bookmarks.tumblr.com/">リンク2</a></li> <li><a href="https://www.google.co.jp">リンク3</a></li> <li><a href="http://www.yahoo.co.jp/">リンク4</a></li> </ul> </div>
CSS
#sample { position: relative; width: 300px; overflow: hidden; } #sample ul { position: absolute; top: 0; left: 0; width: 600px; }
JavaScript
$(function() { var isTouch = ('ontouchstart' in window); $('#sample ul').bind({ 'touchstart mousedown': function(e) { e.preventDefault(); this.pageX = (isTouch ? event.changedTouches[0].pageX : e.pageX); basePoint = this.left = parseFloat($(this).css('left')); this.touched = true; }, 'touchmove mousemove': function(e) { if(!this.touched) { return; } e.preventDefault(); this.left = parseFloat($(this).css('left')) - (this.pageX - (isTouch ? event.changedTouches[0].pageX : e.pageX) ); $(this).css({ left: this.left }); this.pageX = (isTouch ? event.changedTouches[0].pageX : e.pageX); }, 'touchend mouseup': function(e) { if(!this.touched) { return; } this.touched = false; if(basePoint - this.left > 30) { // 一定以上スワイプした場合は自動スライド } else if(basePoint - this.left < -30) { // 一定以上スワイプした場合は自動スライド } else { // 一定以上スワイプしていない場合は元の位置に戻す $(this).css({ left: basePoint }); } } }); });
スワイプする要素の中にリンクがある場合のデモページ1
#sample内のulを動かしています。
現状だと、aタグに触れた状態でスワイプした場合、スワイプ完了後にページ遷移をしてしまします。
サンプルコード2
aタグをクリックしたときにはページ遷移させないようにし、スワイプ完了後にページ遷移するかどうか判別する処理を追加したいと思います。
JavaScript
$(function() { var isTouch = ('ontouchstart' in window); $(document).on('click', '#sample ul a', function() { return false; }); $('#sample ul').bind({ 'touchstart mousedown': function(e) { e.preventDefault(); this.pageX = (isTouch ? event.changedTouches[0].pageX : e.pageX); basePoint = this.left = parseFloat($(this).css('left')); this.touched = true; }, 'touchmove mousemove': function(e) { if(!this.touched) { return; } e.preventDefault(); this.left = parseFloat($(this).css('left')) - (this.pageX - (isTouch ? event.changedTouches[0].pageX : e.pageX) ); $(this).css({ left: this.left }); this.pageX = (isTouch ? event.changedTouches[0].pageX : e.pageX); }, 'touchend mouseup': function(e) { if(!this.touched) { return; } this.touched = false; if(basePoint - this.left > 30) { // 一定以上スワイプした場合は自動スライド } else if(basePoint - this.left < -30) { // 一定以上スワイプした場合は自動スライド } else if(Math.abs(basePoint - this.left) < 5) { // スワイプした距離が5px以下の場合はクリックの処理 } else { // 一定以上スワイプしていない場合は元の位置に戻す $(this).css({ left: basePoint }); } } }); });
スワイプする要素の中にリンクがある場合のデモページ2
クリック時のページ遷移停止、スワイプ完了後にページ遷移するかどうかの判別処理の追加はすぐできたのですが、遷移先のURLをどう取得するかで迷いました。
サンプルコード3
jQueryの.closet()を使うことでできました。
JavaScript
$(function() { var isTouch = ('ontouchstart' in window); $(document).on('click', '#sample ul a', function() { return false; }); $('#sample ul').bind({ 'touchstart mousedown': function(e) { e.preventDefault(); this.pageX = (isTouch ? event.changedTouches[0].pageX : e.pageX); basePoint = this.left = parseFloat($(this).css('left')); this.touched = true; }, 'touchmove mousemove': function(e) { if(!this.touched) { return; } e.preventDefault(); this.left = parseFloat($(this).css('left')) - (this.pageX - (isTouch ? event.changedTouches[0].pageX : e.pageX) ); $(this).css({ left: this.left }); this.pageX = (isTouch ? event.changedTouches[0].pageX : e.pageX); }, 'touchend mouseup': function(e) { if(!this.touched) { return; } this.touched = false; if(basePoint - this.left > 30) { // 一定以上スワイプした場合は自動スライド } else if(basePoint - this.left < -30) { // 一定以上スワイプした場合は自動スライド } else if(Math.abs(basePoint - this.left) < 5) { // スワイプした距離が5px以下の場合はクリックの処理 var goUrl = $(e.target).closest('a').attr('href'); if(goUrl != undefined) { window.location.href = goUrl; } } else { // 一定以上スワイプしていない場合は元の位置に戻す $(this).css({ left: basePoint }); } } }); });
コメントが承認されるまで時間がかかります。