タッチデバイスのボタンのホバー効果の粘着を防ぐ方法


144

常に表示される「前へ」ボタンと「次へ」ボタンを備えたカルーセルを作成しました。これらのボタンにはホバー状態があり、青色に変わります。iPadのようなタッチデバイスでは、ホバー状態が固定されているため、ボタンをタップしても青色のままになります。それは欲しくない。

  • 各ボタンのno-hoverクラスontouchendを追加して、CSSを次のようにすることもできます。button:not(.no-hover):hover { background-color: blue; }ただし、これはおそらくパフォーマンスにかなり悪影響を及ぼし、Chromebook Pixel(タッチスクリーンとマウスの両方を備えている)などのデバイスを正しく処理しません。

  • touchクラスを追加しdocumentElementて、CSSを次のようにするhtml:not(.touch) button:hover { background-color: blue; }こともできます。ただし、タッチとマウスの両方を備えたデバイスでは正しく機能しません。

私が好むのは、ホバー状態を削除することontouchendです。しかし、それは可能ではないようです。別の要素にフォーカスしても、ホバー状態は削除されません。別の要素を手動でタップすると動作しますが、JavaScriptでそれをトリガーできないようです。

私が見つけたすべてのソリューションは不完全に見えます。完璧な解決策はありますか?

回答:


55

DOMからリンクを一時的に削除すると、ホバー状態を削除できます。http://testbug.handcraft.com/ipad.htmlを参照してください


あなたが持っているCSSで:

:hover {background:red;}

JSではあなたが持っています:

function fix()
{
    var el = this;
    var par = el.parentNode;
    var next = el.nextSibling;
    par.removeChild(el);
    setTimeout(function() {par.insertBefore(el, next);}, 0)
}

そして、あなたのHTMLでは:

<a href="#" ontouchend="this.onclick=fix">test</a>

3
@Chris良い点、ontouchendイベントでonclickハンドラーを設定するように例を変更しました。
Sjoerd Visscher 2013

4
最小限のデモコードを回答に追加することを検討してください。ありがとう!stackoverflow.com/help/how-to-answer
2540625 '16

1
@SjoerdVisscher私はそれを貼り付けました。StackOverflowは、リンクが消えてしまう可能性があるため、コードが答えに含まれていることを好みます。(そしてこの場合、クリックするだけでなく、ソースを表示し、どのビットが問題の手法であるかを突き止める必要がありました。)
Darren Cook

2
@KevinBordersはい、一部のデバイスでは、要素の削除と再挿入の間の時間遅延が非常に顕著になる場合があります。残念ながら、Android 4.4デバイスで、setTimeoutなしでこれを行うと機能しないことがわかりました。
ロドニー

1
アイデアは興味深いですが、私はそれが少しぎこちなく、すべてのタッチデバイスで広くサポートされていないことに気づきました。私はタッチサポート検出と純粋なcssに基づくこのような侵襲性の低いソリューションを好むと思います。stackoverflow.com/ a / 39787268/885464
Lorenzo Polidori

83

いったんCSSメディアクエリレベル4が実装されている、あなたはこれを行うことができるようになります:

@media (hover: hover) {
    button:hover {
        background-color: blue;
    }
}

または英語:「ブラウザが適切な/真の/実際の/エミュレートされていないホバリングをサポートしている場合(たとえば、マウスのようなプライマリ入力デバイスがある場合)、ホバーされたときにこのスタイルを適用しますbutton。」

Media Queries Level 4のこの部分はこれまでのところ最先端のChromeでのみ実装されているため、これに対処するためにポリフィルを作成しました。これを使用すると、上記の未来的なCSSを次のように変換できます。

html.my-true-hover button:hover {
    background-color: blue;
}

.no-touch手法のバリエーション)次に、ホバリングのサポートを検出する同じポリフィルのクライアント側JavaScriptを使用して、my-true-hoverそれに応じてクラスの存在を切り替えることができます。

