JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<input id="button1" value="Only click">
<input id="button2" value="Only long click">
<input id="button3" value="Both">
CSS
input {
display: inline-block;
width: 10em;
height: 10em;
margin: 2em;
text-align: center;
}
JavaScript
(function() {
//Register a function with jquery to remove all classes from an element that starts with a certain string
$.fn.removeClassStartingWith = function (filter) {
$(this).removeClass(function (index, className) {
return (className.match(new RegExp("\\S*" + filter + "\\S*", 'g')) || []).join(' ')
});
return this;
};
//Register a function to handle long click/touch events
$.fn.longClick = function (longClickCallback, clickCallback = null, timeout = 1000) {
if (longClickCallback == null && clickCallback == null)
throw new Error("Neither longClickCallback nor clickCallback defined");
let _t = this; //Nailing this to _t for all following function contexts
//Struct to keep track of the state.
let state = {
started : false,
triggered : false,
timer : null,
clear : function () {
state.started = false;
state.triggered = false;
if (state.timer != null)
clearTimeout(state.timer);
state.timer = null;
}
}
//Disable native longpress touch handling on touch devices (like copy/paste)
$(_t).css({
'-webkit-touch-callout' : 'none',
'-webkit-user-select' : 'none',
'-khtml-user-select' : 'none',
'-moz-user-select' : 'none',
'-ms-user-select' : 'none',
'user-select' : 'none'
});
//Handling events
$(_t).on('mousedown mouseup mouseout touchstart touchend touchcancel touchmove', function(event) {
switch (event.type) {
case 'touchstart' :
case 'mousedown' :
if (state.started)
return; //Click handling alread in progress. A touch will trigger both touchstart and mousedown (but mousedown only after touchend)
state.clear(); //To be safe
state.started = true;
//starting a timer when to handle the long press
state.timer = setTimeout(function() {
//User pressed for long enough to handle the press
if (longClickCallback != null && state.started && !state.triggered)...