Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/88.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jquery iPad/iPhone悬停问题导致用户双击链接_Jquery_Ipad_Hover_Mouseover - Fatal编程技术网

Jquery iPad/iPhone悬停问题导致用户双击链接

Jquery iPad/iPhone悬停问题导致用户双击链接,jquery,ipad,hover,mouseover,Jquery,Ipad,Hover,Mouseover,我有一些我很久以前建立的网站,使用jquery鼠标事件…我刚买了一台ipad,我注意到所有鼠标覆盖的事件都转换为点击次数…例如,我必须点击两次而不是一次…(第一次悬停,而不是实际点击) 是否有解决此问题的变通方法?也许我应该用jquery命令代替mouseover/out等。。 谢谢 您可以像这样检查navigator.userAgent: if(!navigator.userAgent.match(/iPhone/i) || !navigator.userAgent.match(/iPad/i

我有一些我很久以前建立的网站,使用jquery鼠标事件…我刚买了一台ipad,我注意到所有鼠标覆盖的事件都转换为点击次数…例如,我必须点击两次而不是一次…(第一次悬停,而不是实际点击)

是否有解决此问题的变通方法?也许我应该用jquery命令代替mouseover/out等。。
谢谢

您可以像这样检查
navigator.userAgent

if(!navigator.userAgent.match(/iPhone/i) || !navigator.userAgent.match(/iPad/i)) {
    //bind your mouseovers...
}
$("body").on("mouseover", function() {
       document.getElementsByTagName("my-class")[0].style.display = 'block'; //show element
       document.querySelector(".my-selector div").style.display = 'none'; // hide element
});
但你必须检查黑莓、机器人和无数其他触摸屏设备。仅当userAgent包含Mozilla、IE、Webkit或Opera时,您还可以绑定鼠标盖,但您仍然需要筛选某些设备,因为Droid(例如)将其userAgent字符串报告为:

Mozilla/5.0 (Linux; U; Android 2.0.1; en-us; Droid Build/ESD56) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17

iPhone的字符串类似。如果你只在屏幕上显示iPhone、iPod、iPad、Android和Blackberry,你可能会看到大部分的手持设备,但不是所有的。

我认为尝试使用
mouseenter
代替
mouseover
是明智的选择。它是绑定到
时内部使用的。hover(fn,fn)
通常是您想要的。

我“认为”您的链接没有onmouseover事件,点击一次激活onmouseover,双击激活链接。但是idk。我没有iPad。 我想你应该使用手势/触摸事件


尚未对此进行全面测试,但由于iOS触发触摸事件,假设您处于jQuery设置中,这可能会起作用

$('a').on('click touchend', function(e) {
    var el = $(this);
    var link = el.attr('href');
    window.location = link;
});

其想法是,Mobile WebKit在点击结束时触发一个
touchend
事件,因此我们监听该事件,然后在链接上触发
touchend
事件后立即重定向浏览器。

我也有同样的问题,但不是在触摸设备上。每次单击时都会触发该事件。关于事件队列之类的东西

然而,我的解决方案是这样的: 单击事件(或触摸?)可设置计时器。如果在X毫秒内再次单击链接,则返回false

要设置每元素计时器,可以使用
$.data()


这也可能解决上述@Ferdy问题。

看来毕竟有一个CSS解决方案。Safari等待第二次触摸的原因是:hover事件中通常指定的背景图像(或元素)。如果没有显示-你不会有任何问题。解决方案是使用辅助CSS文件(或JS方法中的样式)以iOS平台为目标,该文件覆盖:hover background以继承,例如,并隐藏您将在鼠标上显示的元素:

下面是一个CSS和HTML示例-鼠标上方带有星号标签的产品块:

HTML:

解决方案(辅助CSS):


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");
        }
    );
}

*出于说明目的而减少的代码

如果您使用Modernizr,则如前所述,使用Modernizr.touch非常容易

不过,为了安全起见,我更喜欢结合使用Modernizr.touch和用户代理测试

var deviceAgent = navigator.userAgent.toLowerCase();

var isTouchDevice = Modernizr.touch || 
(deviceAgent.match(/(iphone|ipod|ipad)/) ||
deviceAgent.match(/(android)/)  || 
deviceAgent.match(/(iemobile)/) || 
deviceAgent.match(/iphone/i) || 
deviceAgent.match(/ipad/i) || 
deviceAgent.match(/ipod/i) || 
deviceAgent.match(/blackberry/i) || 
deviceAgent.match(/bada/i));

function Tipsy(element, options) {
    this.$element = $(element);
    this.options = options;
    this.enabled = !isTouchDevice;
    this.fixTitle();
};
如果不使用Modernizer,只需将上面的
Modernizer.touch
功能替换为
(“document.documentElement”中的“ontouchstart”)


另外请注意,测试用户代理iemobile将为您提供比Windows Phone更广泛的检测到的Microsoft移动设备。

对我有效的是这里的其他人已经说过的:

不要在hover或mousemove上显示/隐藏元素(在我的例子中就是这样)

以下是苹果公司的说法():

可单击元素是一个链接、表单元素、图像映射区域或具有mousemove、mousedown、mouseup或onclick处理程序的任何其他元素

如果用户点击一个可点击的元素,事件按如下顺序到达:mouseover、mousemove、mousedown、mouseup和click。另外,如果页面内容在mousemove事件中发生更改,则不会发送序列中的后续事件。此行为允许用户点击新内容

