Joe*_*ite 111 javascript hover touch
我正在编写一个旨在从台式机和平板电脑上使用的网站.当从桌面访问它时,我希望屏幕的可点击区域点亮:hover效果(不同的背景颜色等).使用平板电脑,没有鼠标,所以我不想要任何悬停效果.
问题是,当我在平板电脑上点击一些东西时,浏览器显然有某种"隐形鼠标光标",它移动到我点击的位置,然后将其留在那里 - 所以我刚刚点击的东西点亮了悬停效果,直到我点击其他东西.
我在使用鼠标时如何获得悬停效果,但在使用触摸屏时抑制它们?
如果有人想提出建议,我不想使用用户代理嗅探.同样的设备可能同时具有触摸屏和鼠标(今天可能不常见,但将来会更加如此).我对该设备不感兴趣,我对它目前的使用方式感兴趣:鼠标或触摸屏.
我已经尝试挂钩touchstart,touchmove和touchend事件,并呼吁preventDefault()对所有的人,这确实抑制"隐形鼠标"的一些时间; 但是如果我在两个不同的元素之间来回快速点击,经过几次点击它就会开始移动"鼠标光标"并点亮悬停效果 - 这就像我preventDefault并不总是很荣幸.除非必要,否则我不会厌倦你的细节 - 我甚至不确定这是正确的方法; 如果有人有更简单的解决方案,我会全力以赴.
编辑:这可以用沼泽标准的CSS :hover重现,但这里有一个快速的repro供参考.
<style>
.box { border: 1px solid black; width: 150px; height: 150px; }
.box:hover { background: blue; }
</style>
<div class="box"></div>
<div class="box"></div>
Run Code Online (Sandbox Code Playgroud)
如果你鼠标悬停在其中任何一个框上,它将获得我想要的蓝色背景.但是如果你点击其中任何一个盒子,它也会得到一个蓝色背景,这是我试图阻止的事情.
我还在这里发布了一个示例,它可以完成上述操作并且还可以挂钩jQuery的鼠标事件.您可以使用它来查看点击事件也会触发mouseenter,mousemove以及mouseleave.
Mac*_*eek 83
我从你的问题中得知你的悬停效果会改变你网页的内容.在这种情况下,我的建议是:
touchstart和mouseenter.mouseleave,touchmove和click.或者,您可以编辑您的页面,没有内容更改.
为了模拟鼠标,如果用户在触摸屏上触摸并释放手指(如iPad),Webkit移动等浏览器会触发以下事件(来源:html5rocks.com上的触摸和鼠标):
touchstarttouchmovetouchendmouseovermouseenter
mouseover,mouseenter或mousemove事件改变页面的内容,以下事件从未被触发.mousemovemousedownmouseupclick似乎不能简单地告诉webbrowser跳过鼠标事件.
更糟糕的是,如果鼠标悬停事件更改了页面内容,则不会触发单击事件,如Safari Web内容指南 - 处理事件中所述,特别是单指事件中的图6.4 .究竟什么是"内容更改",取决于浏览器和版本.我发现对于iOS 7.0,背景颜色的变化不是(或不再是?)内容更改.
回顾一下:
touchstart和mouseenter.mouseleave,touchmove和click.请注意,没有任何操作touchend!
这显然适用于鼠标事件:mouseenter和mouseleave(稍微改进版本的mouseover和mouseout)被触发,并添加和删除悬停.
如果用户实际上click是链接,则也会删除悬停效果.这可确保在用户按下Web浏览器中的后退按钮时将其删除.
这也适用于触摸事件:在touchstart上添加了悬停效果.在touchend上没有被删除.它再次添加mouseenter,因为这不会导致内容更改(它已经添加),click事件也会被触发,并且跟踪链接而无需用户再次单击!
浏览器在touchstart事件之间延迟300ms 并且click实际上被充分利用,因为悬停效果将在这么短的时间内显示.
如果用户决定取消点击,则手指的移动将正常进行.通常,这是一个问题,因为没有mouseleave事件被触发,并且悬停效果仍然存在.值得庆幸的是,通过删除悬停效果可以很容易地解决这个问题touchmove.
而已!
请注意,可以删除300ms延迟,例如使用FastClick库,但这超出了此问题的范围.
我发现以下替代方案存在以下问题:
touchend:这将错误地跟随链接,即使用户只想滚动或缩放,而无意实际点击链接.touchend在后续鼠标事件中用作if条件,以防止在该时间点发生状态更改.该变量在click事件中重置.请参阅Walter Roman在此页面上的回答.如果您真的不希望在触摸界面上悬停效果,这是一个不错的解决方案.不幸的是,如果touchend由于其他原因而触发并且没有触发任何点击事件(例如用户滚动或缩放),并且随后尝试使用鼠标跟踪链接(即在具有鼠标和触摸界面的设备上),则此功能不起作用).mouseover或mousemove事件期间内容更改后不会触发其他事件.nnn*_*nnn 19
我在使用鼠标时如何获得悬停效果,但在使用触摸屏时抑制它们?
也许不要把它想象为抑制触摸屏的悬停效果,而是为鼠标事件添加悬停效果?
如果要:hover在CSS中保留效果,可以为不同的媒体指定不同的样式:
@media screen { /* hover styles here */ }
@media handheld { /* non-hover styles here */ }
Run Code Online (Sandbox Code Playgroud)
除了不幸的是,有很多移动设备忽略了这一点,只是使用屏幕规则.幸运的是,许多较新的移动/平板电脑浏览器确实支持一些更高级的媒体查询:
@media screen and (max-width:800px) { /* non-hover styles here */ }
Run Code Online (Sandbox Code Playgroud)
因此,即使忽略"屏幕"或"手持"部分,"max-width"也会为您提供帮助.您可以假设屏幕小于800像素的任何内容都必须是平板电脑或手机,而不是使用悬停效果.对于在低分辨率设备上使用鼠标的罕见用户,他们不会看到悬停效果,但您的网站会没有问题.
进一步阅读媒体查询?网上有很多关于这个的文章 - 这里有一篇:http://www.alistapart.com/articles/return-of-the-mobile-stylesheet
如果你将悬停效果从CSS中移出并用JavaScript应用它们,那么你可以专门绑定到鼠标事件,和/或你可能只是根据屏幕大小做出一些假设,最糟糕的"问题"是一些正在使用鼠标的用户错过了悬停效果.
我为最近的一个项目编写了以下JS,这是一个桌面/移动/平板电脑网站,其悬浮效果不应该出现在触摸上.
mobileNoHoverState下面的模块有一个变量preventMouseover(最初声明为false),设置为true当用户touchstart在元素上触发事件时,$target.
preventMouseover然后false在mouseover事件被触发时被设置回,这允许站点在用户同时使用他们的触摸屏和鼠标时按预期工作.
我们知道因为它们被声明的顺序而mouseover被触发.touchstartinit
var mobileNoHoverState = function() {
var hoverClass = 'hover',
$target = $(".foo"),
preventMouseover = false;
function forTouchstart() {
preventMouseover = true;
}
function forMouseover() {
if (preventMouseover === false) {
$(this).addClass(hoverClass);
} else {
preventMouseover = false;
}
}
function forMouseout() {
$(this).removeClass(hoverClass);
}
function init() {
$target.on({
touchstart : forTouchstart,
mouseover : forMouseover,
mouseout : forMouseout
});
}
return {
init: init
};
}();
Run Code Online (Sandbox Code Playgroud)
然后,该模块进一步实例化:
mobileNoHoverState.init();
Run Code Online (Sandbox Code Playgroud)
我的解决方案是将hover-active css类添加到HTML标记中,并在所有CSS选择器的开头使用它:hover并在第一个touchstart事件中删除该类.
http://codepen.io/Bnaya/pen/EoJlb
JS:
(function () {
'use strict';
if (!('addEventListener' in window)) {
return;
}
var htmlElement = document.querySelector('html');
function touchStart () {
document.querySelector('html').classList.remove('hover-active');
htmlElement.removeEventListener('touchstart', touchStart);
}
htmlElement.addEventListener('touchstart', touchStart);
}());
Run Code Online (Sandbox Code Playgroud)
HTML:
<html class="hover-active">
Run Code Online (Sandbox Code Playgroud)
CSS:
.hover-active .mybutton:hover {
box-shadow: 1px 1px 1px #000;
}
Run Code Online (Sandbox Code Playgroud)
我自己真的想要一个纯粹的css解决方案,因为在我的所有观点周围散布一个重量级的JavaScript解决方案似乎是一个令人不快的选择.最后找到@ media.hover查询,它可以检测"主输入机制是否允许用户将鼠标悬停在元素上".这避免了触摸设备,其中"悬停"更多地是模拟动作而不是输入设备的直接能力.
例如,如果我有一个链接:
<a href="/" class="link">Home</a>
Run Code Online (Sandbox Code Playgroud)
然后我可以安全地设置它的样式,只有:hover当设备轻松支持它时css:
@media (hover: hover) {
.link:hover { /* hover styles */ }
}
Run Code Online (Sandbox Code Playgroud)
虽然大多数现代浏览器都支持交互媒体功能查询,但某些流行的浏览器(如IE和Firefox)却不支持.在我的情况下,这很好用,因为我只打算在桌面上支持Chrome,在移动设备上支持Chrome和Safari.
小智 0
查看您的 CSS 可能会有所帮助,因为这听起来是一个相当奇怪的问题。但无论如何,如果它发生并且其他一切都很好,您可以尝试将悬停效果转移到 javascript(您也可以使用 jquery)。简单地说,绑定到 mouseover 或更好的 mouseenter 事件,并在事件触发时点亮您的元素。
在这里查看最后一个示例: http: //api.jquery.com/mouseover/,您可以使用类似的东西来记录事件触发时的情况并从那里获取它!