$(document).on('mq4hsChange', function (e) {
    $(document.documentElement).toggleClass('my-true-hover', e.trueHover);
});

ありがとう!私の目的では、これはほとんどのブラウザーcaniuse.com/#search=media%20queriesでサポートされているようで、見事に機能します。ありがとう!
ragamufin

3
代わりにcaniuse.com/#feat=css-media-interactionを確認する必要があります。FirefoxIE11ではサポートされていないことがわかります(つまり、ポリフィルが必要です
CherryDT

ポリフィルはサポートされていないようです(リポジトリはアーカイブされています)
。jQuery

これは現在、モバイルブラウザーで広くサポートされており、魅力のように機能します。正解だと思います。
Trevor Burnham、

これは間違いなく実装が最も簡単で、最良の答えです。AndroidモバイルおよびPC上のFirefoxで動作します。デュアルタッチデバイスとマウスデバイスについては不明です。
HalfMens

28

これは完全な解決策がない一般的な問題です。ホバー動作はマウスで役立ち、ほとんどの場合タッチでは有害です。問題をさらに悪化させているのは、Chromebook PixelやSurfaceなど、タッチとマウスを同時にサポートするデバイスです(同時に、それ以上ではありません!)。

私が見つけた最もクリーンなソリューションは、デバイスがタッチ入力をサポートしていると見なされない場合にのみホバー動作を有効にすることです。

var isTouch =  !!("ontouchstart" in window) || window.navigator.msMaxTouchPoints > 0;

if( !isTouch ){
    // add class which defines hover behavior
}

確かに、それをサポートしている可能性のあるデバイスでホバーを失う。ただし、ホバーがリンク自体よりも大きな影響を与える場合があります。たとえば、要素がホバーされたときにメニューを表示したい場合があります。このアプローチにより、タッチの存在をテストし、おそらく条件付きで別のイベントをアタッチできます。

これをiPhone、iPad、Chromebook Pixel、Surface、およびさまざまなAndroidデバイスでテストしました。汎用のUSBタッチ入力(スタイラスなど)がミックスに追加されたときに動作することを保証できません。


1
コミュニティのwiki / Darren Cookの回答とは異なり、これでうまくいきました。
Jannik

1
いい答えだ。これは同様のソリューションです。stackoverflow.com
ロレンツォポリドリ

11

Modernizrあなたはノータッチ・デバイスのために特別にあなたのホバーをターゲットにすることができます:

(注:これはStackOverflowのスニペットシステムでは実行されません。代わりにjsfiddleを確認してください)

/* this one is sticky */
#regular:hover, #regular:active {
  opacity: 0.5;
}

/* this one isn't */
html.no-touch #no-touch:hover, #no-touch:active {
  opacity: 0.5;
}

モバイルとデスクトップの両方で期待どおりに機能:activeする.no-touchため、ターゲットにする必要がないことに注意してください。


これはIMOの最良の回答ですが、例は正しくありません。タッチデバイスと非タッチデバイスで同じホバー状態を示しています。タグに.no-touch存在する場合のみホバー状態を適用する必要がありますhtml。そうでなければ、この答えは私の承認の印を取得します。
morrisbret 2015

2
問題は、タッチスクリーンを備えたマウス対応デバイスがいたるところにあるため、この方法に頼ることができなくなったことです。しかし、私はそれを行う別の方法の多くを見ることができません...これはかなりのジレンマです
dudewad

それを行う1つの方法は、Modernizrとmobile-detect.jsなどのライブラリの両方を使用して、それが電話またはタブレットであることを確認することだと思います。
ギャビン

あなたは救世主です。おかげでこれはモバイルデバイスで完全に機能しました
Shivam

9

ホバーをサポートしていないデバイスのホバー効果を上書きできます。お気に入り:

.my-thing {
    color: #BADA55;
}

.my-thing:hover {
    color: hotpink;
}

