是否有一种解决方法可以解决这个问题?也许有一个我应该使用而不是mouseover/out等的jquery命令.. 谢谢!
我没有完全测试过这个方法,但是由于iOS会触发touch事件,所以这个方法可能可行,假设你正在使用jQuery。
$('a').on('click touchend', function(e) {
var el = $(this);
var link = el.attr('href');
window.location = link;
});
Mobile WebKit在轻击结束时会触发touchend
事件,我们监听该事件,一旦链接被触发了touchend
事件,就立即将浏览器重定向。
target="_blank"
属性的链接,它会在当前窗口和新窗口中同时打开。 - rybo111虽然不是很清楚您的问题,但如果您只是想在保留鼠标悬停效果的同时消除双击,我的建议是:
touchstart
和 mouseenter
上添加悬停效果。mouseleave
、touchmove
和 click
上移除悬停效果。为了模拟鼠标,像 Webkit 移动端这样的浏览器会在用户触摸并释放触摸屏幕(例如 iPad)时触发以下事件(来源:Touch And Mouse on html5rocks.com):
touchstart
touchmove
touchend
mouseover
mouseenter
mouseover
、mouseenter
或 mousemove
事件更改页面内容,则不会触发以下事件。mousemove
mousedown
mouseup
click
似乎没有办法简单地告诉网页浏览器跳过鼠标事件。
更糟糕的是,如果鼠标悬停事件改变了页面内容,那么点击事件就永远不会被触发。具体来说,请参见Safari Web内容指南-处理事件中的第6.4图,特别是“单指事件”。什么是“内容更改”将取决于浏览器和版本。 我发现,对于iOS 7.0,背景颜色的更改不是(或不再是)内容更改。mouseleave
事件,而悬停效果仍然存在。幸运的是,可以通过在touchmove
上删除悬停效果来轻松解决这个问题。touchend
中模拟点击事件:即使用户只想滚动或缩放,而没有真正点击链接的意图,也会错误地跟随链接。
- 使用变量抑制鼠标事件:在touchend
中设置一个变量,该变量用作后续鼠标事件的if条件,在此时防止状态更改。单击事件会重置该变量。如果您确实不希望在触摸界面上出现悬停效果,则这是一个不错的解决方案。不幸的是,如果由于其他原因触发了touchend
并且没有触发单击事件(例如用户滚动或缩放),然后尝试在鼠标上(即在具有鼠标和触摸界面的设备上)跟随链接,这就无法正常工作。mouseover
或mousemove
事件期间进行内容更改后不会触发更多事件。看起来还是有CSS解决方案的。Safari等待第二次触摸的原因是由于通常在:hover事件上分配的背景图片(或元素)。如果没有要显示的内容,那么你就不会有任何问题。 解决方法是使用辅助CSS文件(或JS方法中的样式)针对iOS平台进行定位,覆盖:hover背景为inherit等,并保持隐藏你要在鼠标悬停时显示的元素:
这里是一个CSS和HTML示例-带有鼠标悬停星标标签的产品块:
HTML:
<a href="#" class="s"><span class="s-star"></span>Some text here</a>
CSS:
.s {
background: url(some-image.png) no-repeat 0 0;
}
.s:hover {
background: url(some-image-r.png) no-repeat 0 0;
}
.s-star {
background: url(star.png) no-repeat 0 0;
height: 56px;
position: absolute;
width: 72px;
display:none;
}
.s:hover .s-star {
display:block;
}
解决方案(次要的CSS):
/* CSS */
/* Keep hovers the same or hidden */
.s:hover {
background:inherit;
}
.s:hover .s-star {
display:none;
}
不需要过于复杂。
$('a').on('touchend', function() {
$(this).click();
});
不要在hover或mousemove(在我的情况下)上显示/隐藏元素。
可点击的元素包括链接、表单元素、图像映射区域以及任何带有mousemove、mousedown、mouseup或onclick处理程序的元素;
如果用户点击可点击的元素,则事件按此顺序发生:mouseover、mousemove、mousedown、mouseup和click。 另外,如果页面的内容在mousemove事件上更改,则不会发送序列中的后续事件。 此行为允许用户在新内容中轻击。
因此,您可以使用@woop的解决方案:检测userAgent,检查它是否是iOS设备,然后绑定事件。 我最终使用了这种技术,因为它符合我的需求,并且当您不想绑定hover事件时,它更加合理。
但是... 如果您不想混合userAgents,而仍然想在hover/mousemove上隐藏/显示元素,我发现您可以使用本机javascript来实现,如下所示:
$("body").on("mouseover", function() {
document.getElementsByTagName("my-class")[0].style.display = 'block'; //show element
document.querySelector(".my-selector div").style.display = 'none'; // hide element
});
这将适用于桌面版本,并在移动版本上不起作用。
为了更好的兼容性...
$("body").on("mouseover", function() {
if (document.getElementsByTagName && document.querySelector) { // check compatibility
document.getElementsByTagName("my-class")[0].style.display = 'block'; //show element
document.querySelector(".my-selector div").style.display = 'none'; // hide element
} else {
$(".my-class").show();
$(".my-selector div").hide();
}
});
我认为用mouseenter
替换mouseover
是明智的选择。在绑定到.hover(fn,fn)
时,它是内部使用的,并且通常是您想要的。
cduruk的解决方案非常有效,但在我的网站某些部分引起了问题。因为我已经在使用jQuery来添加CSS hover类,最简单的解决方案是在移动设备上不添加CSS hover类(或更准确地说,在非移动设备上才添加)。
以下是基本思路:
var device = navigator.userAgent.toLowerCase();
var ios = device.match(/(iphone|ipod|ipad)/);
if (!(ios)) {
$(".portfolio-style").hover(
function(){
$(this).stop().animate({opacity: 1}, 100);
$(this).addClass("portfolio-red-text");
},
function(){
$(this).stop().animate({opacity: 0.85}, 100);
$(this).removeClass("portfolio-red-text");
}
);
}
*该示例代码仅供说明
touchstart
上的位置视为 mouseover
,并在下一个 touchstart
上进行 mouseout
。因此,在 Android 中查看鼠标悬停内容的一种方法是触摸感兴趣的区域并晃动手指,稍微滚动页面。将 touchmove
视为 mouseout
会破坏这个功能。理论上,您可以通过 touchmove
添加标志,但 iPhones 即使没有移动也会触发 touchmove。理论上,您可以仅比较 touchstart
和 touchend
事件的 pageX
和 pageY
,但在 iPhones 上,没有 touchend
pageX
或 pageY
。
因此,不幸的是,为了覆盖所有情况,它最终变得有点复杂。
$el.on('touchstart', function(e){
$el.data('tstartE', e);
if(event.originalEvent.targetTouches){
// store values, not reference, since touch obj will change
var touch = e.originalEvent.targetTouches[0];
$el.data('tstartT',{ clientX: touch.clientX, clientY: touch.clientY } );
}
});
$el.on('touchmove', function(e){
if(event.originalEvent.targetTouches){
$el.data('tstartM', event.originalEvent.targetTouches[0]);
}
});
$el.on('click touchend', function(e){
var oldE = $el.data('tstartE');
if( oldE && oldE.timeStamp + 1000 < e.timeStamp ) {
$el.data('tstartE',false);
return;
}
if( $el.data('iosTouchM') && $el.data('tstartT') ){
var start = $el.data('tstartT'), end = $el.data('tstartM');
if( start.clientX != end.clientX || start.clientY != end.clientY ){
$el.data('tstartT', false);
$el.data('tstartM', false);
$el.data('tstartE',false);
return;
}
}
$el.data('tstartE',false);
MacFreak的回答对我非常有帮助。以下是一些实际操作代码,希望能对您有所帮助。
问题 - 应用 touchend 意味着每次您用手指滚动元素时,它都会响应,即使您只是试图向下滚动。
我正在使用jQuery创建一种效果,通过淡入一个按钮下方的线条来“突出显示”悬停的按钮。我不希望这意味着您在触摸设备上必须按两次按钮才能跟随链接。
这些是按钮:
<a class="menu_button" href="#">
<div class="menu_underline"></div>
</a>
//Mouse Enter
$('.menu_button').bind('touchstart mouseenter', function(){
$(this).find(".menu_underline").fadeIn();
});
//Mouse Out
$('.menu_button').bind('mouseleave touchmove click', function(){
$(this).find(".menu_underline").fadeOut();
});
我刚刚发现,如果添加一个空的监听器,它就可以工作了。不要问我为什么,但我在iOS 9.3.2的iPhone和iPad上进行了测试,它可以正常工作。
if(/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream){
var elements = document.getElementsByTagName('a');
for(var i = 0; i < elements.length; i++){
elements[i].addEventListener('touchend',function(){});
}
}