Javascript 如何防止触摸设备上的按钮出现粘性悬停效果
我创建了一个旋转木马,上面有一个始终可见的“上一个”和“下一个”按钮。这些按钮处于悬停状态,它们变为蓝色。在像iPad这样的触摸设备上,悬停状态是粘性的,所以点击按钮后按钮保持蓝色。我不想那样Javascript 如何防止触摸设备上的按钮出现粘性悬停效果,javascript,css,hover,touch,Javascript,Css,Hover,Touch,我创建了一个旋转木马,上面有一个始终可见的“上一个”和“下一个”按钮。这些按钮处于悬停状态,它们变为蓝色。在像iPad这样的触摸设备上,悬停状态是粘性的,所以点击按钮后按钮保持蓝色。我不想那样 我可以为每个按钮添加一个no hoverclassontouchend,然后 我的CSS是这样的:按钮:不(.no hover):hover{背景色: 蓝色;}但这可能对性能非常不利,而且不会 处理像Chromebook Pixel这样的设备(它具有 触摸屏和鼠标)正确 我可以在documentElem
- 我可以为每个按钮添加一个
classno hover
,然后 我的CSS是这样的:ontouchend
但这可能对性能非常不利,而且不会 处理像Chromebook Pixel这样的设备(它具有 触摸屏和鼠标)正确按钮:不(.no hover):hover{背景色: 蓝色;}
- 我可以在
中添加documentElement
类,并制作CSS 如下:touch
但这在既有触摸屏又有触摸屏的设备上也不起作用 老鼠html:not(.touch)按钮:悬停{背景色:蓝色; }
ontouchend
。但这似乎是不可能的。聚焦另一个元素不会移除悬停状态。手动点击另一个元素可以,但我似乎无法在JavaScript中触发它
我找到的所有解决方案似乎都不完美。有完美的解决方案吗?您可以将背景色设置为
:active
状态,并将背景设置为:focus
如果通过onfocus/ontouch
设置背景色,颜色样式将保持一次:focus
状态已消失。当焦点丢失时,您还需要重置
onblur
以恢复defaut bg。您可以通过临时从DOM中删除链接来删除悬停状态。看
在CSS中,您有:
:hover {background:red;}
function fix()
{
var el = this;
var par = el.parentNode;
var next = el.nextSibling;
par.removeChild(el);
setTimeout(function() {par.insertBefore(el, next);}, 0)
}
<a href="#" ontouchend="this.onclick=fix">test</a>
在JS中,您有:
:hover {background:red;}
function fix()
{
var el = this;
var par = el.parentNode;
var next = el.nextSibling;
par.removeChild(el);
setTimeout(function() {par.insertBefore(el, next);}, 0)
}
<a href="#" ontouchend="this.onclick=fix">test</a>
然后在HTML中,您有:
:hover {background:red;}
function fix()
{
var el = this;
var par = el.parentNode;
var next = el.nextSibling;
par.removeChild(el);
setTimeout(function() {par.insertBefore(el, next);}, 0)
}
<a href="#" ontouchend="this.onclick=fix">test</a>
这是一个常见的问题,没有完美的解决方案。鼠标的悬停行为是有用的,而触摸则是有害的。使问题更加复杂的是支持触摸和鼠标的设备(同时,同样如此!),比如Chromebook像素和表面 我找到的最干净的解决方案是,只有当设备不支持触摸输入时,才启用悬停行为
var isTouch = !!("ontouchstart" in window) || window.navigator.msMaxTouchPoints > 0;
if( !isTouch ){
// add class which defines hover behavior
}
当然,您在可能支持它的设备上失去了悬停。但是,有时悬停的影响比链接本身更大,例如,当元素悬停时,您可能希望显示菜单。这种方法允许您测试触摸是否存在,并可能有条件地附加不同的事件
我已经在iPhone、iPad、Chromebook Pixel、Surface和各种Android设备上进行了测试。我不能保证在混音中添加通用USB触控输入(如触控笔)时,它会起作用。您可以专门针对非触控设备进行悬停:
.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;
}
}
(注意:这不会在StackOverflow的代码段系统上运行,请检查)
请注意,:active
不需要以为目标。无需触摸
,因为它在移动设备和桌面上都能正常工作。一旦实现,您将能够执行以下操作:
@media (hover: hover) {
button:hover {
background-color: blue;
}
}
或英文:“如果浏览器支持正确/真实/真实/非模拟悬停(例如,有一个类似鼠标的主输入设备),则在悬停按钮时应用此样式。”
由于媒体查询级别4的这一部分到目前为止只在最前沿的Chrome中实现,因此需要解决这个问题。使用它,您可以将上述未来主义CSS转换为:
html.my-true-hover button:hover {
background-color: blue;
}
(是.no touch
技术的一种变体)然后使用同一个polyfill中检测到对悬停支持的一些客户端JavaScript,您可以相应地切换my true hover
类的存在:
$(document).on('mq4hsChange', function (e) {
$(document.documentElement).toggleClass('my-true-hover', e.trueHover);
});
这对我很有帮助:
这对我很有用:将悬停样式放在一个新类中
.fakehover {background: red}
然后根据需要添加/删除该类
$(".someclass > li").on("mouseenter", function(e) {
$(this).addClass("fakehover");
});
$(".someclass > li").on("mouseleave", function(e) {
$(this).removeClass("fakehover");
});
对touchstart和touchend事件重复上述步骤。或者任何您希望获得所需结果的事件,例如,我希望在触摸屏上切换悬停效果。将此JS代码添加到您的页面:
$("#elementwithhover").click(function() {
// code that makes element or parent slide or otherwise move out from under mouse.
$(this).clone(true).insertAfter($(this));
$(this).remove();
});
document.body.className = 'ontouchstart' in document.documentElement ? '' : 'hover';
现在在CSS中,在每次悬停之前添加如下悬停类:
.hover .foo:hover {}
// 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;
}
}
}
var touchDevice = /ipad|iphone|android|windows phone|blackberry/i.test(navigator.userAgent.toLowerCase());
如果设备为touch,body类将为空,否则其类将为hover,并应用规则
我可以为每个按钮在touchend上添加一个无悬停类,并使我的CSS类似于>this:button:not(.no hover):hover{background color:
蓝色;}但这可能对性能非常不利,并且不能正确处理>像Chromebook Pixel(它有触摸屏和鼠标)>这样的设备
这是正确的起点。下一步:
在以下事件上应用/删除nohover类(使用jQuery演示)
注意:如果您希望将其他类应用于ButtoneElement,CSS中的:not(.nohover)将不再像预期的那样工作。然后,您必须添加一个带有默认值和的单独定义!覆盖悬停样式的重要标记:
.nohover{背景色:白色!重要}
这甚至可以正确处理Chromebook Pixel(它同时具有触摸屏和鼠标)等设备!我不认为这是一个主要的性能杀手…一个对我有效的解决方案:
html {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
将此代码添加到样式表中
我想摆脱点击链接时iOS Safari上出现的灰色背景。但它似乎做得更多。现在,单击一个按钮(带有:hover
伪类!)立即打开!我只在iPad上测试过,不知道它是否能在其他设备上使用 我想我已经为类似的问题找到了一个优雅的(最小js)解决方案:
使用jQuery,您可以使用.mouseover()
因此,我只需将this处理程序附加到元素的ontouchend
事件,如下所示:
var unhover=function(){
$(“body”).mousover();
};代码>
。可悬停{
宽度:100px;
高度:100px;
背景:茶
.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;
}
}
// 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;
}
}
}
var touchDevice = /ipad|iphone|android|windows phone|blackberry/i.test(navigator.userAgent.toLowerCase());
if (!touchDevice) {
$(".navbar-ul").addClass("hoverable");
}
.navbar-ul.hoverable li a:hover {
color: #fff;
}
.my-thing {
color: #BADA55;
}
.my-thing:hover {
color: hotpink;
}
@media (hover: none) {
.my-thing {
color: #BADA55;
}
}
@mixin hover-support {
@media not all and (pointer: coarse) {
&:hover {
@content;
}
}
}
@include hover-support() {
// Your css-classes or css that you want to apply on those devices that support hover.
}
@include hover-support() {
.animate-icon {
-webkit-transition: all 0.2s;
transition: all 0.2s;
&:hover {
transform: scale(1.3);
filter: brightness(85%);
cursor: pointer;
}
}
}
<a class='my-link hover' href='#'>
Test
</a>
.my-link:active, // :active can be turned off to disable hover state on 'touchmove'
.my-link.hover:hover {
border: 2px dotted grey;
}
$('.hover').bind('touchstart', function () {
var $el;
$el = $(this);
$el.removeClass('hover');
$el.hover(null, function () {
$el.addClass('hover');
});
});
@media (hover: hover) and (pointer: fine) {
/* css hover class/style */
}
.button:focus {
outline: none;
}