我有一个悬停功能,如果它是一个触摸设备,我希望悬停事件不会发生。问题是当您点击带有触摸设备的链接时,它会在执行点击事件之前执行悬停事件,因此您必须点按两次才能使其正常工作。
这是悬停功能:
$("#close").hover(
function () {
$("#close_2").css({
display: "none"
});
$("#close_1").css({
display: "block"
});
},
function () {
$("#close_1").css({
display: "none"
});
$("#close_2").css({
display: "block"
});;
}
);
然后我将此设置为点击功能:
$('#close').click(function() {
var id = $(this).attr('id');
$('#full_image').animate({
height: 0
}, 300, function() {
$('#full_image img').attr('src','#');
});
$("#close_1").css({
display: "none"
});
$("#close_2").css({
display: "none"
});
$("#close").css({
display: "none"
});
});
答案 0 :(得分:13)
使.hover()方法更明确,并将其与.on()结合使用:
var $close1 = $('#close_1'),
$close2 = $('#close_2');
$('#close').on({
mouseenter: function(){
$close2.css({display:'none'});
$close1.css({display:'block'});
},
mouseleave: function(){
$close1.css({display:'none'});
$close2.css({display:'block'});
}
});
然后将其与.off()结合起来。
$('#close').on('touchstart',function(){
$(this).off('mouseenter,mouseleave');
});
如果您希望在点击触摸设备时触发事件,但悬停在桌面设备上,则将这些功能分别作为您在这些操作中调用的单独功能。
修改强>
我做了这个答案已经有一段时间了,这是一个更好的方法:
$(function(){
var isTouchDevice = ('ontouchstart' in window || 'onmsgesturechange' in window),
$close = $('#close'),
$close1 = $('#close_1'),
$close2 = $('#close_2');
if(!isTouchDevice){
$close.on({
mouseenter: function(){
$close2.hide();
$close1.show();
},
mouseleave: function(){
$close1.hide();
$close2.show();
}
});
}
$close.on('click',function(){
$('#full_image').animate({height:0},300,function(){
$(this).find('img').attr('src','#');
});
$close.hide();
$close1.hide();
$close2.hide();
});
});
这不需要每次触摸都会触发“悬停预防”事件,基本上会在页面加载时设置功能,同时不会影响点击事件。
答案 1 :(得分:5)
我认为一个明确的方法是:
如果你已经使用了Modernizr这样的东西:
if(!Modernizr.touch){
// only if the browser doesn't support touch events,
// add the hover handler here.
}
//add the click handler here, as you want it bound no matter what
有关检测触控功能的其他选项,请参阅What's the best way to detect a 'touch screen' device using JavaScript?和What's the best way to detect a 'touch screen' device using JavaScript?。
答案 2 :(得分:2)
在移动端,在 touchstart 事件中调用 preventDefault 会阻止鼠标悬停, mouseenter , mousedown 和附属活动。细节:https://patrickhlauke.github.io/touch/tests/results/
$('#close').on('touchstart',function(e){
console.log('touchstart');
e.preventDefault();
//Do touch stuff
});
答案 3 :(得分:1)
由于Windows 8和Ultrabooks,我希望看到很多设备同时支持触摸和指针事件。因此,我避免完全禁用悬停事件,因为它可能会使用鼠标破坏启用触摸的用户的站点。
为了解决这个问题,我最终使用两个不同的类来显示菜单.hover
和.touch
,以及单独的悬停和点击事件。
我正在使用jquery.finger来捕获点击事件,虽然任何插件都可以使用,但这只是最小的插件。
HTML类似于:
<li>
<a>Some Link</a>
<div>Some Content</div>
</li>
CSS类似于:
li div {display:none;}
li.hover div, li.touch div {display:block;}
使用JQuery的Javascript:
// Caching whatever elements I'm using for the navigation
a = $("a");
li = $("li");
// Set hover events
li.hover(
// Both hover in and out fire whenever the user taps, aggravating!
function(e) {
// Close unused menus
li.not(this).removeClass("hover").removeClass("touch");
// Show this menu
$(this).addClass( "hover" );
}, function(e) {
// Only closes if the menu doesn't have .touch, hell yeah!
li.removeClass("hover");
}
);
// Set the tap event
a.on('tap',function(e,data){
e.stopPropagation();
var thisParent = $(this.parentNode);
// Close unused menus
li.not(thisParent).removeClass("touch");
// Toggle the current menu
thisParent.toggleClass("touch");
// The menu is open, so we don't need this class anymore
li.removeClass("hover");
});
// Prevent the list items when being tapped from closing the drop down
li.on('tap',function(e){e.stopPropagation();});
// Close drop downs when tapping outside the menus
$(document).on('tap',function(e){
li.removeClass("touch");
});
这里重要的一点就是我如何根据事件添加单独的.hover
或.touch
类,以及删除未使用的类。订单很重要,因此菜单不会闪烁。
答案 4 :(得分:-5)
最终使用了触摸检测:
var deviceAgent = navigator.userAgent.toLowerCase();
var agentID = deviceAgent.match(/(iphone|ipod|ipad)/);
if(agentID) {
$('#close').click(function() {
var id = $(this).attr('id');
$('#full_image').animate({
height: 0
}, 300, function() {
$('#full_image img').attr('src','#');
});
$("#close_1").css({
display: "none"
});
$("#close_2").css({
display: "none"
});
$("#close").css({
display: "none"
});
});
}
else {
$('#close').hover(
function() {
$("#close_2").css({
display: "none"
});
$("#close_1").css({
display: "block"
});
}, function() {
$("#close_1").css({
display: "none"
});
$("#close_2").css({
display: "block"
});
}
);
$('#close').click(function() {
var id = $(this).attr('id');
$('#full_image').animate({
height: 0
}, 300, function() {
$('#full_image img').attr('src','#');
});
$("#close_1").css({
display: "none"
});
$("#close_2").css({
display: "none"
});
$("#close").css({
display: "none"
});
});
}