最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to make ondblclick event works on phone? - Stack Overflow

programmeradmin5浏览0评论

I want to achieve the double click event on a specific div like this:

<div   id="divID" ondblclick = 'alert("double click!!");' >

it worked on the google chrome browser but when I open it with phone it didn't work, by the way the single click worked.

ps: i added this two things

<meta name="viewport" content="width=device-width, initial scale=1,user-scalable=no">

and this

body {
-ms-touch-action: manipulation;
touch-action: manipulation;}

but it didnt work!

I want to achieve the double click event on a specific div like this:

<div   id="divID" ondblclick = 'alert("double click!!");' >

it worked on the google chrome browser but when I open it with phone it didn't work, by the way the single click worked.

ps: i added this two things

<meta name="viewport" content="width=device-width, initial scale=1,user-scalable=no">

and this

body {
-ms-touch-action: manipulation;
touch-action: manipulation;}

but it didnt work!

Share Improve this question edited Mar 9, 2015 at 12:11 hrskrs 4,4805 gold badges39 silver badges52 bronze badges asked Mar 9, 2015 at 11:17 Wissem AchourWissem Achour 1971 gold badge3 silver badges14 bronze badges
Add a comment  | 

7 Answers 7

Reset to default 5

I got the same issue. On touch devices, if you want to detect a double-tap gesture and you use the ondblclick event in most cases it will not work and also the problem is it will also fire an onclick. One of the solution is to implement a double tap detection pattern using the following code sample:

var doubletapDeltaTime_ = 700;
var doubletap1Function_ = null;
var doubletap2Function_ = null;
var doubletapTimer = null;

function tap(singleTapFunc, doubleTapFunc) {
    if (doubletapTimer==null) {
    // First tap, we wait X ms to the second tap
        doubletapTimer_ = setTimeout(doubletapTimeout_, doubletapDeltaTime_);
        doubletap1Function_ = singleTapFunc;
        doubletap2Function_ = doubleTapFunc;
    } else {
    // Second tap
        clearTimeout(doubletapTimer);
        doubletapTimer_ = null;
        doubletap2Function_();
    }
}

function doubletapTimeout() {
// Wait for second tap timeout
    doubletap1Function_();
    doubleTapTimer_ = null;
}

And you can call it like

<div   id="divID" onclick="tap(tapOnce, tapTwice)" >

tapOnce and tapTwice are your functions which will be called in respective cases. This solution will work on browsers too.

Reference

Here is the external function 'doubletap' which can be helpful:

/*
 * jQuery Double Tap
 * Developer: Sergey Margaritov ([email protected])
 * Date: 22.10.2013
 * Based on jquery documentation http://learn.jquery.com/events/event-extensions/
 */

(function($){

  $.event.special.doubletap = {
    bindType: 'touchend',
    delegateType: 'touchend',

    handle: function(event) {
      var handleObj   = event.handleObj,
          targetData  = jQuery.data(event.target),
          now         = new Date().getTime(),
          delta       = targetData.lastTouch ? now - targetData.lastTouch : 0,
          delay       = delay == null ? 300 : delay;

      if (delta < delay && delta > 30) {
        targetData.lastTouch = null;
        event.type = handleObj.origType;
        ['clientX', 'clientY', 'pageX', 'pageY'].forEach(function(property) {
          event[property] = event.originalEvent.changedTouches[0][property];
        })

        // let jQuery handle the triggering of "doubletap" event handlers
        handleObj.handler.apply(this, arguments);
      } else {
        targetData.lastTouch = now;
      }
    }
  };

})(jQuery);

Load jQuery Mobile into your project and try using taphold or some of the other mobile specific touch events that are available to you through that API.

Here's the jQuery Mobile documentation with all the events you can use: http://api.jquerymobile.com/category/events/

Here is the snippet for TS React users. Pass in the click event, so that double click is only invoked if the same element is clicked twice

import React from "react";

type CallBack = () => any;
type TapParams = { onSingleTap?: CallBack; onDoubleTap?: CallBack };

var DELTA_TIME_THRESHOLD_MS = 700;
var timer: NodeJS.Timeout | null = null;
var target: EventTarget;

export function tap(
  e: React.MouseEvent,
  { onSingleTap, onDoubleTap }: TapParams
) {

  if (timer == null) {
    // First tap
    onSingleTap?.();

    timer = setTimeout(() => {
      timer = null;
    }, DELTA_TIME_THRESHOLD_MS);
  } else {
    // Second tap
    if (e.target === target) {
      onDoubleTap?.();
    }

    clearTimeout(timer);
    timer = null;
  }
  target = e.target;
}

Usage

<div
  onClick={(e) => tap(e, { onSingleTap, onDoubleTap })}
>Tap or doubletap</div>

Using only JavaScript

You can use "touchstart" event for a single touch,
but with calculating the time when he should click again

I used 400 (0.4s) as it's the longer duration between two touches
It's only an estimate, but it's still a reasonable time

let expired

let doubleClick = function () {
    console.log('double click')
}

let doubleTouch = function (e) {
    if (e.touches.length === 1) {
        if (!expired) {
            expired = e.timeStamp + 400
        } else if (e.timeStamp <= expired) {
            // remove the default of this event ( Zoom )
            e.preventDefault()
            doubleClick()
            // then reset the variable for other "double Touches" event
            expired = null
        } else {
            // if the second touch was expired, make it as it's the first
            expired = e.timeStamp + 400
        }
    }
}

let element = document.getElementById('btn')
element.addEventListener('touchstart', doubleTouch)
element.addEventListener('dblclick', doubleClick)

In case of this error :
Unable to preventDefault inside passive event listener due to target being treated as passive.

event.preventDefault( ) not working if element = "document" or "document.body"
So the solution of that, you should have a full page div container :

let element = document.getElementById('container')
element.style.minWidth = '100vw'
element.style.minHeight = '100vh'
document.body.style.margin = '0px'
element.addEventListener('touchstart', elementTouch)
element.addEventListener('dblclick', doubleClick)

If you need simple pure js then try something like this gist.

I created this based off the answer @planet260 gave; this one actually works though. It uses Typescript, but you can just remove the typing if you're using JS. You can also play with the time delta (how long to wait for the 2nd tap). Personally, 300ms feels pretty natural to me.

let tapTimer: ReturnType<typeof setTimeout>| null = null
export function tap(singleTapFunc: Function, doubleTapFunc: Function) {
  const dblTapDelta = 300
  function dblTapTimeout() {
    singleTapFunc()
    tapTimer = null;
  }
  if (!tapTimer) {
    tapTimer = setTimeout(dblTapTimeout, dblTapDelta)
  } else {
    clearTimeout(tapTimer)
    tapTimer = null
    doubleTapFunc()
  }
}

And you can call it like this:

<div onClick={() => tap(
    () => console.log('SINGLE CLICK'),
    () => console.log('DOUBLE CLICK'),
)}></div>
发布评论

评论列表(0)

  1. 暂无评论