programing

싱글클릭 이벤트와 더블클릭 이벤트를 구분하는 방법은?

jooyons 2023. 11. 1. 22:20
반응형

싱글클릭 이벤트와 더블클릭 이벤트를 구분하는 방법은?

나는 아이디가 있는 li에 버튼이 하나 있습니다."my_id". 이 요소로 jQuery 이벤트 2개를 첨부하였습니다.

1.

$("#my_id").click(function() { 
    alert('single click');
});

2.

$("#my_id").dblclick(function() {
    alert('double click');
});

하지만 그때마다 나는single click

더 많은 임시 상태 및 setTimeout을 활용하는 대신 다음과 같은 네이티브 속성이 있음이 밝혀졌습니다.detail당신이 접근할 수 있는.event물건!

element.onclick = event => {
   if (event.detail === 1) {
     // it was a single click
   } else if (event.detail === 2) {
     // it was a double click
   }
};

현대 브라우저는 물론 IE-9까지 지원 :)

출처 : https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail

의 행동은.dblclick이벤트는 Quicks mode에서 설명됩니다.

A에 대한 이벤트 순서.dblclick다음과 같습니다.

  1. 콧수염을 기른
  2. 마우스를 갖다 대다
  3. 딸깍 소리를 내다
  4. 콧수염을 기른
  5. 마우스를 갖다 대다
  6. 딸깍 소리를 내다
  7. dbl click

이 규칙의 한 가지 예외는 (물론)Internet Explorer(인터넷 익스플로러) 사용자 정의 순서:

  1. 콧수염을 기른
  2. 마우스를 갖다 대다
  3. 딸깍 소리를 내다
  4. 마우스를 갖다 대다
  5. dbl click

보다시피, 같은 요소에서 두 이벤트를 함께 듣는 것은 당신에게 추가적인 호출을 초래할 것입니다.click조련사

타임아웃을 이용하여 첫 번째 클릭 후 또 다른 클릭이 있는지 확인해야 합니다.

비결은 다음과 같습니다.

// Author:  Jacek Becela
// Source:  http://gist.github.com/399624
// License: MIT

jQuery.fn.single_double_click = function(single_click_callback, double_click_callback, timeout) {
  return this.each(function(){
    var clicks = 0, self = this;
    jQuery(this).click(function(event){
      clicks++;
      if (clicks == 1) {
        setTimeout(function(){
          if(clicks == 1) {
            single_click_callback.call(self, event);
          } else {
            double_click_callback.call(self, event);
          }
          clicks = 0;
        }, timeout || 300);
      }
    });
  });
}

용도:

$("button").single_double_click(function () {
  alert("Try double-clicking me!")
}, function () {
  alert("Double click detected, I'm hiding")
  $(this).hide()
})
<button>Click Me!</button>

편집:

다음과 같이 네이티브를 사용하는 것을 선호합니다.dblclick이벤트 : http://www.quirksmode.org/dom/events/click.html

또는 jQuery에서 제공하는 것: http://api.jquery.com/dblclick/

현대의 정답은 수용된 정답과 @yw의 풀이를 혼합한 것입니다.첫 번째 클릭을 방지하려면 시간 초과가 필요합니다.event.detail체크하여 두 번째 클릭을 방지합니다.

const button = document.getElementById('button')
let timer
button.addEventListener('click', event => {
  if (event.detail === 1) {
    timer = setTimeout(() => {
      console.log('click')
    }, 200)
  }
})
button.addEventListener('dblclick', event => {
  clearTimeout(timer)
  console.log('dblclick')
})
<button id="button">Click me</button>

간단한 기능.jquery나 다른 프레임워크가 필요하지 않습니다.기능을 매개 변수로 전달

<div onclick="doubleclick(this, function(){alert('single')}, function(){alert('double')})">click me</div>
    <script>
        function doubleclick(el, onsingle, ondouble) {
            if (el.getAttribute("data-dblclick") == null) {
                el.setAttribute("data-dblclick", 1);
                setTimeout(function () {
                    if (el.getAttribute("data-dblclick") == 1) {
                        onsingle();
                    }
                    el.removeAttribute("data-dblclick");
                }, 300);
            } else {
                el.removeAttribute("data-dblclick");
                ondouble();
            }
        }
    </script>

브라우저에 따라 동작이 달라집니다.

핸들러를 동일한 요소에 대한 클릭 이벤트와 dblclick 이벤트에 모두 바인딩하는 것은 바람직하지 않습니다.트리거된 이벤트의 순서는 브라우저마다 다르며, 일부는 dblclick 전에 두 번의 클릭 이벤트를 수신하고 다른 이벤트는 한 번만 수신합니다.더블 클릭 감도(더블 클릭으로 감지되는 클릭 간 최대 시간)는 운영 체제 및 브라우저에 따라 달라질 수 있으며, 종종 사용자가 구성할 수 있습니다.

http://api.jquery.com/dblclick/

Firefox에서 코드 실행, 의 경보()click()핸들러를 사용하면 두 번째 클릭을 할 수 없습니다.이러한 경고를 제거하면 두 이벤트가 모두 표시됩니다.

더블 클릭(두 번 클릭)을 하려면 먼저 한 번 클릭해야 합니다.click()핸들러는 첫 번째 클릭으로 발사되고, 경고가 팝업되기 때문에 두 번째 클릭으로 발사할 기회가 없습니다.dblclick()조련사

핸들러를 변경하여 다른 작업을 수행합니다.alert()행동을 보게 될 겁니다(아마도 요소의 배경색을 변경할 수 있습니다.

$("#my_id").click(function() { 
    $(this).css('backgroundColor', 'red')
});

$("#my_id").dblclick(function() {
    $(this).css('backgroundColor', 'green')
});

이 대답은 시간이 지나면서 쓸모가 없어집니다. @kyw의 해결책을 확인해 보세요.

@AdrienSchuler가 올린 요지에서 영감을 얻어 솔루션을 만들었습니다.한 번의 클릭과 두 번의 클릭을 요소에 바인딩하려는 경우에만 이 솔루션을 사용합니다.그렇지 않으면 네이티브를 사용하는 것이 좋습니다.click그리고.dblclick청취자 여러분

차이점은 다음과 같습니다.

  • Vanillajs, 종속성 없음
  • 기다리지 마세요.setTimeout클릭 또는 더블 클릭 핸들러를 다루다
  • 먼저 두 번 클릭하면 클릭 핸들러가 실행되고, 다음으로 두 번 클릭 핸들러가 실행됩니다.

자바스크립트:

function makeDoubleClick(doubleClickCallback, singleClickCallback) {
    var clicks = 0, timeout;
    return function() {
        clicks++;
        if (clicks == 1) {
            singleClickCallback && singleClickCallback.apply(this, arguments);
            timeout = setTimeout(function() { clicks = 0; }, 400);
        } else {
            timeout && clearTimeout(timeout);
            doubleClickCallback && doubleClickCallback.apply(this, arguments);
            clicks = 0;
        }
    };
}

용도:

var singleClick = function(){ console.log('single click') };
var doubleClick = function(){ console.log('double click') };
element.addEventListener('click', makeDoubleClick(doubleClick, singleClick));

아래는 jsfiddle에서의 사용법이며, jQuery 버튼은 수락된 답변의 동작입니다.

jsfiddle

A1rPun 답변을 기반으로 한 또 다른 간단한 바닐라 솔루션(jQuery 솔루션에 대한 그의 피들 참조).

사용자가 더블클릭할 때 싱글클릭 핸들러를 트리거하지 않기 위해서는 반드시 지연 후 싱글클릭 핸들러가 트리거되어야 하는 것 같습니다...

var single = function(e){console.log('single')},
    double = function(e){console.log('double')};

var makeDoubleClick = function(e) {

  var clicks = 0,
      timeout;

  return function (e) {

    clicks++;

    if (clicks == 1) {
      timeout = setTimeout(function () {
        single(e);
        clicks = 0;
      }, 250);
    } else {
      clearTimeout(timeout);
      double(e);
      clicks = 0;
    }
  };
}
document.getElementById('btnVanilla').addEventListener('click', makeDoubleClick(), false);

하나의 요소와 동일한 요소에 대한 한 번의 클릭과 두 번의 클릭을 구분하는 방법은 무엇입니까?

굳이 섞을 필요가 없다면, 의지할 수 있습니다.click그리고.dblclick각자가 일을 잘 해낼 겁니다

이들을 혼합하려고 할 때 문제가 발생합니다. 이벤트가 실제로 이벤트도 트리거하므로 단일 클릭이 "독립 실행형" 단일 클릭인지 또는 두 번 클릭의 일부인지 확인해야 합니다.

또한: 하나의 동일한 요소에 모두 사용해서는 안 됩니다.

핸들러를 동일한 요소에 대한 클릭 이벤트와 dblclick 이벤트에 모두 바인딩하는 것은 바람직하지 않습니다.트리거된 이벤트의 순서는 브라우저마다 다르며, 일부는 dblclick 전에 두 번의 클릭 이벤트를 수신하고 다른 이벤트는 한 번만 수신합니다.더블 클릭 감도(더블 클릭으로 감지되는 클릭 간 최대 시간)는 운영 체제 및 브라우저에 따라 달라질 수 있으며, 종종 사용자가 구성할 수 있습니다.
출처 : https://api.jquery.com/dblclick/

자, 이제 좋은 소식을 전하겠습니다.

이벤트 속성을 사용하여 이벤트와 관련된 클릭 수를 탐지할 수 있습니다.이것은 안에서 더블 클릭을 합니다.click꽤나 쉽게 발견할 수군요

문제는 한 번의 클릭과 두 번의 클릭에 포함되는지 여부를 감지하는 것입니다.그래서 저희가 다시 타이머를 사용하고 또.setTimeout.

(글로벌 변수를 방지하기 위해) 데이터 속성을 사용하고 클릭 수를 직접 셀 필요 없이 이 모든 것을 함께 포장하면 다음과 같은 이점을 얻을 수 있습니다.

HTML:

<div class="clickit" style="font-size: 200%; margin: 2em; padding: 0.25em; background: orange;">Double click me</div>

<div id="log" style="background: #efefef;"></div>

자바스크립트:

<script>
var clickTimeoutID;
$( document ).ready(function() {

    $( '.clickit' ).click( function( event ) {

        if ( event.originalEvent.detail === 1 ) {
            $( '#log' ).append( '(Event:) Single click event received.<br>' );

            /** Is this a true single click or it it a single click that's part of a double click?
             * The only way to find out is to wait it for either a specific amount of time or the `dblclick` event.
             **/
            clickTimeoutID = window.setTimeout(
                    function() {
                        $( '#log' ).append( 'USER BEHAVIOR: Single click detected.<br><br>' );
                    },
                    500 // how much time users have to perform the second click in a double click -- see accessibility note below.
                );

        } else if ( event.originalEvent.detail === 2 ) {
            $( '#log' ).append( '(Event:) Double click event received.<br>' );
            $( '#log' ).append( 'USER BEHAVIOR: Double click detected.<br>' );
            window.clearTimeout( clickTimeoutID ); // it's a dblclick, so cancel the single click behavior.
        } // triple, quadruple, etc. clicks are ignored.

    });

});
</script>

데모:

제이에스피들


접근성 및 더블 클릭 속도에 관한 참고 사항:

  • 위키피디아는 "두 번의 연속 클릭이 더블 클릭으로 해석되는 데 필요한 최대 지연 시간은 표준화되어 있지 않습니다."라고 말합니다.
  • 브라우저에서 시스템의 더블 클릭 속도를 감지할 방법이 없습니다.
  • 기본값은 500ms이고 Windows(소스)의 범위는 100-900ms인 것 같습니다.
  • OS 설정에서 더블 클릭 속도를 가장 느린 속도로 설정하는 장애인을 생각해 보십시오.
    • 시스템 더블 클릭 속도가 위의 기본값 500ms보다 느릴 경우 싱글 및 더블 클릭 동작이 모두 트리거됩니다.
    • 한 번의 조합에 의존하지 말고 한 개의 동일한 항목을 두 번 클릭하세요.
    • 또는: 옵션에 설정을 추가하여 값을 증가시킬 수 있습니다.

만족스러운 해결책을 찾는 데 시간이 꽤 걸렸습니다. 도움이 되었으면 좋겠습니다!

임의의 수의 사건에 대한 점 코드의 대안은 다음과 같습니다.

 var multiClickHandler = function (handlers, delay) {
    var clicks = 0, timeout, delay = delay || 250;
    return function (e) {
      clicks++;
      clearTimeout(timeout);
      timeout = setTimeout(function () {
        if(handlers[clicks]) handlers[clicks](e);
        clicks = 0;
      }, delay);
    };
  }

  cy.on('click', 'node', multiClickHandler({
    1: function(e){console.log('single clicked ', e.cyTarget.id())},
    2: function(e){console.log('double clicked ', e.cyTarget.id())},
    3: function(e){console.log('triple clicked ', e.cyTarget.id())},
    4: function(e){console.log('quadro clicked ', e.cyTarget.id())},
    // ...
  }, 300));

cytoscape.js 앱에 필요했습니다.

우수한 jQuery Sparkle 플러그인을 사용합니다.플러그인은 처음 클릭과 마지막 클릭을 감지할 수 있는 옵션을 제공합니다.첫 번째 클릭 뒤에 다른 클릭이 이어졌는지 감지하여 클릭과 dbl클릭을 구분하는 데 사용할 수 있습니다.

http://balupton.com/sandbox/jquery-sparkle/demo/ 에서 확인해보세요.

사용자 지정 'single click' 이벤트를 사용하여 한 번의 클릭과 두 번의 클릭을 구분할 수 있는 간단한 jQuery 플러그인을 작성했습니다.

https://github.com/omriyariv/jquery-singleclick

$('#someDiv').on('singleclick', function(e) {
    // The event will be fired with a small delay.
    console.log('This is certainly a single-click');
}

저는 jquery(및 기타 90-140k lib)를 피하는 것을 좋아하며, 브라우저가 먼저 클릭하면 처리하므로 여기에 제가 만든 웹 사이트에서 수행한 작업이 있습니다(이 예제에서는 클릭 위치 local xy도 포함됩니다).

clicksNow-0; //global js, owell

function notify2(e, right) {  // called from onclick= and oncontextmenu= (rc)
var x,y,xx,yy;
var ele = document.getElementById('wrap');  
    // offset fixed parent for local win x y
var xxx= ele.offsetLeft;
var yyy= ele.offsetTop;

//NScape
if (document.layers || document.getElementById&&!document.all) {
    xx= e.pageX;
    yy= e.pageY;
} else {
    xx= e.clientX;
    yy= e.clientY;
}
x=xx-xxx;
y=yy-yyy;

clicksNow++;
    // 200 (2/10ths a sec) is about a low as i seem to be able to go
setTimeout( "processClick( " + right + " , " + x + " , " + y + ")", 200);
}

function processClick(right, x, y) {
if (clicksNow==0) return; // already processed as dblclick
if (clicksNow==2) alert('dbl');
clicksNow=0;
    ... handle, etc ...
}

도움이 되는 희망

Adrien Schuler(정말 감사합니다!!!)의 답변을 토대로 Datatables.net 을 비롯한 다양한 용도로 사용할 수 있도록 다음과 같이 수정합니다.

기능.

/**
 * For handle click and single click in child's objects
 * @param {any} selector Parents selector, like 'tr'
 * @param {any} single_click_callback Callback for single click
 * @param {any} double_click_callback Callback for dblclick
 * @param {any} timeout Timeout, optional, 300 by default
 */
jQuery.fn.single_double_click = function (selector, single_click_callback, double_click_callback, timeout) {
    return this.each(function () {
        let clicks = 0;
        jQuery(this).on('click', selector, function (event) {
            let self = this;
            clicks++;
            if (clicks == 1) {
                setTimeout(function () {
                    if (clicks == 1) {
                        single_click_callback.call(self, event);
                    } else {
                        double_click_callback.call(self, event);
                    }
                    clicks = 0;
                }, timeout || 300);
            }
        });
    });
}

사용하다

$("#MyTableId").single_double_click('tr',
            function () {   //  Click
                let row = MyTable.row(this);
                let id = row.id();
                let data = row.data();
                console.log("Click in "+id+" "+data);
            },
            function () {   //  DBLClick
                let row = MyTable.row(this);
                let id = row.id();
                let data = row.data();
                console.log("DBLClick in "+id+" "+data);
            }
        );
let clickTimes = 0;
let timer = null;
roundBox.click = function (e) {
  clearTimeout(timer);
  timer = setTimeout(() => { // 单击事件
    console.log("single click");
  }, 600);
  clickTimes++;

  if (clickTimes == 2) { // 双击
    clearTimeout(timer);
    clickTimes = 0;
    console.log("double click");
    toggleExpanded(id);
  }
}

저한테는 효과가 있었습니다만..

var clicked=0;
function chkBtnClcked(evnt) {
    clicked++;
    // wait to see if dblclick
    if (clicked===1) {
        setTimeout(function() {
            clicked=0;
            .
            .
        }, 300); // test for another click within 300ms
    }
    if (clicked===2) {
        stopTimer=setInterval(function() {
            clicked=0;
            .
            .
        }, 30*1000); // refresh every 30 seconds
    }
}

사용 –

<div id="cloneimages" style="position: fixed;" onclick="chkBtnClcked(evnt)"  title="Click for next pic; double-click for slide show"></div>

필요할 때를 대비해 HTML로 네이티브 답변을 올려주시면 됩니다.

<p ondblclick="myFunction()" id = 'id'>Double-click me</p>

물론 이것은 네이티브 Jquery 옵션이 있습니다. 즉...$('#id').attr('ondblclick',function(){...})또는, 앞서 밝힌 바와 같이,$('#id').dblclick(function(){...});

나는 이것이 오래된 것이라는 것을 알고 있지만, 아래는 단일 타이머가 단일 대 더블 클릭을 결정하는 기본 루프 카운터의 예입니다.이것이 누군가에게 도움이 되기를 바랍니다.

var count = 0;
var ele = document.getElementById("my_id");
ele.addEventListener('click', handleSingleDoubleClick, false); 

function handleSingleDoubleClick()
{
  if(!count) setTimeout(TimerFcn, 400); // 400 ms click delay
  count += 1;
}
function TimerFcn() 
{
  if(count > 1) console.log('you double clicked!')
  else console.log('you single clicked')
  count = 0;
}

이 코드를 사용해 보십시오.

let click = 0;
element.onclick = (event) => {
  click++;
  console.log(click);
  setTimeout(() => {
    click = 0;
  }, 300);
  if (click === 2) {
    console.log("double Click");
    click = 0;
    console.log(click);
  }
};

싱글 클릭과 더블 클릭을 구별하려면 싱글 클릭의 이벤트 처리기가 더블 클릭의 시작이 아님이 증명될 때까지 기다려야 합니다.이로 인해 한 번의 클릭이 지연됩니다.예는 이를 보여줍니다.

var distinguish = (() => {
  var target = null;
  var timeout = null;
  return (element, action) => {
    element.addEventListener ('click', e => {
      if (e.target === target) {
        clearTimeout (timeout);
        target = null;
        timeout = null;
        action ('double');
      } else {
        target = e.target;
        timeout = setTimeout (() => {
          target = null;
          timeout = null;
          action ('single');
        }, 500);
      }
    });
  };
})();

var button = document.getElementById ('button');

distinguish (button, kind => console.log (kind + ' click'));
<input id="button" type="button" value="click">

순수 JS는 싱글 대 더블 클릭을 진정으로 구별하기 위한 것입니다(예: 둘 다 동시에 트리거하지 않는 것).더블클릭으로 취소될 경우 싱글클릭이 발생하지 않도록 네이티브 event.detail과 사용자 지정 지연의 조합을 사용하고 있습니다.이 접근 방식은 우리가 클릭할 때마다 새로운 타이머가 시작되지 않기 때문에 성능 면에서도 매우 뛰어납니다.

다른 솔루션 중 일부와 마찬가지로 유일하게 사소한 것은 사용자가 매우 느리게 두 번 클릭할 경우 두 이벤트가 모두 발생할 수 있다는 것입니다.이는 지연 시간을 높임으로써 방지할 수 있지만, 이는 한 번의 클릭으로 훨씬 더 지연되는 느낌을 줄 것입니다.

또한 빠른 멀티 클릭을 처리하는 방법에 대해서는 제안된 답변에 많은 차이가 있습니다.이 접근 방식을 사용하면 클릭할 때마다 다음과 같은 결과가 발생합니다.

  1. 더블 클릭으로 취소되지 않으면 약간 지연된 싱글 클릭을 트리거합니다.
  2. 트리거를 더블 클릭
  3. 아무 것도 없어요.
  4. 트리거를 더블 클릭
  5. 아무 것도 없어요.

...(매 두 번째 클릭은 더블 클릭으로 매우 자연스럽게 느껴집니다.)

당신이 직접 테스트할 수 있도록 토막을 포함했습니다.

document.querySelector('button').addEventListener('click', single_or_double);

let isSingleClick; // flag to allow or cancel single clicks 

function single_or_double(){
  if (isSingleClick = event.detail == 1){ //check for a singleclick and store flag globally at the same time
    setTimeout(() => {
      if(isSingleClick){ //check if the flag is still set after the delay
        console.log("single");
      }
    }, 200); // singleclick delay in milliseconds
  }
  else if (event.detail == 2) {
    console.log("double");
  }
}
<button>Single OR Double-Click</button>

언급URL : https://stackoverflow.com/questions/5497073/how-to-differentiate-single-click-event-and-double-click-event

반응형