因此,您可以使用@woop的解决方案:检测userAgent,检查它是否与iOS设备兼容,然后绑定事件。我最终使用了这种技术,因为它适合我的需要,而且在不需要的时候不绑定悬停事件更有意义

但是。。。如果您不想搞乱UserAgent,仍然在hover/mousemove上隐藏/显示元素,我发现您可以使用本机javascript来实现这一点,如下所示:

if(!navigator.userAgent.match(/iPhone/i) || !navigator.userAgent.match(/iPad/i)) {
    //bind your mouseovers...
}
$("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();
    }
});

您可以使用
单击touchend

例如:

$('a').on('click touchend', function() {
    var linkToAffect = $(this);
    var linkToAffectHref = linkToAffect.attr('href');
    window.location = linkToAffectHref;
});
上述示例将影响触摸设备上的所有链接

如果只针对特定链接,可以通过在其上设置类来实现,即:

HTML:

$('a.prevent-extra-click').on('click touchend', function() {
    var linkToAffect = $(this);
    var linkToAffectHref = linkToAffect.attr('href');
    window.location = linkToAffectHref;
});

Jquery:

$('a.prevent-extra-click').on('click touchend', function() {
    var linkToAffect = $(this);
    var linkToAffectHref = linkToAffect.attr('href');
    window.location = linkToAffectHref;
});
干杯


Jeroen

你的问题并不完全清楚,但如果你只是想消除双击,同时保留鼠标的悬停效果,我的建议是:

  • touchstart
    mouseenter
    上添加悬停效果
  • 鼠标移动
    触摸移动
    单击
    上移除悬停效果
背景 为了模拟鼠标,如果用户在触摸屏(如iPad)上触摸并释放手指,Webkit mobile等浏览器会触发以下事件(来源:html5rocks.com):

  • touchstart
  • touchmove
  • touchend
  • 300毫秒延迟,浏览器确保这是一次点击,而不是两次点击
  • mouseov
    
    // mouseenter event
    $('.element').on( "mouseenter", function() {
        // insert mouseenter events below
    
        // double click fix for iOS and mouseenter events
        if ($.browser.iphone || $.browser.ipad) $(this).trigger('click');
    });
    // mouseleave event
    $('.element').on( "mouseleave", function() { 
        // insert mouseout events below
    });
    // onclick event
    $('.element').on( "click", function() {
        // insert click events below
    });
    
    $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);
    
    // tablet "one touch (click)" X "hover" > link redirection
    $('a').on('touchmove touchend', function(e) {
    
        // if touchmove>touchend, set the data() for this element to true. then leave touchmove & let touchend fail(data=true) redirection
        if (e.type == 'touchmove') {
            $.data(this, "touchmove_cancel_redirection", true );
            return;
        }
    
        // if it's a simple touchend, data() for this element doesn't exist.
        if (e.type == 'touchend' && !$.data(this, "touchmove_cancel_redirection")) {
            var el = $(this);
            var link = el.attr('href');
            window.location = link;
        }
    
        // if touchmove>touchend, to be redirected on a future simple touchend for this element
        $.data(this, "touchmove_cancel_redirection", false );
    });
    
        $('a').not('nav.navbar a').on("tap", function () {
            var link = $(this).attr('href');
            if (typeof link !== 'undefined') {
                window.location = link;
            }
        });
    
    <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();
    });
    
        $('body').on('touchstart','*',function(){   //listen to touch
            var jQueryElement=$(this);  
            var element = jQueryElement.get(0); // find tapped HTML element
            if(!element.click){
                var eventObj = document.createEvent('MouseEvents');
                eventObj.initEvent('click',true,true);
                element.dispatchEvent(eventObj);
            }
        });
    
    @media screen and (min-device-width:1024px) {
        your-element:hover {
            /* Do whatever here */
        }
    }
    
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
    
      $('a').on('touchstart', function() {
        $(this).trigger('click');
      });
    
    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(){});
        }
    }
    
    var selector = "label, a, button";
    var timer;
    var startX;
    var startY;
    $(document).on("click", selector, function (e) {
        if ($(this).data("touched") === true) {
            e.stopImmediatePropagation();
            return false;
        }
        return;
    }).on("touchend", selector, function (e) {
        if (Math.abs(startX - e.originalEvent.changedTouches[0].screenX) > 10 || Math.abs(startY - e.originalEvent.changedTouches[0].screenY) > 10)
            // user action is not a tap
            return;
        var $this = $(this);
        // Visit: http://stackoverflow.com/questions/1694595/can-i-call-jquery-click-to-follow-an-a-link-if-i-havent-bound-an-event-hand/12801548#12801548
        this.click();
        // prevents double click
        $this.data("touched", true);
        if (timer)
            clearTimeout(timer);
        setTimeout(function () {
            $this.data("touched", false);
        }, 400);
        e.stopImmediatePropagation();
        return false;
    }).on("touchstart", function (e) {
        startX = e.originalEvent.changedTouches[0].screenX;
        startY = e.originalEvent.changedTouches[0].screenY;
    });
    
    $('a').on('touchend', function() {
        $(this).click();
    });
    
    if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
          $('.ui-autocomplete').off('menufocus hover mouseover');
    }
    
    @media (pointer: fine) {
      a span {
        display: none;
      }
      a:hover span {
        display: inline-block;
      }
    }