I want the user to be able to touch and hold a button, and after a certain period of time, a function is called.
E.g. the button text starts as black, turns orange after 0.2s of pressing, and then green after 0.5s of pressing. If it is green, a function, myFunction(), is triggered.
I have made a start on it, more help would be appreciated. Thanks :)
var btn = document.getElementById("pressBtn");
var pressedTime = 0;
var elaspedHoldTime;
btn.onmousedown = function() {
if (pressedTime != 0) {
pressedTime = performance.now();
} else {
elaspedHoldTime = performance.now() - pressedTime;
}
if (elaspedHoldTime > 200) {
btn.style.color = "orange";
}
if (elaspedHoldTime > 1000) {
btn.style.color = "green";
}
};
btn.addEventListener("mouseup", function() {
elaspedHoldTime = performance.now() - pressedTime;
btn.style.color = "black";
if (elaspedHoldTime > 500) {
console.log("Call Function Here");
}
pressedTime = 0;
elaspedHoldTime = 0;
});
<button id="btn">Button Text</button>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
(It also has a bug for some reason)
CodePudding user response:
If you're making it for a touchscreen, you need to use TouchEvents:
ontouchstart -> when a target is being pressed by a finger
ontouchmove -> the active finger moves off the target
ontouchcancel -> when the the target has lost focus of a touch event
ontouchend -> lifting the finger off of the target
MouseEvents are reserved for mouse / trackpad-controlled devices, such as Computers.
TouchEvents are reserved for touch-screen devices, such as tablets and phones.
Also read this answer for code.
CodePudding user response:
You can use for that mousedown
and setTimeout
in Javascript
in setTimeout first arguement is what function must be run and second is when it should run,
in Javscript setTimeout 1000 is 1 second in your case
0.5s = 500
0.2s = 200
I also used
mouseup
to back to normal the button styling
const btn = document.querySelector(".btn")
let pressed = false
let pressTimer;
const triggerButton = () => {
pressed = true
if (pressed) {
pressTimer = setTimeout(() => {
btn.className = 'btn orange'
}, 200)
pressTimer = setTimeout(() => {
btn.className = 'btn red'
console.log("Triggered")
}, 500)
}
}
btn.addEventListener("mouseup", () => {
pressed = false
window.clearInterval(pressTimer)
btn.className = 'btn'
})
btn.addEventListener("mousedown", triggerButton)
.btn.orange {
background: orange;
}
.btn.red {
background: red;
}
<button class="btn">Click</button>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Updated: If user releases early, clearTimeout appears
CodePudding user response:
mousedown
, mouseup
, touchstart
, touchend
triggers just once when the key is pressed.
To check, if the user is still holding it, you need to check for a truly variable inside a setTimeout()
function-call or a setInterval()
-function-call that only runs when it's pressed.
For example:
let pressed = false;
button.addEventListener("mousedown", () => {
pressed = true;
setTimeout(() => {
if (pressed) { ... }
}, 200);
});
button.addEventListener("mouseup", () => { pressed = false; });
As there is already an answer with setTimeout()
, here is another solution with setInterval()
.
let vars = {
interval: null, // used to store the interval id
start: 0, // changes to Date.now() on every start.
// used to avoid myFunction be called more than once per "hold"
myFunctionCalled: false
}, myFunction = () => console.log("Yes...?");
button.addEventListener("mousedown", (event) => {
// avoid start w/ rightclick
if (event.which == 1) {
vars.start = Date.now();
vars.myFunctionCalled = false;
vars.interval = setInterval(() => {
let dur = Date.now() - vars.start;
if (dur > 1000) {
button.style.color = "green";
if (!vars.myFunctionCalled) {
vars.myFunctionCalled = true;
myFunction();
}
} else if (dur > 500) {
button.style.color = "orange";
} else if (dur > 100) {
button.style.color = "red";
}
}, 10);
}
});
// using window, so the user can move the mouse
window.addEventListener("mouseup", (event) => {
// checking again for the mouse key, to avoid disabling it on rightlick
if (vars.interval && event.which == 1) {
// stop the interval and reset the color to default
clearInterval(vars.interval);
button.style.color = "";
vars.interval = null;
}
})
<button id="button">Hold me</button>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>