33

我已经构建了一个 webapp,为了稍微润色一下,我想添加 mousedown 和 mouseup 处理程序来交换图像(在这种情况下,使按钮看起来像是被按下了)。

我的代码是这样的:

window.onload = function() {
    //preload mouse down image here via Image()
    $("#button_img").mousedown(function(){$("#button_img").attr("src","button_on.png");});
    $("#button_img").mouseup(function(){$("#button_img").attr("src","button_off.png")});
}

这在桌面上运行得很好,但在移动设备上(在 iOS Safari 中测试),mousedown 和 mouseup 事件同时发生,所以实际上什么也没发生。

我尝试在 jQueryMobile 中使用 vmousedown 和 vmouseup 事件,但是这段代码:

//include jquerymobile.js and jquerymobile.css 
window.onload = function() {
    //preload mouse down image here via Image()
    $("#button_img").vmousedown(function(){$("#button_img").attr("src","button_on.png");});
    $("#button_img").vmouseup(function(){$("#button_img").attr("src","button_off.png")});
}

只是给了我 vmousedown 和 vmouseup 不存在的错误。此外,jQueryMobile 覆盖了我已经为页面编写的 CSS。

那么有没有办法让 vmousedown 和 vmouseup 工作,并且在没有 jQuery Mobile 的 CSS 的情况下做到这一点?

4

4 回答 4

73

您正在寻找touchstarttouchend。它们是那些试图模仿vmousedown的事件。vmouseup

这是一个例子:

window.onload = function() {
    //preload mouse down image here via Image()
    $("#button_img").bind('touchstart', function(){
        $("#button_img").attr("src","button_on.png");
    }).bind('touchend', function(){
        $("#button_img").attr("src","button_off.png");
    });
}

这在任何支持触摸事件的设备上都可以在没有任何框架的情况下工作。你可以使用Modernizr之类的东西来做这个测试,如果设备不支持触摸事件,绑定到常规桌面事件。

当您使用touchstart//您会得到一些有趣的信息touchendtouchmove例如一次发生了多少次触摸,因此您可以检测用户是否在滚动或尝试缩放。

更新

由于event事件处理程序中的对象对于触摸事件和鼠标事件是不同的,如果你想知道事件的坐标,你可以做这样的事情(下面的例子假设 Modernizr 已经加载):

//determine which events to use
var startEventType = 'mousedown',
    endEventType   = 'mouseup';

if (Modernizr.touch === true) {
    startEventType = 'touchstart';
    endEventType   = 'touchend';
}

//bind to determined event(s)
$("#button_img").bind(startEventType, function(event) {

    //determine where to look for pageX by the event type
    var pageX = (startEventType === 'mousedown')
                ? event.pageX
                : event.originalEvent.touches[0].pageX;

    ...
})...

更新

我正在查看这个,似乎您不需要在绑定事件处理程序之前检测事件类型:

//bind to determined event(s)
$("#button_img").bind('mousedown touchstart', function(event) {

    //determine where to look for pageX by the event type
    var pageX = (event.type.toLowerCase() === 'mousedown')
                ? event.pageX
                : event.originalEvent.touches[0].pageX;

    ...
})...

如果您担心快速连续接收这两个事件,您可以使用超时来限制事件处理程序:

//create timer
var timer = null;

//bind to determined event(s)
$("#button_img").bind('mousedown touchstart', function(event) {

    //clear timer
    clearTimeout(timer);

    //set timer
    timer = setTimeout(function () {

        //determine where to look for pageX by the event type
        var pageX = (event.type.toLowerCase() === 'mousedown')
                    ? event.pageX
                    : event.originalEvent.touches[0].pageX;

        ...

    }, 50);
})...

注意:您可以使用开发人员工具快速连续地强制mousedowntouchstart事件,但我不确定这里的真实用例。

于 2012-06-21T19:20:22.973 回答
6

您是否考虑过使用 CSS 来设置按钮的样式?当:active用户单击/触摸元素时将触发状态。这是一个例子:

/* Default state */
#button_img {
    background-image: url('button_off.png');
}

/* Clicked/touched state */
#button_img:active { 
    background-image: url('button_on.png');
}

CSS 的性能会更高,您还可以更好地分离关注点(显示与逻辑等)。

JSBin:http: //jsbin.com/beyin/1/

于 2014-07-07T23:31:43.113 回答
4

有一种方法可以获得 jQueryMobile 的vmouseupvmousedownvmousemovevclick等功能,而无需获得 jquerymobile 的所有其余部分(尤其是副作用)(即增强、额外的 css 等)

下载将仅包含一个 .js 文件(最小化和未压缩版本)。没有CSS。

在纯 jquery 之后将此脚本链接到 html 的头部,并像这样使用它:

<head>
  <script src="http://code.jquery.com/ui/1.10.4/jquery-ui.min.js"></script>
  <script src="whatever/path/jquery.mobile.custom.min.js"></script>
  <script>
    $(function(){ // or replace this with window.onload for that matter
      // Your code here, e.g.
      $("#button_img").on("vmousedown", function() { 
        /*whatever*/
      });
      // CAUTION: this won't work (see note below):
      // $("#button_img").vmousedown(function(){/*whatever*/}); // WON'T WORK
    });
  </script>
</head>

注意:方法.vmousedown(),.vmouseup()等将不起作用。您必须将事件侦听器与.on("vmousedown", ...). 不知道为什么:我猜这是因为创建与事件同名的快捷方法的 jquerymobile 部分位于其他模块中。也许可以找出它是哪个模块并将其包含在下载中,但我认为它会迫使您包含其他不需要的依赖项。

于 2014-07-02T20:52:46.977 回答
1

对触摸设备使用 touchstart 或 touchend。

大多数时候,您想要捕捉 touchstart 和 mousedown。您需要确保处理程序只触发一次。最简单的方法是同时捕获它们并调用 e.preventDefault()。

$("#button_img").on('touchstart mousedown', function(e) {
  //your code...

  e.preventDefault(); //prevents further events from being dispatched
}

来源:developer.mozilla.org

如果浏览器因为单个用户输入而同时触发触摸和鼠标事件,则浏览器必须在任何鼠标事件之前触发 touchstart。因此,如果应用程序不希望在特定触摸目标元素上触发鼠标事件,则该元素的触摸事件处理程序应调用 preventDefault() 并且不会调度其他鼠标事件。

于 2021-01-24T21:01:03.123 回答