簡體   English   中英

如何使用觸控啟用的瀏覽器模擬懸停?

[英]How do I simulate a hover with a touch in touch enabled browsers?

使用這樣的HTML:

<p>Some Text</p>

然后一些CSS像這樣:

p {
  color:black;
}

p:hover {
  color:red;
}

如何允許長時間觸摸啟用觸摸的設備復制懸停? 我可以改變標記/使用JS等,但想不到一個簡單的方法來做到這一點。

好的,我已經解決了! 它涉及稍微改變CSS並添加一些JS。

使用jQuery使其變得簡單:

$(document).ready(function() {
    $('.hover').on('touchstart touchend', function(e) {
        e.preventDefault();
        $(this).toggleClass('hover_effect');
    });
});

在英語中:當您開始或結束觸摸時,打開或關閉班級hover_effect

然后,在HTML中,將類懸停添加到您希望使用的任何內容。 在您的CSS中,替換以下任何實例:

element:hover {
    rule:properties;
}

element:hover, element.hover_effect {
    rule:properties;
}

只是為了增加實用性,也可以將它添加到CSS中:

.hover {
-webkit-user-select: none;
-webkit-touch-callout: none;        
}

停止瀏覽器要求您復制/保存/選擇圖像或其他任何內容。

簡單!

您需要做的就是在父級上綁定touchstart。 這樣的東西會起作用:

$('body').on('touchstart', function() {});

您無需在函數中執行任何操作,請將其留空。 這足以讓人在觸摸時盤旋,因此觸摸行為更像是:懸停而不像:活躍。 iOS魔術。

試試這個:

<script>
document.addEventListener("touchstart", function(){}, true);
</script>

在你的CSS中:

element:hover, element:active {
-webkit-tap-highlight-color: rgba(0,0,0,0);
-webkit-user-select: none;
-webkit-touch-callout: none /*only to disable context menu on long press*/
}

使用此代碼,您不需要額外的.hover類!

要回答您的主要問題: “如何通過觸摸啟用瀏覽器來模擬懸停?”

只需允許“點擊”元素(通過點擊屏幕),然后使用JavaScript觸發hover事件。

var p = document.getElementsByTagName('p')[0];
p.onclick = function() {
 // Trigger the `hover` event on the paragraph
 p.onhover.call(p);
};

只要您的設備上有hover事件(即使通常不使用),這應該可以正常工作。

更新:我剛剛在我的iPhone上測試了這種技術,它似乎工作正常。 在這里嘗試: http//jsfiddle.net/mathias/YS7ft/show/light/

如果你想使用“長觸摸”來觸發懸停,你可以使用上面的代碼片段作為起點,享受定時器和東西的樂趣;)

進一步改進的方案

首先,我采用Rich Bradshaw的方法 ,然后問題開始出現。 通過對'touchstart'事件執行e.preventDefault() ,頁面不再滾動,長按既不能觸發選項菜單也不能雙擊縮放能夠完成執行。

一個解決方案可能是找出正在調用的事件,並在后面的'touchend'中找到e.preventDefault() 由於滾動的'touchmove'出現在'touchend'之前,它默認保持不變,並且'click'也會被阻止,因為事件鏈中的詞語應用於移動設備,如下所示:

// Binding to the '.static_parent' ensuring dynamic ajaxified content
$('.static_parent').on('touchstart touchend', '.link', function (e) {

    // If event is 'touchend' then...
    if (e.type == 'touchend') {
        // Ensuring we event prevent default in all major browsers
        e.preventDefault ? e.preventDefault() : e.returnValue = false;
    }

    // Add class responsible for :hover effect
    $(this).toggleClass('hover_effect');
});

但是,當選項菜單出現時,它不再觸發'touchend'負責切換課程,下次懸停行為將是另一種方式,完全混淆。

然后,一個解決方案將有條件地找出我們所處的事件,或者只是單獨執行,並分別在'touchstart''touchend'上使用addClass()removeClass () ,確保它始終以開始和結束為止分別添加和刪除而不是有條件地決定它。 為了完成,我們還將刪除回調綁定到'focusout'事件類型,負責清除任何可能保留的鏈接的懸停類,並且永遠不會再次重新訪問,如下所示:

$('.static_parent').on('touchstart', '.link', function (e) {
    $(this).addClass('hover_effect');
});

$('.static_parent').on('touchend focusout', '.link', function (e) {
    // Think double click zoom still fails here
    e.preventDefault ? e.preventDefault() : e.returnValue = false;
    $(this).removeClass('hover_effect');
});

注意:前兩個解決方案中仍然會出現一些錯誤,並且還認為(未經測試),雙擊縮放仍然失敗。

整潔和希望錯誤免費(不是:))Javascript解決方案

現在 ,對於第二個更干凈,更整潔,響應更快的方法,只使用javascript(.hover類和偽:懸停之間沒有混合),你可以直接在通用(移動和桌面) '點擊'事件上調用你的ajax行為,我發現了一個很好的回答問題 ,我終於明白了如何將觸摸和鼠標事件混合在一起而沒有幾個事件回調不可避免地在事件鏈中改變彼此的事件。 這是如何做:

$('.static_parent').on('touchstart mouseenter', '.link', function (e) {
    $(this).addClass('hover_effect');
});

$('.static_parent').on('mouseleave touchmove click', '.link', function (e) {
    $(this).removeClass('hover_effect');

    // As it's the chain's last event we only prevent it from making HTTP request
    if (e.type == 'click') {
        e.preventDefault ? e.preventDefault() : e.returnValue = false;

        // Ajax behavior here!
    }
});

