如何使用适用于Android和iPhone的javascript检测长时间的触摸压力

How to detect a long touch pressure with javascript for android and iphone?

本文关键字:javascript 检测 触摸 压力 长时间 iPhone 何使用 适用于 Android      更新时间:2023-09-26

如何使用 android 和 iPhone 版 javascript 检测长触摸压力?原生JavaScript或jquery...

我想要听起来像:

<input type='button' onLongTouch='myFunc();' />

使用触控端检测长按的问题在于,如果您希望事件在一段时间后触发,它将不起作用。最好在触摸开始时使用计时器,并在触摸端清除事件计时器。可以使用以下模式:

var onlongtouch; 
var timer;
var touchduration = 500; //length of time we want the user to touch before we do something
touchstart() {
    timer = setTimeout(onlongtouch, touchduration); 
}
touchend() {
    //stops short touches from firing the event
    if (timer)
        clearTimeout(timer); // clearTimeout, not cleartimeout..
}
onlongtouch = function() { //do something };

这是 Joshua 答案的扩展版本,因为他的代码在用户不执行多点触控之前运行良好(您可以用两根手指点击屏幕,功能将被触发两次,4 根手指 - 4 次(。经过一些额外的测试场景后,我甚至触发了非常自由地触摸并在每次点击后接收执行的功能的可能性。

我添加了名为"lockTimer"的变量,该变量应该在用户触发"touchend"之前锁定任何其他触摸启动。

var onlongtouch; 
var timer;
var touchduration = 800; //length of time we want the user to touch before we do something
function touchstart(e) {
    e.preventDefault();
    if (!timer) {
        timer = setTimeout(onlongtouch, touchduration);
    }
}
function touchend() {
    //stops short touches from firing the event
    if (timer) {
        clearTimeout(timer);
        timer = null;
    }
}
onlongtouch = function() { 
    timer = null;
    document.getElementById('ping').innerText+='ping'n'; 
};
document.addEventListener("DOMContentLoaded", function(event) { 
    window.addEventListener("touchstart", touchstart, false);
    window.addEventListener("touchend", touchend, false);
});
<div id="ping"></div>

此处发布的解决方案忽略了用户需要触摸屏幕才能启动滚动的事实。我们只希望在用户不尝试滚动时才使用长按行为。

function onLongPress(element, callback) {
  let timer;
  element.addEventListener('touchstart', () => { 
    timer = setTimeout(() => {
      timer = null;
      callback();
    }, 500);
  });
  function cancel() {
    clearTimeout(timer);
  }
  element.addEventListener('touchend', cancel);
  element.addEventListener('touchmove', cancel);
}

然后:

onLongPress(element, () => {
  console.log('Long pressed', element);
});

我在我的安卓应用程序中是这样做到的:

  1. 已注册的事件侦听器:

    var touchStartTimeStamp = 0;
    var touchEndTimeStamp   = 0;
    window.addEventListener('touchstart', onTouchStart,false);
    window.addEventListener('touchend', onTouchEnd,false);
    
  2. 新增功能:

    var timer;
    function onTouchStart(e) {
        touchStartTimeStamp = e.timeStamp;
    }
    function onTouchEnd(e) {
        touchEndTimeStamp = e.timeStamp;
        console.log(touchEndTimeStamp - touchStartTimeStamp);// in miliseconds
    }
    
  3. 检查时差,做了我的东西

我希望这会有所帮助。

通过@djanowski处理触摸滚动来构建解决方案。 这也应该防止长按上下文菜单和选择。

function onLongPress(element, callback) {
    var timeoutId;
    element.addEventListener('touchstart', function(e) {
        timeoutId = setTimeout(function() {
            timeoutId = null;
            e.stopPropagation();
            callback(e.target);
        }, 500);
    });
    element.addEventListener('contextmenu', function(e) {
        e.preventDefault();
    });
    element.addEventListener('touchend', function () {
        if (timeoutId) clearTimeout(timeoutId);
    });
    element.addEventListener('touchmove', function () {
        if (timeoutId) clearTimeout(timeoutId);
    });
}
onLongPress(document.getElementById('kitty1'), function(element) {
    alert('Meow from ' + element.outerHTML );
});
onLongPress(document.getElementById('kitty2'), function(element) {
    alert('Meow from ' + element.outerHTML );
});
img {
  max-width: 100%;
  -webkit-user-select: none; /* Safari */
  -ms-user-select: none; /* IE 10 and IE 11 */
  user-select: none; /* Standard syntax */
}
<p>Long press on kitty!  Kitty should meow on 500ms long press but not scroll</p>
<img id="kitty1" src="http://placekitten.com/300/400" />
<img id="kitty2" src="http://placekitten.com/300/300" />

我们可以计算触摸开始和触摸结束时的时间差。如果计算的时间差超过触摸持续时间,那么我们使用函数名称taphold。

var touchduration = 300; 
var timerInterval;
function timer(interval) {
    interval--;
    if (interval >= 0) {
        timerInterval = setTimeout(function() {
                            timer(interval);
                        });
    } else {
        taphold();
    }
}
function touchstart() {
    timer(touchduration);
}
function touchend() {
    clearTimeout(timerInterval);
}
function taphold(){
    alert("taphold");
}

document.getElementById("xyz").addEventListener('touchstart',touchstart);
document.getElementById("xyz").addEventListener('touchend',touchend);

对于跨平台开发人员:

鼠标向上/向下似乎在安卓上工作正常 - 但并非所有设备,即(三星标签4(。在iOS上根本不起作用。

进一步的研究似乎是由于元素具有选择和原生放大

倍率打断了听众。

如果用户持有缩略图 500 毫秒,则此事件侦听器允许在引导模式中打开缩略图图像。

它使用响应式图像类,因此显示图像的较大版本。这段代码已经过全面测试(iPad/Tab4/TabA/Galaxy4(:

var pressTimer;  
$(".thumbnail").on('touchend', function (e) {
   clearTimeout(pressTimer);
}).on('touchstart', function (e) {
   var target = $(e.currentTarget);
   var imagePath = target.find('img').attr('src');
   var title = target.find('.myCaption:visible').first().text();
   $('#dds-modal-title').text(title);
   $('#dds-modal-img').attr('src', imagePath);
   // Set timeout
   pressTimer = window.setTimeout(function () {
      $('#dds-modal').modal('show');
   }, 500)
});

这个基于@Joshua的更好的解决方案,有时需要直接在事件中调用代码(某些Web API需要用户安装才能触发某些内容( 在这种情况下,您可以使用此修改:

var longtouch;
var timer;
//length of time we want the user to touch before we do something
var touchduration = 500;
function touchstart() {
    longtouch = false;
    timer = setTimeout(function() {
       longtouch = true;
       timer = null
    }, touchduration);
}
function touchend() {
    if (timer) {
        clearTimeout(timer);
        timer = null;
    }
    if (longtouch) {
        // your long acction inside event
        longtouch = false;
    }
}

在 setTimeout 中,您将标志设置为 true,在 touchend 中,检查它是否已设置。

这适用于我的用例,即想要在触摸屏幕时执行某些功能。

let triggerInterval = 200; // in milliseconds
let timerId;
function touchstart(e) {
  // e.preventDefault();
  timerId = setInterval(yourFunction, triggerInterval);
}
function touchend(e) {
  clearInterval(timerId);
}
function yourFunction() {
  //   perform your logic
}
document.addEventListener("touchstart", touchstart);
document.addEventListener("touchend", touchend);

注意:- 触发器间隔中的较小值将更快地执行您的函数((。

完成程序后,您可以删除相应的事件侦听器:

document.removeEventListener("touchstart", touchstart);
document.removeEventListener("touchend", touchend);

在所有浏览器中工作的长按事件

(function (a) {
        function n(b) { a.each("touchstart touchmove touchend touchcancel".split(/ /), function (d, e) { b.addEventListener(e, function () { a(b).trigger(e) }, false) }); return a(b) } function j(b) { function d() { a(e).data(h, true); b.type = f; jQuery.event.handle.apply(e, o) } if (!a(this).data(g)) { var e = this, o = arguments; a(this).data(h, false).data(g, setTimeout(d, a(this).data(i) || a.longclick.duration)) } } function k() { a(this).data(g, clearTimeout(a(this).data(g)) || null) } function l(b) {
            if (a(this).data(h)) return b.stopImmediatePropagation() ||
            false
        } var p = a.fn.click; a.fn.click = function (b, d) { if (!d) return p.apply(this, arguments); return a(this).data(i, b || null).bind(f, d) }; a.fn.longclick = function () { var b = [].splice.call(arguments, 0), d = b.pop(); b = b.pop(); var e = a(this).data(i, b || null); return d ? e.click(b, d) : e.trigger(f) }; a.longclick = { duration: 500 }; a.event.special.longclick = {
            setup: function () {
                /iphone|ipad|ipod/i.test(navigator.userAgent) ? n(this).bind(q, j).bind([r, s, t].join(" "), k).bind(m, l).css({ WebkitUserSelect: "none" }) : a(this).bind(u, j).bind([v,
                w, x, y].join(" "), k).bind(m, l)
            }, teardown: function () { a(this).unbind(c) }
        }; var f = "longclick", c = "." + f, u = "mousedown" + c, m = "click" + c, v = "mousemove" + c, w = "mouseup" + c, x = "mouseout" + c, y = "contextmenu" + c, q = "touchstart" + c, r = "touchend" + c, s = "touchmove" + c, t = "touchcancel" + c, i = "duration" + c, g = "timer" + c, h = "fired" + c
    })(jQuery);

绑定具有时间间隔的长点击事件

 $('element').longclick(250, longClickHandler);

在触摸设备上长按功能下火

function longClickHandler() {
    alter('Long tap Fired');
}