Pergunta

É possível implementar "Long Press" em JavaScript (ou jQuery)? Como?

alt text
(fonte: Androinica.com)

Html

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

JavaScript

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

Solução

Não existe uma mágica 'jQuery', apenas timers de 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; 
});

Outras dicas

Com base na resposta de Maycow Moura, escrevi isso. Também garante que o usuário não tenha um clique direito, o que acionaria uma pressão longa e funciona em dispositivos móveis. Demonstração

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);

Você também deve incluir alguns indicadores usando animações 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; }
}

Você pode usar Taphold Evento da API JQuery Mobile.

jQuery("a").on("taphold", function( event ) { ... } )

Embora pareça simples o suficiente para implementar por conta própria com um tempo limite e alguns manipuladores de eventos do mouse, ele fica um pouco mais complicado quando você considera casos como liberação de cliques, apoiando a imprensa e a pressão há muito tempo no mesmo elemento e trabalhando com dispositivos de toque como o iPad. Acabei usando o LongClick JQuery Plugin (Github), que cuida dessas coisas para mim. Se você só precisar suportar dispositivos de tela sensível ao toque, como telefones celulares, também pode tentar o Evento JQuery Mobile Taphold.

plugin jQuery. Apenas coloque $(expression).longClick(function() { <your code here> });. O segundo parâmetro é duração de retenção; O tempo limite padrão é de 500 ms.

(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);

eu criei Devent-ingestão de prisão longa (JavaScript puro de 0,5k) Para resolver isso, adiciona um long-press evento para o DOM.

Ouça a long-press sobre algum elemento:

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

Ouça a long-press com um específico elemento:

// 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);
});

Trabalha em aplicativos móveis IE9+, Chrome, Firefox, Safari e Híbrido (Cordova & Ionic no iOS/Android)

Demonstração

$(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;
    });
});

Demonstração

Para desenvolvedores de plataforma cruzada (Observe todas as respostas dadas até agora não funcionarão no iOS):

MouseUp/Down parecia funcionar bem Android - mas nem todos os dispositivos, isto é (Samsung Tab4). Não funcionou em nada iOS.

Mais pesquisas parecem que isso se deve ao elemento ter seleção e a ampliação nativa interrompe o ouvinte.

Este ouvinte de evento permite que uma imagem de miniatura seja aberta em um modal de bootstrap, se o usuário segurar a imagem por 500ms.

Ele usa uma classe de imagem responsiva, portanto, mostrando uma versão maior da imagem. Este pedaço de código foi totalmente testado (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)
});

A resposta do diodeu é incrível, mas impede que você adicione uma função OnClick, ela nunca executará a função Hold se você colocar um OnClick. E a resposta do RAZZAK é quase perfeita, mas ele executa a função de retenção apenas no MouseUp e, geralmente, a função é executada, mesmo que o usuário continue segurando.

Então, eu entrei para os dois e fiz isso:

$(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
});

Você pode definir o tempo limite para esse elemento no mouse para baixo e limpá -lo no mouse para cima:

$("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;
});

Com isso, cada elemento recebe seu próprio tempo limite.

Para navegadores móveis modernos:

document.addEventListener('contextmenu', callback);

https://developer.mozilla.org/en-us/docs/web/events/contextmenu

Você pode usar o Taphold da JQuery-Mobile. Inclua o jQuery-mobile.js e o código a seguir funcionará bem

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

O mais elegante e limpo é um plugin jQuery:https://github.com/untill/jquery.longclick/, também disponível como packacke:https://www.npmjs.com/package/jquery.longClick.

Em suma, você usa assim:

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

A vantagem deste plug -in é que, ao contrário de algumas das outras respostas aqui, os eventos de clique ainda são possíveis. Observe também que ocorre um clique longo, assim como um toque longo em um dispositivo, antes do mouseup. Então, isso é um recurso.

Para mim, é trabalho com esse código (com 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);

Você pode verificar o tempo para identificar clique ou pressione há muito tempo [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);
}
} 

assim?

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

Você pode usar jquery Toque em eventos. (Veja aqui)

  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 );
  });

Eu precisava de algo para eventos de teclado longpress, então escrevi isso.

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;
});
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top