###実現したいこと
下図のように<a>タグを入れ子にせずに、入れ子にしたかのような機能にしたいです。
しかし、難しい条件がございます。
###条件
条件として次の機能1から4を求めておりまして、各<a>タグは通常の<a>タグと同じ挙動での実現を求めています。(テキストを選択できないなどの挙動の違いがないようにしたいです。)
機能1. カード全体のクリックで「画像タイトル」のリンクへ飛ぶこと
機能2.「著者名」「タグ」のクリックでそれぞれのリンクへ飛ぶこと
機能3. aタグの右クリックメニュー(新しいタブで開く等)を出せること
機能4. テキストをカーソルで選択できること(コピペできないと使いにくいため)
###実装した機能
機能123をCSSで実装しました。
「画像タイトル」のリンク範囲をCSSの:after
で.card
全体に伸ばしたわけです。
(これは昨日の質問でご回答いただいた方法です。)
しかしこれによって機能4ができなくなりました。
テキスト選択しようとすると、:after
になっているためにドラッグが発生してしまいます。
そこで下記のJavaScriptを書きました。
テキスト選択の際はis_drag = true
となり、先のCSSの:after
を解除したという感じになっています。
###発生している問題
これでいけるとかと思いましたが、テキスト選択のタイミングが次のように遅れます。
読み込み終了→テキスト選択→できない→もう一度テキスト選択→できる
このように、一度目の選択ができないのです。
###ソースコード
次のソースコードを実行できるjsfiddle がありますので、よろしければお試しください。
html
1<div class="card is_arrow_link"> 2 <img src="https://placehold.jp/250x200.png"> 3 <div class="card-body"> 4 <h3 class="card-title"> 5 <a href="example.com" class="stretched-link">画像タイトル</a> 6 </h3> 7 <p class="card-author"> 8 <a href="#author">著者名:ふかみ</a> 9 </p> 10 <p class="card-tag"> 11 <a href="#tags">タグ :夜景・ビル・綺麗</a> 12 </p> 13 </div> 14</div>
css
1.card { 2 position: relative; 3 width: 250px; 4 border: 1px solid gray; 5 padding: 5px; 6 margin: 0 0 100px 0; 7} 8 9.card.is_arrow_link .stretched-link::after { 10 position: absolute; 11 top: 0; 12 right: 0; 13 bottom: 0; 14 left: 0; 15 z-index: 1; 16 content: ""; 17 background-color: transparent; 18} 19 20.card-author > a, .card-tag > a { 21 position: relative; 22 z-index: 2; 23} 24 25a { 26 line-height: 2; 27 display: inline-block; 28 text-decoration: none; 29} 30 31a:hover { 32 text-decoration: underline; 33} 34 35h3,p{ 36 margin: 0; 37}
javascript
1// これがtrueのときCSSの:afterを解除して、テキスト選択できるようにしました 2var is_drag = false; 3 4// mousedown 5$(document).on('mousedown','.card', function(){ 6 console.log('mousedown'); 7 console.log('mousedown is_drag =' ,is_drag); 8 $(this).addClass('is_arrow_link'); 9 is_drag = true; 10}); 11 12// mouseup 13$(document).on('mouseup','.card', function(){ 14 console.log('mouseup'); 15 is_drag = false; 16 //$(this).addClass('is_arrow_link'); 17}); 18 19// mousemove 20$(document).on('mousemove', function() { 21 console.log('mousemove'); 22 // drag 23 if (is_drag === true) { 24 console.log('drag'); 25 $('.card').removeClass('is_arrow_link'); 26 } 27});
※.card
は.append()
されるため、$(document).on();
の方法で書いています。
###試したこと
素人試行錯誤で恐縮ですが、上記JavaScriptのような「ドラッグの検出」をやめて、「長押しの検出」というアプローチを試してみました。
「長押しの検出」はライブラリ「longpress 」を用いて以下前半部分にコピペしています。
しかしこちらも「ドラッグの検出」と同様のタイミングのズレが生じてしまいました。
JavaScript
1/*------------------------------------------------- 2 3 以下は ライブラリ longpress です 4 5--------------------------------------------------*/ 6 7/** 8 * Longpress is a jQuery plugin that makes it easy to support long press 9 * events on mobile devices and desktop borwsers. 10 * 11 * @name longpress 12 * @version 0.1.2 13 * @requires jQuery v1.2.3+ 14 * @author Vaidik Kapoor 15 * @license MIT License - http://www.opensource.org/licenses/mit-license.php 16 * 17 * For usage and examples, check out the README at: 18 * http://github.com/vaidik/jquery-longpress/ 19 * 20 * Copyright (c) 2008-2013, Vaidik Kapoor (kapoor [*dot*] vaidik -[at]- gmail [*dot*] com) 21 */ 22 23(function($) { 24 $.fn.longpress = function(longCallback, shortCallback, duration) { 25 if (typeof duration === "undefined") { 26 duration = 500; 27 } 28 29 return this.each(function() { 30 var $this = $(this); 31 32 // to keep track of how long something was pressed 33 var mouse_down_time; 34 var timeout; 35 36 // mousedown or touchstart callback 37 function mousedown_callback(e) { 38 mouse_down_time = new Date().getTime(); 39 var context = $(this); 40 41 // set a timeout to call the longpress callback when time elapses 42 timeout = setTimeout(function() { 43 if (typeof longCallback === "function") { 44 longCallback.call(context, e); 45 } else { 46 $.error('Callback required for long press. You provided: ' + typeof longCallback); 47 } 48 }, duration); 49 } 50 51 // mouseup or touchend callback 52 function mouseup_callback(e) { 53 var press_time = new Date().getTime() - mouse_down_time; 54 if (press_time < duration) { 55 // cancel the timeout 56 clearTimeout(timeout); 57 58 // call the shortCallback if provided 59 if (typeof shortCallback === "function") { 60 shortCallback.call($(this), e); 61 } else if (typeof shortCallback === "undefined") { 62 ; 63 } else { 64 $.error('Optional callback for short press should be a function.'); 65 } 66 } 67 } 68 69 // cancel long press event if the finger or mouse was moved 70 function move_callback(e) { 71 clearTimeout(timeout); 72 } 73 74 // Browser Support 75 $this.on('mousedown', mousedown_callback); 76 $this.on('mouseup', mouseup_callback); 77 $this.on('mousemove', move_callback); 78 79 // Mobile Support 80 $this.on('touchstart', mousedown_callback); 81 $this.on('touchend', mouseup_callback); 82 $this.on('touchmove', move_callback); 83 }); 84 }; 85}(jQuery)); 86 87 88/*------------------------------------------------- 89 90 以下が自作コードです 91 92--------------------------------------------------*/ 93 94$('.card').longpress(function(e) { 95 // 長押しの場合 96 console.log('longpress'); 97 $(this).removeClass('is_arrow_link'); 98}, 99function(){ 100 // 長押し期間以内に離した場合(普通のクリック) 101 console.log('click'); 102 $(this).addClass('is_arrow_link'); 103}, 100 ); // 長押し期間 104
回答1件
あなたの回答
tips
プレビュー