awakening82
@awakening82 (ryo saeki)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

スマホでホバーアクションを見せるため、2回目のタップでリンクへ移動するようにしたい

解決したいこと

aタグなどリンク要素に記述したhoverアクションをスマホでも見せたいので
親要素にontouchstart=""を記述し、タップすることでアクションが起こるよう記述しています。

しかし今の記述ではアクションを眺める暇なくリンク先へ飛んでしまいます。
1回タップしたらホバーアクション発動 → 2回目のタップでリンクに行く という仕様にしたいです。

追記) 下記デモサイトを自分のスマートフォン(android, chrome)で確認していたのですが、
希望通りの挙動をする時もあれば1回のタップでリンク先へ飛んだり、何回タップしてもリンク先に行かなかったりと非常に不安定な挙動をします。
もはやaタグに記述したhoverアクションをスマホで見せること、ontouchstartを書いて希望の挙動を実現させようとすることそのものが間違いなのでしょうか?

発生している問題・エラー

    <div class="wrapper" ontouchstart="">
        <h2 class="for-a">aタグ</h2>
        <a href="https://qiita.com/" id="sprite_dancer_a" class="sprite_dancer"></a>

        <h2 class="for-div">divタグ(onclick属性)</h2>
        <div id="sprite_dancer_div" class="sprite_dancer" onclick="location.href='https://www.google.com/'"></div>
    </div>
.sprite_dancer {
  background-image: url("../img/test-image.png");
  width: 213px;
  height: 190px;
  background-position: 0 0;
}

// スプライトアニメーション

.sprite_dancer:hover{
  animation: sprite 1s steps(10) infinite;
}

@keyframes sprite {
  from { background-position: 0 0; }
  to { background-position: -2130px 0; }
}

cssにてhover要素が追加されたらアニメーションが発動するように設定しています。

以下はこのコードを書いたデモサイトです。
https://rsaeki0.parallel.jp/sprite-hover/

自分で試したこと

jQueryで、1回目のタップではアニメーションが記述されたクラスを付与して
2回目のタップ時にリンク先へ飛ぶように書いてみました。

.animating {
  animation: sprite 1s steps(10) infinite;
}

@keyframes sprite {
  from { background-position: 0 0; }
  to { background-position: -2130px 0; }
}
// aタグをクリックした回数を記録する変数
let clickCount = 0;

// .sprite_dancerをクリックした際の処理
$(".sprite_dancer").on("click", function(event) {
  event.preventDefault();
  clickCount++;
  if (clickCount === 1) {
    // アニメーションを開始する
    $(this).addClass("animating");
    setTimeout(function() {
      // アニメーションが終了したら、再度クリックした場合に備えて、
      // animatingクラスを除去する
      $(".sprite_dancer").removeClass("animating");
    }, 3000);
  } else if (clickCount === 2) {
    // リンク先へ遷移する
    window.location = $(this).attr("href");
  }
});

しかしこれは余りにも力技すぎる気がします。
もっとスマートな方法をどなたかご存知ないでしょうか。
どうかご教授お願い致します。

0

1Answer

こんな感じではどうでしょう。
touchデバイスだった場合、click遷移を潰すかどうか決める前に、対象要素が1回目のclick済みかをチェックしています。

sample.html
<style>
a:hover {
  background-color: cyan;
}
</style>

<a href='https://qiita.com'>click here</a>
<a href='https://qiita.com'>click here</a>
<a href='https://qiita.com'>click here</a>

<script>
{
  const isTouchDevice = window.ontouchstart !== undefined;
  let touchDeviceHoverElement;
  addEventListener('click', e => {
    if (isTouchDevice) {
      if (touchDeviceHoverElement !== e.target) {
        touchDeviceHoverElement = e.target;
        e.preventDefault();
      }
    }
  });
}
</script>
0Like

Comments

  1. @awakening82

    Questioner

    ありがとうございます。

    頂いたコードをサーバーにアップしました。
    https://rsaeki0.parallel.jp/hoverOnPhoneTest/

    androidでも問題なく動き、iphone、ipadでも問題なく希望通りに動作しました。


    @ss8826さん、私の稚拙な質問にお答え頂き本当にありがとうございました。

Your answer might help someone💌