如何在支持触摸的浏览器中通过触摸模拟悬停?

IT技术 javascript html css hover touch
2021-01-14 23:19:58

使用一些像这样的 HTML:

<p>Some Text</p>

然后一些像这样的CSS:

p {
  color:black;
}

p:hover {
  color:red;
}

如何允许在启用触摸的设备上长按以复制悬停?我可以更改标记/使用 JS 等,但想不出一个简单的方法来做到这一点。

6个回答

好的,我已经解决了!它涉及稍微更改 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;        
}

停止浏览器要求您复制/保存/选择图像或其他任何内容。

简单!

无论如何要忽略滚动手势?这正是我需要的,但现在我无法上下滚动具有这种效果的内容。
2021-03-12 23:19:58
在我的网站中删除了touchendpreventDefault()并且它运行良好,但现在菜单不会因点击目标而自动关闭。
2021-03-15 23:19:58
我还想就如何在用户触摸其他地方或开始滚动时关闭此类菜单提供一些建议。我想touchstart身体上可能还有另一个听众(或类似的),但我想知道是否有更好的方法。谢谢!
2021-03-18 23:19:58
这很棒。不过,我将 domready 功能分开,因为toggle如果用户触摸一个元素并拖动到另一个元素(例如,如果他们触摸错误的项目并试图取消触摸),则会把事情搞砸
2021-03-27 23:19:58
我删除了 preventDefault ,因为我希望滚动可用,但感谢有关 touchstart 和 touchend 的提示!上帝发送这是唯一可以在所有浏览器上可靠运行的答案。
2021-04-05 23:19:58

您需要做的就是在父级上绑定 touchstart。像这样的事情会起作用:

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

你不需要在函数中做任何事情,把它留空。这足以在触摸时获得悬停,因此触摸的行为更像 :hover 而不太像 :active。iOS 魔法。

很棒的解决方案!快捷方便。
2021-03-14 23:19:58
不,它仍然会在第一次触摸时触发点击。我刚刚测试了它。
2021-03-28 23:19:58
此解决方案是否允许在第二次点击时执行链接?
2021-04-05 23:19:58

试试这个:

<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 类!

为我工作。谢谢...唯一的事情-它有点滞后...我的意思是-按下后,它不会立即加载。
2021-03-25 23:19:58
使用 fastclick.js 消除延迟
2021-03-26 23:19:58
这对我有用.. 其他一些可能对这个更有帮助的事情是而不是添加 javascript,这样做: <body ontouchstart=""> 然后在 css 中添加一个小计时器 :active 事件: tr:active { background-color :#118aab; 过渡:所有 .2s 线性;-webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-user-select:无;-webkit-touch-callout: 无 }
2021-04-07 23:19:58

回答您的主要问题:“如何在支持触摸的浏览器中通过触摸来模拟悬停?”

只需允许“点击”元素(通过点击屏幕),然后hover使用 JavaScript触发事件。

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/

如果您想使用“长按”来触发悬停,您可以使用上面的代码片段作为起点,并享受计时器之类的乐趣;)

好像如果你已经在使用 jQuery,你可以只用 jQuery 本身调用悬停事件,例如:jQuery.hover(); 不过,不确定 api 是否支持。
2021-03-14 23:19:58
我不知道 onhover.call(p) 位,这很酷。虽然没有关闭悬停...
2021-03-19 23:19:58
您是否使用多个元素和长时间触摸进行了测试?这意味着用户在屏幕上移动手指,并为每个元素显示悬停样式?
2021-03-30 23:19:58
oop,这是一条更适用于上面实际上使用 jQuery 的帖子的评论,抱歉。
2021-04-02 23:19:58
您是否需要任何特殊的脚本或调用该函数?它对我有用,但只在一页上,我不知道有什么区别。
2021-04-02 23:19:58

进一步改进的解决方案

首先我采用了Rich Bradshaw 的方法,但随后问题开始出现。通过'touchstart'事件执行e.preventDefault(),页面不再滚动,并且长按既不能触发选项菜单,也不能双击缩放完成执行。

溶液可以找出哪些事件被称为,只是e.preventDefault()在后来的一个,“touchend”由于 scroll 的'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');
});

但是,当出现选项菜单时,它不再触发“触摸”负责切换类,下次悬停行为将是另一个方式,完全混合。

一个解决方案是,再次有条件地找出我们在哪个事件中,或者只是做单独的事件,并分别在'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 类和伪 :hover 之间没有混合)的第二个,更干净,更整洁和响应式的方法,并且您可以从那里直接调用通用(移动和桌面)'click'事件上的 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!
    }
});