@media (hover: none) {
    .my-thing {
        color: #BADA55;
    }
}

iOS 12でテストおよび検証済み

これを指摘するためのhttps://stackoverflow.com/a/50285058/178959への帽子の先端。


これはより近代的なソリューションであり、JavaScriptやDOMの操作は不要であり、ブラウザを完全にサポートしており(IEを除く)、受け入れられる答えになるはずです。
funkju

8
$("#elementwithhover").click(function() { 
  // code that makes element or parent slide or otherwise move out from under mouse. 

  $(this).clone(true).insertAfter($(this));
  $(this).remove();
});

この答えは、click()の代わりにon()を使用して改善できます。DOMから要素を削除して再アタッチすると、クリックイベントが失われました。onで関数を書き直したとき、要素にバインドし、削除と追加が機能しました。例: `$( 'body')。on( 'click'、 '#elementwithhover'、function(){// clone、insertafter、remove}); あなたがその変更をした場合、私はこれに投票します。
ウィルランニ

クローンtrueは、スタックしたホバーを持つ要素の代わりに新しい要素のクリックイベントを保持します。元の要素は、複製後にdomから削除されます。
Verard Sloggett 16

素晴らしい仲間、10倍
Kaloyan Stamatov 2017年

修正を検索する時間。これにより、最終的に修正が提供されました。どうもありがとう!
phil917

8

携帯にスティッキーホバーに対処するための4つの方法:ここでは、動的に「追加または削除する方法だcan touch、ユーザーの現在の入力タイプに基づいて文書に」クラスが。これは、ユーザーがタッチとマウス/トラックパッドを切り替える可能性があるハイブリッドデバイスでも機能します。

<script>

;(function(){
    var isTouch = false //var to indicate current input type (is touch versus no touch) 
    var isTouchTimer 
    var curRootClass = '' //var indicating current document root class ("can-touch" or "")

    function addtouchclass(e){
        clearTimeout(isTouchTimer)
        isTouch = true
        if (curRootClass != 'can-touch'){ //add "can-touch' class if it's not already present
            curRootClass = 'can-touch'
            document.documentElement.classList.add(curRootClass)
        }
        isTouchTimer = setTimeout(function(){isTouch = false}, 500) //maintain "istouch" state for 500ms so removetouchclass doesn't get fired immediately following a touch event
    }

    function removetouchclass(e){
        if (!isTouch && curRootClass == 'can-touch'){ //remove 'can-touch' class if not triggered by a touch event and class is present
            isTouch = false
            curRootClass = ''
            document.documentElement.classList.remove('can-touch')
        }
    }

    document.addEventListener('touchstart', addtouchclass, false) //this event only gets called when input type is touch
    document.addEventListener('mouseover', removetouchclass, false) //this event gets called when input type is everything from touch to mouse/ trackpad
})();

</script>

これが私が見つけた最良の方法です。さらに、タイマーを1000ミリ秒に増やすと、長押しもカバーできますこちらを参照してください。素晴らしいもの!
lowtechsun 2017年

3

私は自分の解決策を投稿するつもりでしたが、誰かがすでに投稿したかどうかを確認したところ、@ Rodneyがほとんどそれを実行したことがわかりました。しかし、少なくとも私の場合、彼はそれを不愉快なものにする最後の重要なものを逃しました。つまり、私も同じ.fakeHoverクラスの追加/削除via mouseentermouseleaveイベント検出を行いましたが、それだけでも、それ自体がほぼ「本物」のように機能し:hoverます。つまり、テーブル内の要素をタップしても、その要素が「離れた」ことは検出されないため、「偽装」状態が維持されます。

私がしたことも単に聞くだけだったclickので、ボタンを「タップ」すると手動でを発射しましたmouseleave

Siこれは私の最後のコードです:

.fakeHover {
    background-color: blue;
}


$(document).on('mouseenter', 'button.myButton',function(){
    $(this).addClass('fakeHover');
});

$(document).on('mouseleave', 'button.myButton',function(){
    $(this).removeClass('fakeHover');
});

$(document).on('button.myButton, 'click', function(){
    $(this).mouseleave();
});

これによりhover、マウスを使用してボタンを「ホバリング」するだけで通常の機能を維持できます。まあ、それのほとんどすべて:どういうわけか唯一の欠点は、マウスでボタンをクリックした後、それがhover状態にならないことです。クリックしてすぐにボタンからポインターを離した場合と同じです。しかし、私の場合、私はそれとともに生きることができます。


2

これは、残りの答えを研究した後に私がこれまでに思いついたものです。タッチのみ、マウスのみ、またはハイブリッドユーザーをサポートできる必要があります。

ホバー効果用に別のホバークラスを作成します。デフォルトでは、このホバークラスをボタンに追加します。

タッチサポートの存在を検出し、すべてのホバー効果を最初から無効にしたくありません。他の人が述べたように、ハイブリッドデバイスが人気を集めています。人々はタッチサポートを持っているかもしれませんが、マウスを使用したいと思っています。したがって、ユーザーが実際にボタンに触れたときにのみホバークラスを削除します。

次の問題は、ユーザーがボタンに触れた後、マウスを使用することに戻りたい場合はどうなりますか?それを解決するには、削除したホバークラスを追加するための適切な瞬間を見つける必要があります。

ただし、ホバー状態がまだアクティブであるため、削除した直後に再度追加することはできません。ボタン全体を破棄して再作成したくない場合もあります。

そこで、ビジー待機アルゴリズム(setIntervalを使用)を使用してホバー状態を確認することを考えました。ホバー状態が非アクティブ化されたら、ホバークラスを追加してビジー待機を停止し、ユーザーがマウスまたはタッチを使用できる元の状態に戻すことができます。

忙しい待っていることはそれほど素晴らしいことではありませんが、適切なイベントがあるかどうかはわかりません。マウスリーブイベントで再度追加することを検討しましたが、それほど堅牢ではありませんでした。たとえば、ボタンがタッチされた後にアラートがポップアップすると、マウスの位置は移動しますが、mouseleaveイベントはトリガーされません。

var button = document.getElementById('myButton');

button.ontouchstart = function(e) {
  console.log('ontouchstart');
  $('.button').removeClass('button-hover');
  startIntervalToResetHover();
};

button.onclick = function(e) {
  console.log('onclick');
}

var intervalId;

function startIntervalToResetHover() {
  // Clear the previous one, if any.
  if (intervalId) {
    clearInterval(intervalId);
  }
  
  intervalId = setInterval(function() {
    // Stop if the hover class already exists.
    if ($('.button').hasClass('button-hover')) {
      clearInterval(intervalId);
      intervalId = null;
      return;
    }
    
    // Checking of hover state from 
    // http://stackoverflow.com/a/8981521/2669960.
    var isHovered = !!$('.button').filter(function() {
      return $(this).is(":hover");
    }).length;
    
    if (isHovered) {
      console.log('Hover state is active');
    } else {
      console.log('Hover state is inactive');
      $('.button').addClass('button-hover');
      console.log('Added back the button-hover class');
      
      clearInterval(intervalId);
      intervalId = null;
    }
  }, 1000);
}
.button {
  color: green;
  border: none;
}

.button-hover:hover {
  background: yellow;
  border: none;
}

.button:active {
  border: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id='myButton' class='button button-hover'>Hello</button>

編集:私が試した別のアプローチは、e.preventDefault()ontouchstartまたはontouchend内で呼び出すことです。ボタンがタッチされるとホバー効果が停止するように見えますが、ボタンクリックアニメーションも停止し、ボタンがタッチされるとonclick関数が呼び出されないため、ontouchstartまたはontouchendハンドラーで手動で呼び出す必要があります。あまりクリーンなソリューションではありません。


1

それは私にとって役に立ちました:リンク

function hoverTouchUnstick() {
    // Check if the device supports touch events
    if('ontouchstart' in document.documentElement) {
        // Loop through each stylesheet
        for(var sheetI = document.styleSheets.length - 1; sheetI >= 0; sheetI--) {
            var sheet = document.styleSheets[sheetI];
            // Verify if cssRules exists in sheet
            if(sheet.cssRules) {
                // Loop through each rule in sheet
                for(var ruleI = sheet.cssRules.length - 1; ruleI >= 0; ruleI--) {
                    var rule = sheet.cssRules[ruleI];
                    // Verify rule has selector text
                    if(rule.selectorText) {
                        // Replace hover psuedo-class with active psuedo-class
                        rule.selectorText = rule.selectorText.replace(":hover", ":active");
                    }
                }
            }
        }
    }
}

グローバルontouchstartイベントハンドラーからhoverTouchUnstick()を1回呼び出す必要があります。そして、このソリューションは完全に機能します。
ジュシド

1

次のJSコードをページに追加します。

document.body.className = 'ontouchstart' in document.documentElement ? '' : 'hover';

CSSで、ホバーする前に次のようにホバークラスを追加します。

.hover .foo:hover {}

デバイスがタッチされている場合、ボディクラスは空になります。それ以外の場合、そのクラスはホバーされ、ルールが適用されます。


私にはうまくdocument.body.className = 'ontouchstart' in window ? '' : 'hover';
いき

1

各ボタンにホバーなしのクラスontouchendを追加し、次のようなCSSを作成できます> this:button:not(.no-hover):hover {background-color:blue; }しかし、それはおそらくパフォーマンスにかなり悪影響を及ぼし、Chromebook Pixel(タッチスクリーンとマウスの両方を備えている)のようなデバイスを正しく処理しません。

これが正しい出発点です。次のステップ:次のイベントでnohoverクラスを適用/削除する(jQueryを使用したデモ)

buttonelement
 .on("touchend touchcancel",function(){$(this).addClass("nohover")})
 .on("touchstart mouseover",function({$(this).removeClass("nohover")});   

注意:ボタン要素に他のクラスを適用したい場合、CSSの:not(.nohover)は期待どおりに機能しなくなります。ホバースタイルを上書きするには、代わりにデフォルト値と!importantタグを使用して別の定義を追加する必要があります:.nohover {background-color:white!important}

これにより、Chromebook Pixel(タッチスクリーンとマウスの両方を備えている)などのデバイスも正しく処理できます。そして、私はこれが主要なパフォーマンスキラーだとは思わない...


1

私のために働いた解決策:

html {
   -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

このコードをスタイルシートに追加します。

リンクをクリックしたときにiOS Safariに表示される灰色の背景を削除したかったのです。しかし、それはもっと多くのことをするようです。ボタンをクリックすると(:hover疑似クラスで!)すぐに開きます!私はiPadでテストしただけで、他のデバイスで動作するかどうかはわかりません。


1

私は同様の問題のエレガントな(最小のjs)ソリューションを見つけたと思います:

jQueryを使用すると、本文(またはその他の要素)にホバーをトリガーできます。 .mouseover()

したがって、次のように、このハンドラーを要素のontouchendイベントに単にアタッチします。

var unhover = function() {
  $("body").mousover();  
};
.hoverable {
  width: 100px;
  height: 100px;
  background: teal;
  cursor: pointer;
}

.hoverable:hover {
  background: pink;
}
<div class="hoverable" ontouchend={unhover}></div>

ただし、これは、スワイプや別のタッチなどの他のタッチイベントがトリガーされた後にのみ、要素から:hover疑似クラスを削除します


1
コードスニペットの場合、正方形をタッチした後も正方形はピンクのままです。この質問で尋ねられた問題を本当に解決しなかったと思いますか?
Kevin Lee

このソリューションは機能しません。最初に、間違ったメソッドを使用してイベントを呼び出しました。.trigger()を使用する必要があります。第二に、どちらの方法でもモバイルサファリでは機能しません。
xHocquet 2017年

1

私が共有したい素敵な解決策があります。最初に、ユーザーが次のようにモバイルにいるかどうかを検出する必要があります。

var touchDevice = /ipad|iphone|android|windows phone|blackberry/i.test(navigator.userAgent.toLowerCase());

次に追加するだけです:

if (!touchDevice) {
    $(".navbar-ul").addClass("hoverable");
}

そしてCSSでは:

.navbar-ul.hoverable li a:hover {
    color: #fff;
}

2
WindowsタッチスクリーンPCなどのハイブリッドデバイスでは機能しません。
cspolton

1

私は同様の問題を経験しました、私のアプリケーションはすべての画面サイズに互換性があり、デスクトップ画面サイズ /マウスベースのデバイスでホバー効果が非常に多く、後でタッチベースのデバイスがスティッキーと呼ばれる状態を引き起こしていることに気付きました-ホバーし、タッチベースのデバイスユーザーに対してアプリが適切に機能することはハードルでした。

私たちはアプリでSCSSを利用していました。タッチベースのデバイスを処理するためのミックスインを定義しました。

@mixin hover-support {
  @media not all and (pointer: coarse) {
    &:hover {
      @content;
    }
  }
}

次に、すべてのcssクラスを下記のスニペットの下に配置しました。

   @include hover-support() {
    // Your css-classes or css that you want to apply on those devices that support hover.
   }

たとえば、アイコンをアニメーション化するためのクラスがあり、CSSから確認できるようにアイコンにカーソルを合わせるとトリガーされていましたが、タッチベースのデバイスではスティッキーホバー効果の影響を受けて、@の中に配置しましたホバーがホバーをサポートするデバイスにのみ適用されるようにするには、hover-support()を含めます

@include hover-support() {
  .animate-icon {
    -webkit-transition: all 0.2s;
    transition: all 0.2s;
    &:hover {
      transform: scale(1.3);
      filter: brightness(85%);
      cursor: pointer;
    }
  }
}

1

開発者がCSSを編集したり、新しいCSSルールを記述したりする必要のない簡単なJavaScriptコードを以下に示します。これをでブートストラップボタン用に作成class="btn"しましたが、特定のクラス名を持つすべてのボタンで動作します。

手順は次のとおりです。

  1. これがタッチデバイスかどうかを判別
  2. そうであれば、すべてのCSSルールを繰り返します document.styleSheets
  3. .btnとの両方を含むルールを削除します:hover

すべての.btn :hoverCSSルールを排除することで、ボタンにホバー効果が表示されなくなります。

手順1:タッチデバイスを検出する

メディアクエリの存在を確認します(hover: none)

    const hasMatchMedia = typeof window.matchMedia !== 'undefined';
    /**
     * determine if device is touch-capable
     * true - device is touch-capable
     * false - device is not touch-capable
     * null - unable to determine touch capability
     * @return {null|boolean}
     */
    const hasTouch = () => {
      if (hasMatchMedia) {
        return window.matchMedia('(hover: none)').matches;
      }
      return null;
    };

ステップ2: `btn`と`:hover`を含むCSSルールを削除する

    /**
     * remove all CSS rules contaning both '.btn' and ':hover'
     * @return {number} count of rules deleted
     */
    function removeBtnHovers () {

      let rulesDeleted = 0;

      // recursively delete '.btn:hover' rules
      function recursiveDelete (rules, styleSheet) {

        if (typeof rules === 'undefined' ||
          typeof rules.length === 'undefined' ||
          rules.length <= 0) {
          return;
        }

        // iterate in reverse order,
        // deleting any rule containing both '.btn' and ':hover'
        const ruleLen = rules.length;
        for (let i = ruleLen - 1; i >= 0; i--) {
          const rule = rules[i];
          if (typeof rule.cssRules === 'undefined') {
            // a standard rule, evaluate it
            const cssText = rule.cssText;
            if (typeof cssText === 'string' &&
              cssText.includes('.btn') &&
              cssText.includes(':hover')) {
              styleSheet.deleteRule(i);
              rulesDeleted++;
            }
          } else {
            // rule contains cssRules, iterate over them
            recursiveDelete(rule.cssRules, rule);
          }
        }
      }

      // iterate over all style sheets in document
      for (const styleSheet of document.styleSheets) {
        let rules = styleSheet.cssRules;
        if (!rules) { continue; }
        recursiveDelete(rules, styleSheet);
      }
      return rulesDeleted;
    }

完全なコードはGitHubnpmにあります。

terrymorse.comでのライブデモ。


これは、マウス/トラックパッドを備えたタッチスクリーンデバイスのホバー効果も削除しませんか?
ジェンセイ

@ジェンセイ デバイスがに一致した場合@media (hover:none)、またはユーザーが最初に画面に触れた場合、ホバールールは削除されます。ライブデモページで試してみてください。
terrymorse

0

あなたは:active状態の背景色を設定し:focus 、デフォルトの背景を与えることができます。

を介してbackground-colorを設定した場合onfocus/ontouch:focus状態がなくなってもカラースタイルはそのままです。フォーカスが失われたときにデフォルトのbgを復元
するには、リセットもオンにする必要がありonblurます。


しかし、マウスユーザーのホバー効果を維持したいと思います。
Chris

:hoverと:activeは同じCSSを受け取ることができ、問題がある:focusにあります。実際、onfocusでbackground-colorを設定した場合、フォーカスがなくなってもカラースタイルは維持されます。デフォルトのbgを復元するには、onlurでもリセットが必要です
G-Cyrillus

0

これは私にとってうまくいきました:ホバースタイルを新しいクラスに入れます

.fakehover {background: red}

次に、必要に応じてクラスを追加/削除します

$(".someclass > li").on("mouseenter", function(e) {
  $(this).addClass("fakehover");
});
$(".someclass > li").on("mouseleave", function(e) {
  $(this).removeClass("fakehover");
});

touchstartイベントとtouchendイベントについて繰り返します。または、希望する結果を得るために好きなイベント、たとえば、タッチスクリーンでホバー効果を切り替えたいと思っていました。


0

Darren Cooksの回答に基づく。これは、指を別の要素の上に移動した場合にも機能します。

参照してください検索要素の指がtouchendイベント中にあります

jQuery(function() {
    FastClick.attach(document.body);
});
// Prevent sticky hover effects for buttons on touch devices
// From https://stackoverflow.com/a/17234319
//
//
// Usage:
// <a href="..." touch-focus-fix>..</a>
//
// Refactored from a directive for better performance and compability
jQuery(document.documentElement).on('touchend', function(event) {
  'use strict';

  function fix(sourceElement) {
    var el = $(sourceElement).closest('[touch-focus-fix]')[0];
    if (!el) {
      return;
    }
    var par = el.parentNode;
    var next = el.nextSibling;
    par.removeChild(el);
    par.insertBefore(el, next);
  }

  fix(event.target);
  var changedTouch = event.originalEvent.changedTouches[0];
  // http://www.w3.org/TR/2011/WD-touch-events-20110505/#the-touchend-event
  if (!changedTouch) {
    return;
  }
  var touchTarget = document.elementFromPoint(changedTouch.clientX, changedTouch.clientY);
  if (touchTarget && touchTarget !== event.target) {
    fix(touchTarget);
  }
});

Codepen Demo


0

この方法を試すことができます。

javascript:

var isEventSupported = function (eventName, elementName) {
    var el = elementName ? document.createElement(elementName) : window;
    eventName = 'on' + eventName;
    var isSupported = (eventName in el);
    if (!isSupported && el.setAttribute) {
        el.setAttribute(eventName, 'return;');
        isSupported = typeof el[eventName] == 'function';
    }
    el = null;
    return isSupported;
};

if (!isEventSupported('touchstart')) {
    $('a').addClass('with-hover');
}

css:

a.with-hover:hover {
  color: #fafafa;
}

0

私のプロジェクトでこれまでに行ったことは:hover、タッチデバイスの変更を元に戻すことでした。

.myhoveredclass {
    background-color:green;
}
.myhoveredclass:hover {
    background-color:red;
}
@media screen and (-webkit-min-device-pixel-ratio:0) {
    .myhoveredclass:hover, .myhoveredclass:active, .myhoveredclass:focus {
        background-color:green;
    }
}

すべてのクラス名と名前の付いた色は、デモ用です;-)


0

これは2つのステップで完全に機能します。

  1. bodyタグを次のように設定します<body ontouchstart="">。私はこの「ハック」のファンではありませんが、iOS上のSafariがタッチに即座に反応できるようにします。方法はわかりませんが、動作します。

  2. 次のようにタッチ可能なクラスを設定します。

    // I did this in SASS, but this should work with normal CSS as well
    
    // Touchable class
    .example {
    
        // Default styles
        background: green;
    
        // Default hover styles 
        // (Think of this as Desktop and larger)
        &:hover {
            background: yellow;
        }
    
        // Default active styles
        &:active {
            background: red;
        }
    
        // Setup breakpoint for smaller device widths
        @media only screen and (max-width: 1048px) {
    
            // Important!
            // Reset touchable hover styles
            // You may want to use the same exact styles as the Default styles
            &:hover {
                background: green;
            }
    
            // Important!
            // Touchable active styles
            &:active {
                background: red;
            }
        }
    }

タッチ可能なクラスのアニメーションも削除したい場合があります。Android ChromeはiOSより少し遅いようです。

これにより、ユーザーがクラスに触れている間にページをスクロールした場合にも、アクティブ状態が適用されます。


0

ブラウザが画面を操作しようとしたときに、:hover :focus :activeモバイルデバイスのスティッキーまたはスタックの問題の一部が見つからないことが原因である可能性が<meta name="viewport" content="width=device-width">あります。


0

私にとっての解決策は、タッチエンドがノードを複製して置き換えることでした...これを行うのは嫌いですが、offsetHeightで要素を再描画しようとしても機能しませんでした

    let cloneNode = originNode.cloneNode( true );
    originNode.parentNode.replaceChild( cloneNode, originNode );

結局、これは私にとってはうまくいきませんでした...私の場合、拡張されたES6全体といくつかのイベントリスナーを複製する必要があります。
禁止

0

HTMLクラスを交換することで実現できます。特に大きな画像リンクなどでは、要素全体を削除するよりもグリッチが発生しにくいはずです。

ホバーするかどうかも決定できます、タッチでスクロールしたときに状態をトリガー(touchmove)、タイムアウトを追加して遅延させるます。

コードの重要な変更は<a class='hover'></a>、新しい動作を実装する要素などで追加のHTMLクラスを使用することだけです。

HTML

<a class='my-link hover' href='#'>
    Test
</a>

CSS

.my-link:active, // :active can be turned off to disable hover state on 'touchmove'
.my-link.hover:hover {

    border: 2px dotted grey;
}

JS(jQueryを使用)

$('.hover').bind('touchstart', function () {

   var $el;
   $el = $(this);
   $el.removeClass('hover'); 

   $el.hover(null, function () {
      $el.addClass('hover');
   });
});

https://codepen.io/mattrcouk/pen/VweajZv

-

ただし、マウスとタッチの両方を備えたデバイスを使用していないため、適切にテストできません。


0

2020年からメディアクエリ内にホバースタイルを追加できます

@media (hover: hover) and (pointer: fine) {
    /* css hover class/style */
}

このメディアクエリは、スタイルが:hoverをエミュレートしないブラウザーで機能するため、タッチブラウザーでは機能しないことを示しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.