鼠標hover效果無法在觸控設備中實現。 當我在safari ios出現相同情況時我使用:active在css中:active以實現效果。

即。

p:active {
  color:red;
}

在我的情況下它的工作。可能這也是可以使用javascript使用的情況。 試試吧。

添加此代碼,然后將類“tapHover”設置為您希望以此方式工作的元素。 第一次點擊一個元素時,它將獲得偽類“:hover”和類“tapped”。 將阻止點擊事件。 第二次點擊相同的元素 - 將觸發click事件。

 // Activate only in devices with touch screen if('ontouchstart' in window) { // this will make touch event add hover pseudoclass document.addEventListener('touchstart', function(e) {}, true); // modify click event document.addEventListener('click', function(e) { // get .tapHover element under cursor var el = jQuery(e.target).hasClass('tapHover') ? jQuery(e.target) : jQuery(e.target).closest('.tapHover'); if(!el.length) return; // remove tapped class from old ones jQuery('.tapHover.tapped').each(function() { if(this != el.get(0)) jQuery(this).removeClass('tapped'); }); if(!el.hasClass('tapped')) { // this is the first tap el.addClass('tapped'); e.preventDefault(); return false; } else { // second tap return true; } }, true); } 
 .box { float: left; display: inline-block; margin: 50px 0 0 50px; width: 100px; height: 100px; overflow: hidden; font-size: 20px; border: solid 1px black; } .box.tapHover { background: yellow; } .box.tapped { border: solid 3px red; } .box:hover { background: red; } 
 <div class="box" onclick="this.innerHTML = Math.random().toFixed(5)"></div> <div class="box tapHover" onclick="this.innerHTML = Math.random().toFixed(5)"></div> <div class="box tapHover" onclick="this.innerHTML = Math.random().toFixed(5)"></div> 

沒有設備(或更確切地說是瀏覽器)特定的JS,我很確定你運氣不好。

編輯:以為你想要避免這種情況,直到我重讀你的問題。 對於Mobile Safari,您可以注冊以獲取與您使用本機UIView-s類似的所有觸摸事件。 現在找不到文檔,但會嘗試。

一種方法是在觸摸開始時進行懸停效果,然后在觸摸移動或結束時移除懸停效果。

由於你提到iPhone,這就是蘋果公司對觸控處理的一般說法。

我的個人品味是將:hover樣式歸因於:focus狀態,如:

p {
    color: red;
}

p:hover, p:focus {
    color: blue;
}

然后使用以下HTML:

<p id="some-p-tag" tabindex="-1">WOOOO</p>

以下JavaScript:

$("#some-p-tag").on("touchstart", function(e){
    e.preventDefault();
    var $elem = $(this);

    if($elem.is(":focus")) {
        //this can be registered as a "click" on a mobile device, as it's a double tap
        $elem.blur()
    }
    else {
        $elem.focus();
    }
});

本機Javascript和jQuery的混合:

var gFireEvent = function (oElem,sEvent) 
{
 try {
 if( typeof sEvent == 'string' && o.isDOM( oElem ))
 {
  var b = !!(document.createEvent),
     evt = b?document.createEvent("HTMLEvents"):document.createEventObject();
  if( b )    
  {  evt.initEvent(sEvent, true, true ); 
    return !oElem.dispatchEvent(evt);
  }
  return oElem.fireEvent('on'+sEvent,evt);
 }
 } catch(e) {}
 return false;
};


// Next you can do is (bIsMob etc you have to determine yourself):

   if( <<< bIsMob || bIsTab || bisTouch >>> )
   {
     $(document).on('mousedown', function(e)
     {
       gFireEvent(e.target,'mouseover' );
     }).on('mouseup', function(e)
     {
       gFireEvent(e.target,'mouseout' );
     });
   }

我發現最簡單的解決方案:我有一些<span>標簽:hover css規則。 我換了<a href =“javascript:void(0)”>和il。 iOS中的懸停樣式開始起作用。

使用也可以使用CSS,將焦點和活動(對於IE7及以下)添加到隱藏鏈接。 帶有類菜單的div中的ul菜單示例:

.menu ul ul {display:none; position:absolute; left:100%; top:0; padding:0;}
.menu ul ul ul {display:none; position:absolute; top:0; left:100%;}
.menu ul ul a, .menu ul ul a:focus, .menu ul ul a:active { width:170px; padding:4px 4%; background:#e77776; color:#fff; margin-left:-15px; }
.menu ul li:hover > ul { display:block; }
.menu ul li ul li {margin:0;}

這是遲到的,未經測試,應該工作;-)

解決了2019年 - 懸停在觸摸上

現在似乎最好避免一般使用ios或touch進行懸停。 只要保持觸摸,並且沒有其他ios彈出按鈕,以下代碼將應用您的CSS。 做這個;

  1. Jquery add:$(“p”)。on(“touchstart”,function(e){$(this).focus(); e.preventDefault();});

  2. CSS:用p:focus替換p:hover,並添加p:active

選項;

  • 用任何類等替換jquery p選擇器

  • 要保持效果,請保持p:hover,然后添加body {cursor:ponter;}以便點按任意位置結束它

  • 嘗試點擊和鼠標懸停事件以及相同代碼中的touchstart(但未測試)

  • 刪除e.preventDefault(); 使用戶能夠利用ios彈出窗口,例如復制

筆記

  • 只測試了文本元素,ios可以不同地處理輸入等

  • 僅在iphone XR ios 12.1.12和ipad 3 ios 9.3.5上使用Safari或Chrome進行測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM