JavaScript에서 길게 누르시겠습니까?


117

자바 스크립트 (또는 jQuery)에서 "길게 누르기"를 구현할 수 있습니까? 어떻게?

대체 텍스트
(출처 : androinica.com )

HTML

<a href="" title="">Long press</a>

자바 스크립트

$("a").mouseup(function(){
  // Clear timeout
  return false;
}).mousedown(function(){
  // Set timeout
  return false; 
});

7
나는 아마 당신의 코드를 기반으로 사용자 정의 jQuery 이벤트를 만들 것입니다. 그래서 당신은 그냥 할 수 있습니다jQuery(...).longclick(function() { ... });
Matti Virkkunen 2010

1
질문에는 jQuery로 태그가 지정되어 있지 않습니다. 질문은 먼저 jQuery 솔루션을 선호하거나 선택적으로 (괄호 안에) 순수한 Javascript 솔루션을 요청합니다. 대부분의 답변은 기본적으로 jQuery를 표준 가정으로 사용하는 것 같습니다. 나는 항상 jQuery를 경멸했고 한 번도 그것을 사용하지 않았고 그것에 대한 어떤 강력한 필요성도 느끼지 않았습니다. 어떤 사람들은 그것을 사용하는 것을 좋아합니다. 두 가지 기술을 사용한 답변은 아무런 해가되지 않습니다. 그러나 질문이 jQuery 솔루션을 받아 들일 것이기 때문에 jQuery 태그는 더 많은 시선을 끌고 더 나은 답변을 얻을 수 있습니다. 여기에 jQuery 답변이 부족한 것 같습니다.

답변:


159

'jQuery'마법은 없으며 JavaScript 타이머 만 있습니다.

var pressTimer;

$("a").mouseup(function(){
  clearTimeout(pressTimer);
  // Clear timeout
  return false;
}).mousedown(function(){
  // Set timeout
  pressTimer = window.setTimeout(function() { ... Your Code ...},1000);
  return false; 
});

39
이 불도 끌리지 않습니까?
Gallal

11
아마도 호출하여 그에게 볼 아주 간단한 것 @Gallal clearTimeout(pressTimer)mousemove내가 뭔가를 누락하지 않는 한,. 전례가 없을 것입니다.
David John Welsh

5
@DavidJohnWelsh 제가 살펴본 바로는, 마우스 움직임만을 원하지는 않습니다. 손가락을 움직이지 않고 1px를 움직이지 않는 것은 매우 어렵습니다! 임계 값을 적용해야합니다 (마우스가 10px를 이동하지 않은 경우). 매우 빠르게 복잡해집니다!
Ian

6
휴대 전화에서이 기능이 작동 할 것으로 예상되는 경우 자체 기본 길게 누르기 동작이있는 경우가 많습니다 (예를 들어 Android의 크롬은 링크를 길게 누르면 다양한 옵션이있는 모달 메뉴를 표시 함). 나는 이것을 막을 행운이 없었으며 솔직히 브라우저 기본 동작을 방해하는 것은 어쨌든 아무것도 숨기는 것입니다.
dartacus 2016

4
이것은 선택된 답변이지만 실제로 질문에 대한 답변은 아닙니다. 지나치게 단순하고 순진합니다. 길게 누르는 이벤트는이 답변이 무시하는 여러 문제를 해결해야합니다. 1) 멀티 터치의 제스처에서 길게 누름을 구별 (예 : 핀치 확대 또는 축소) 2) 요소 또는 브라우저 영역 외부로 이동하는 경우 취소 3) 많은 플랫폼 및 장치에서 텍스트 선택의 기본 동작 해결 4) 허용 민감도에 대한 구성 가능한 임계 값이며 매직 넘버에 의존하지 않습니다. 접근성 문제에 특히 도움이되지만 배타적이지는 않습니다.

34

Maycow Moura의 답변을 바탕으로 이것을 썼습니다. 또한 사용자가 마우스 오른쪽 버튼을 클릭하지 않았는지 확인하여 길게 누르면 모바일 장치에서 작동합니다. 데모

var node = document.getElementsByTagName("p")[0];
var longpress = false;
var presstimer = null;
var longtarget = null;

var cancel = function(e) {
    if (presstimer !== null) {
        clearTimeout(presstimer);
        presstimer = null;
    }

    this.classList.remove("longpress");
};

var click = function(e) {
    if (presstimer !== null) {
        clearTimeout(presstimer);
        presstimer = null;
    }

    this.classList.remove("longpress");

    if (longpress) {
        return false;
    }

    alert("press");
};

var start = function(e) {
    console.log(e);

    if (e.type === "click" && e.button !== 0) {
        return;
    }

    longpress = false;

    this.classList.add("longpress");

    if (presstimer === null) {
        presstimer = setTimeout(function() {
            alert("long click");
            longpress = true;
        }, 1000);
    }

    return false;
};

node.addEventListener("mousedown", start);
node.addEventListener("touchstart", start);
node.addEventListener("click", click);
node.addEventListener("mouseout", cancel);
node.addEventListener("touchend", cancel);
node.addEventListener("touchleave", cancel);
node.addEventListener("touchcancel", cancel);

CSS 애니메이션을 사용하여 몇 가지 표시기를 포함해야합니다.

p {
    background: red;
    padding: 100px;
}

.longpress {
    -webkit-animation: 1s longpress;
            animation: 1s longpress;
}

@-webkit-keyframes longpress {
    0%, 20% { background: red; }
    100% { background: yellow; }
}

@keyframes longpress {
    0%, 20% { background: red; }
    100% { background: yellow; }
}

나는 jsfiddle 버튼을 누르고있는 동안 계속해서 무언가를하기 위해이 수정 된 버전을 만들었습니다. 하지만 어떤 이유로 안드로이드에서는 + 버튼을 터치를 멈춘 후에도 실행됩니다 ...
Xander

@Xander : :hover터치 장치 에서 상태가 고정되어 있기 때문에 여기에도 적용됩니다.
kelunik

Dang, 긴 누르기를 지원하는 모바일 사이트에서 작동하는-/ + 숫자 증가 버튼을 얻을 수있는 방법이 있는지 궁금합니다. 내가 찾은 모든 방법은 반복적으로 클릭하는 것만 지원하므로 엄청난 수의 고통입니다. 그래도 고마워!
Xander

@Xander : 실제로, touchendIMO를 실행해야합니다. 터치 장치 용 특수 코드 일 때 끈적 거릴 이유가 없습니다. 내일 뭔가를 시도해 보겠습니다.
kelunik

1
Android에서 문제를 파악했습니다. 를 누르면 mousedown과 touchstart가 모두 실행되므로 2 개의 타이머가 실행되지만 손가락을 떼면 1 개만 취소됩니다. 타이머가 이미 활성화되지 않았는지 확인하기 위해 presstimer를 if (presstimer === null)로 래핑했습니다.
Xander


16

내가 만든 긴 프레스 이벤트 (0.5K 순수 자바 스크립트) 이 문제를 해결하기를, 그것은 추가 long-press는 DOM에 이벤트를.

모든 요소 long-press대해 들어보십시오 .

// the event bubbles, so you can listen at the root level
document.addEventListener('long-press', function(e) {
  console.log(e.target);
});

특정 요소 long-press에 대한 청취 :

// get the element
var el = document.getElementById('idOfElement');

// add a long-press event listener
el.addEventListener('long-press', function(e) {

    // stop the event from bubbling up
    e.preventDefault()

    console.log(e.target);
});

IE9 +, Chrome, Firefox, Safari 및 하이브리드 모바일 앱에서 작동합니다 (iOS / Android의 Cordova 및 Ionic).

데모


2
신세, 친구!
제프 T.

1
이 솔루션 원숭이는 window.CustomEvent 객체를 다소 우연하고 불완전하며 비표준 방식으로 패치합니다. 읽기 전용 속성을 읽기 전용이 아니라 읽기-쓰기로 제대로 생성하지 않습니다. 특히 returnValue, type, timeStamp 및 isTrusted가 누락되었습니다. 드래그, 제스처, 핀치 확대 / 축소 또는 길게 누르기의 멀티 터치 오작동을 해결하지 않으며 500ms에서도 길게 누르기를 기본으로 설정하는 많은 수의 장치 및 / 또는 플랫폼 문제를 해결하지 않습니다. 라이브러리에는 이러한 조건에 대한 모든 테스트 케이스가 누락되었습니다.

4
그것은 오픈 소스, :) 프로젝트에 기여 주시기
존 도허티

@JohnDoherty 대단해! 그러나 동일한 요소에 "onClick"을 계속 사용할 수 있습니까?
Devashish

2
당신은 여전히 긴 언론에 '긴 프레스 지연'타이머 차기 전에 출시로 너무 오래 '온 클릭'이벤트를 얻어야한다
존 도허티

15

타임 아웃과 몇 가지 마우스 이벤트 핸들러를 사용하여 자체적으로 구현할 수있을만큼 간단 해 보이지만 동일한 요소에서 누르기와 길게 누르기를 모두 지원하는 클릭-드래그-릴리스와 같은 경우를 고려하면 조금 더 복잡해집니다. , iPad와 같은 터치 장치로 작업합니다. 결국 longclick jQuery 플러그인 ( Github )을 사용하게 되었습니다 . 휴대폰과 같은 터치 스크린 장치 만 지원해야하는 경우 jQuery Mobile taphold 이벤트를 사용해 볼 수도 있습니다 .


Github 링크는 작동하지만 프로젝트는 2010 년 이후로 업데이트되지 않았으며 현재 jquery 버전에서 작동하지 않습니다. 그러나 소스 코드에서 handle.apply를 dispatch.apply로 바꾸면 문제가 해결됩니다.
arlomedia

11

jQuery 플러그인. 그냥 넣어 $(expression).longClick(function() { <your code here> });. 두 번째 매개 변수는 유지 기간입니다. 기본 시간 제한은 500ms입니다.

(function($) {
    $.fn.longClick = function(callback, timeout) {
        var timer;
        timeout = timeout || 500;
        $(this).mousedown(function() {
            timer = setTimeout(function() { callback(); }, timeout);
            return false;
        });
        $(document).mouseup(function() {
            clearTimeout(timer);
            return false;
        });
    };

})(jQuery);

이것은 호출에 유지되지 않습니다.
Champ

안녕하세요 브로 우리는 백본 이벤트로 사용할 수 있습니다
user2075328

6

크로스 플랫폼 개발자의 경우 (참고 지금까지 제공된 모든 답변은 iOS에서 작동하지 않습니다) :

Mouseup / down은 Android 에서 제대로 작동하는 것처럼 보였지만 모든 장치 (예 : 삼성 탭 4)는 아닙니다. iOS 에서 전혀 작동하지 않았습니다. .

추가 연구는 이것이 선택을 갖는 요소 때문이며 기본 배율이 청취자를 방해하는 것으로 보입니다.

이 이벤트 리스너는 사용자가 이미지를 500ms 동안 보유하는 경우 부트 스트랩 모달에서 축소판 이미지를 열 수 있도록합니다.

반응 형 이미지 클래스를 사용하므로 더 큰 버전의 이미지를 표시합니다. 이 코드는 (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)
});

iOS를위한 멋진 솔루션
eric xu

썸네일에서 시작하는 터치를 어떻게 방지 할 수 있지만 결국 스크롤이되는 것입니다. 즉, touchstart / end in place가 아니라 핸들러를 사용하여 요소에서 시작했지만 스크롤이되는 터치
Akin Hwan

5
$(document).ready(function () {
    var longpress = false;

    $("button").on('click', function () {
        (longpress) ? alert("Long Press") : alert("Short Press");
    });

    var startTime, endTime;
    $("button").on('mousedown', function () {
        startTime = new Date().getTime();
    });

    $("button").on('mouseup', function () {
        endTime = new Date().getTime();
        longpress = (endTime - startTime < 500) ? false : true;
    });
});

데모


2
이 코드는 500ms가 끝날 때 longclick이 실행되지 않습니다. 사용자는 마우스 클릭으로 죽을 수 있습니다. :). 긴 클릭은 사용자가 버튼 클릭을 중단하는 경우에만 실행됩니다.
jedi 2016 년

이것은 사용자가 같은 지점에서 길게 누르는 대신 스크롤을 시작한 경우를 다룰까요?
Akin Hwan

@AkinHwan 아니요, 마우스 클릭이 동일한 요소 위에 놓인 경우에만 트리거됩니다.
razz

4

Diodeus의 대답은 굉장하지만 onClick 기능을 추가 할 수 없으며 onclick을 입력하면 hold 기능을 실행하지 않습니다. 그리고 Razzak의 대답은 거의 완벽하지만 mouseup에서만 Hold 기능을 실행하며 일반적으로 사용자가 계속 누르고 있어도 기능이 실행됩니다.

그래서 나는 둘 다 합류하여 이것을 만들었습니다.

$(element).on('click', function () {
    if(longpress) { // if detect hold, stop onclick function
        return false;
    };
});

$(element).on('mousedown', function () {
    longpress = false; //longpress is false initially
    pressTimer = window.setTimeout(function(){
    // your code here

    longpress = true; //if run hold function, longpress is true
    },1000)
});

$(element).on('mouseup', function () {
    clearTimeout(pressTimer); //clear time on mouseup
});

사용자가 mousedown 후 스크롤을 시작하고 길게 누르려는 의도가 없다면 어떻게 될까요
Akin Hwan


2

마우스를 눌렀을 때 해당 요소에 대한 시간 제한을 설정하고 마우스를 올리면 지울 수 있습니다.

$("a").mousedown(function() {
    // set timeout for this element
    var timeout = window.setTimeout(function() { /* … */ }, 1234);
    $(this).mouseup(function() {
        // clear timeout for this element
        window.clearTimeout(timeout);
        // reset mouse up event handler
        $(this).unbind("mouseup");
        return false;
    });
    return false;
});

이를 통해 각 요소는 자체 시간 초과를 얻습니다.


1
$(this).mouseup(function(){});이벤트 핸들러를 제거하지 않고 다른 핸들러를 추가합니다. .unbind대신 사용하십시오 .
Matti Virkkunen 2010

off()바인딩 해제 대신 지금 사용해야합니다 .
dbinott

1

jquery-mobile의 탭 홀드를 사용할 수 있습니다. jquery-mobile.js를 포함하면 다음 코드가 제대로 작동합니다.

$(document).on("pagecreate","#pagename",function(){
  $("p").on("taphold",function(){
   $(this).hide(); //your code
  });    
});

JQuery와 모바일이 좋은 안정 프레임 워크를 제공하기 때문에이 허용 대답해야한다
pasx

1

가장 우아하고 깨끗한 jQuery 플러그인 : https://github.com/untill/jquery.longclick/ , packacke로도 사용 가능 : https://www.npmjs.com/package/jquery.longclick .

간단히 말해서 다음과 같이 사용합니다.

$( 'button').mayTriggerLongClicks().on( 'longClick', function() { your code here } );

이 플러그인의 장점은 다른 답변과 달리 클릭 이벤트가 여전히 가능하다는 것입니다. 마우스를 올리기 전에 장치를 길게 탭하는 것처럼 긴 클릭이 발생합니다. 그래서 그것은 기능입니다.


0

저에게는 해당 코드 (jQuery 사용)로 작업합니다.

var int       = null,
    fired     = false;

var longclickFilm = function($t) {
        $body.css('background', 'red');
    },
    clickFilm = function($t) {
        $t  = $t.clone(false, false);
        var $to = $('footer > div:first');
        $to.find('.empty').remove();
        $t.appendTo($to);
    },
    touchStartFilm = function(event) {
        event.preventDefault();
        fired     = false;
        int       = setTimeout(function($t) {
            longclickFilm($t);
            fired = true;
        }, 2000, $(this)); // 2 sec for long click ?
        return false;
    },
    touchEndFilm = function(event) {
        event.preventDefault();
        clearTimeout(int);
        if (fired) return false;
        else  clickFilm($(this));
        return false;
    };

$('ul#thelist .thumbBox')
    .live('mousedown touchstart', touchStartFilm)
    .live('mouseup touchend touchcancel', touchEndFilm);

0

Click 또는 Long Press [jQuery] 식별 시간을 확인할 수 있습니다.

function AddButtonEventListener() {
try {
    var mousedowntime;
    var presstime;
    $("button[id$='" + buttonID + "']").mousedown(function() {
        var d = new Date();
        mousedowntime = d.getTime();
    });
    $("button[id$='" + buttonID + "']").mouseup(function() {
        var d = new Date();
        presstime = d.getTime() - mousedowntime;
        if (presstime > 999/*You can decide the time*/) {
            //Do_Action_Long_Press_Event();
        }
        else {
            //Do_Action_Click_Event();
        }
    });
}
catch (err) {
    alert(err.message);
}
} 

0

이렇게?

doc.addEeventListener("touchstart", function(){
    // your code ...
}, false);    

0

jquery터치 이벤트 를 사용할 수 있습니다 . ( 여기 참조 )

  let holdBtn = $('#holdBtn')
  let holdDuration = 1000
  let holdTimer

  holdBtn.on('touchend', function () {
    // finish hold
  });
  holdBtn.on('touchstart', function () {
    // start hold
    holdTimer = setTimeout(function() {
      //action after certain time of hold
    }, holdDuration );
  });

0

길게 누르는 키보드 이벤트에 필요한 것이있어서 이것을 썼습니다.

var longpressKeys = [13];
var longpressTimeout = 1500;
var longpressActive = false;
var longpressFunc = null;

document.addEventListener('keydown', function(e) {
    if (longpressFunc == null && longpressKeys.indexOf(e.keyCode) > -1) {
        longpressFunc = setTimeout(function() {
            console.log('longpress triggered');
            longpressActive = true;
        }, longpressTimeout);

    // any key not defined as a longpress
    } else if (longpressKeys.indexOf(e.keyCode) == -1) {
        console.log('shortpress triggered');
    }
});

document.addEventListener('keyup', function(e) {
    clearTimeout(longpressFunc);
    longpressFunc = null;

    // longpress key triggered as a shortpress
    if (!longpressActive && longpressKeys.indexOf(e.keyCode) > -1) {
        console.log('shortpress triggered');
    }
    longpressActive = false;
});

0

나는 이것이 당신을 도울 수 있다고 생각합니다.

var image_save_msg = 'You Can Not Save images!';
var no_menu_msg = 'Context Menu disabled!';
var smessage = "Content is protected !!";

function disableEnterKey(e) {
    if (e.ctrlKey) {
        var key;
        if (window.event)
            key = window.event.keyCode; //IE
        else
            key = e.which; //firefox (97)
        //if (key != 17) alert(key);
        if (key == 97 || key == 65 || key == 67 || key == 99 || key == 88 || key == 120 || key == 26 || key == 85 || key == 86 || key == 83 || key == 43) {
            show_wpcp_message('You are not allowed to copy content or view source');
            return false;
        } else
            return true;
    }
}

function disable_copy(e) {
    var elemtype = e.target.nodeName;
    var isSafari = /Safari/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor);
    elemtype = elemtype.toUpperCase();
    var checker_IMG = '';
    if (elemtype == "IMG" && checker_IMG == 'checked' && e.detail >= 2) {
        show_wpcp_message(alertMsg_IMG);
        return false;
    }
    if (elemtype != "TEXT" && elemtype != "TEXTAREA" && elemtype != "INPUT" && elemtype != "PASSWORD" && elemtype != "SELECT" && elemtype != "OPTION" && elemtype != "EMBED") {
        if (smessage !== "" && e.detail == 2)
            show_wpcp_message(smessage);

        if (isSafari)
            return true;
        else
            return false;
    }
}

function disable_copy_ie() {
    var elemtype = window.event.srcElement.nodeName;
    elemtype = elemtype.toUpperCase();
    if (elemtype == "IMG") {
        show_wpcp_message(alertMsg_IMG);
        return false;
    }
    if (elemtype != "TEXT" && elemtype != "TEXTAREA" && elemtype != "INPUT" && elemtype != "PASSWORD" && elemtype != "SELECT" && elemtype != "OPTION" && elemtype != "EMBED") {
        //alert(navigator.userAgent.indexOf('MSIE'));
        //if (smessage !== "") show_wpcp_message(smessage);
        return false;
    }
}

function reEnable() {
    return true;
}
document.onkeydown = disableEnterKey;
document.onselectstart = disable_copy_ie;
if (navigator.userAgent.indexOf('MSIE') == -1) {
    document.onmousedown = disable_copy;
    document.onclick = reEnable;
}

function disableSelection(target) {
    //For IE This code will work
    if (typeof target.onselectstart != "undefined")
        target.onselectstart = disable_copy_ie;

    //For Firefox This code will work
    else if (typeof target.style.MozUserSelect != "undefined") {
        target.style.MozUserSelect = "none";
    }

    //All other  (ie: Opera) This code will work
    else
        target.onmousedown = function() {
            return false
        }
    target.style.cursor = "default";
}
// on_body_load

window.onload = function() {
    disableSelection(document.body);
};



// disable_Right_Click



document.ondragstart = function() {
    return false;
}

function nocontext(e) {
    return false;
}
document.oncontextmenu = nocontext;

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.