While mousedown JS - javascript

I'm trying to run a function while mousedown but for the life of me I can't get it to work while holding down but everything works by just clicking. I'm trying to change color of countries on a map as I hold down.
Here's my code:
var int;
var mouseStillDown = false;
function mousedown(geography)
{ console.log('mousedown '+mousedownID);
mouseStillDown = true;
int = setInterval( performWhileMouseDown(geography), 100);
}
function mouseup()
{
clearInterval(int);
mouseStillDown = false;
}
function mouseout()
{
clearInterval(int);
}
function performWhileMouseDown(geography)
{
if (!mouseStillDown)
{console.log('error');}
if (mouseStillDown) {
if(data[geography.id])
{
data[geography.id] ++;
}else
{
data[geography.id] = 1;
}
var m = {};
m[geography.id] = color(data[geography.id]);
map.updateChoropleth(m);
}
/* if (mouseStillDown)
{ setInterval(performWhileMouseDown(geography), 100); }*/
}

You could try to use mousemove instead, mousedown will only fire once.
var mouseDown = false;
window.addEventListener('mousedown', function() { mouseDown = true })
window.addEventListener('mouseup', function() { mouseDown = false })
window.addEventListener('mousemove', function() {
if (!mouseDown) {
return;
}
// perform while mouse is moving
})

here's what worked for me
var timeout ;
function mouseDown(geography){
timeout = setInterval( function(){
if(data[geography.id]){
data[geography.id] ++;
}else{
data[geography.id] = 1;
}
var m = {};
m[geography.id] = color(data[geography.id]);
map.updateChoropleth(m);}, 100);
return false;
}
function mouseUp(geography){
clearInterval(timeout);
return false;
}

The two conditions for your event are that the code executes every time there is an update in mouse position AND the mouse button is pressed.
Addressing the first part can be done with the 'mousemove' event, which fires when the mouse is moved over the element.
The second filter can be solved, by checking the mouse event, on if the button is pressed. If not, we don't execute the following code.
window.addEventListener('mousemove', function() { // Attach listener
if (event.buttons == 0) // Check event for button
return; // Button not pressed, exit
// perform while mouse is moving
})

Related

Vanilla JS Swipe Function Now Overrides Links/Expected Behaviour

I have written a detect swipe left or right script; it has one unintended consequence. Links that reside within the swipeable container are no longer clickable.
I was wondering if anyone had any solutions they could point me to or any thoughts to experiment with my code.
I have tried:
Adding/toggling with event.preventDefault() within the Pointer Events
Looking at other get gesture type scripts, they include a distance threshold. If it is does not meet the threshold, I remove all event listeners. Adding this creates an unexpected result of working, only if you click the button twice.
Find the clickable elements within the container such as a span a , add an incremental click event listener then change the window location ref. Kinda works, but when you swipe near the span; the selection takes over and swipe actions stop. Experimenting with css touch-action: none or user-select:none have not improved the experience. It feels like I am breaking the default behaviour and reinventing the wheel.
link to a demo here on JS Bin
JS code here
window.addEventListener('load', () => {
let test = new getSwipeX({
elementId: 'container'
});
// previous attempt - adding a click on top of the browser default
let grabBtn = document.getElementsByClassName('button')[0];
grabBtn.addEventListener('click', (e) => {
window.location.href = 'www.google.co.uk'
});
})
function getSwipeX({elementId}) {
this.e = document.getElementsByClassName(elementId)[0];
this.initialPosition = 0;
this.lastPosition = 0;
this.threshold = 200;
this.diffInPosition = null;
this.diffVsThreshold = null;
this.gestureState = 0;
this.getTouchStart = (event) => {
event.stopPropagation();
if (window.PointerEvent) {
this.e.setPointerCapture(event.pointerId);
}
return this.initalTouchPos = this.getGesturePoint(event);
}
this.getTouchMove = (event) => {
event.stopPropagation();
return this.lastPosition = this.getGesturePoint(event);
}
this.getTouchEnd = (event) => {
event.stopPropagation();
if (window.PointerEvent) {
this.e.releasePointerCapture(event.pointerId);
}
this.doSomething();
this.initialPosition = 0;
}
this.getGesturePoint = (event) => {
this.point = event.pageX
return this.point;
}
this.whatGestureDirection = (event) => {
this.diffInPosition = this.initalTouchPos - this.lastPosition;
this.diffVsThreshold = Math.abs(this.diffInPosition) > this.threshold;
(Math.sign(this.diffInPosition) > 0) ? this.gestureState = 'L' : (Math.sign(this.diffInPosition) < 0) ? this.gestureState = 'R' : this.gestureState = 'N';
return [this.diffInPosition, this.diffVsThreshold, this.gestureState];
}
this.doSomething = (event) => {
let [gestureDelta,gestureThreshold,gestureDirection] = this.whatGestureDirection();
// USE THIS TO DEBUG
console.log(gestureDelta,gestureThreshold,gestureDirection);
if (gestureThreshold) {
(gestureDirection == 'L') ? console.log('Left') : console.log('Right');
} else {
this.e.removeEventListener('pointerdown', this.getTouchStart, true);
this.e.removeEventListener('pointermove', this.getTouchMove, true);
this.e.removeEventListener('pointerup', this.getTouchEnd, true);
this.e.removeEventListener('pointercancel', this.getTouchEnd, true);
}
}
if (window.PointerEvent) {
this.e.addEventListener('pointerdown', this.getTouchStart, true);
this.e.addEventListener('pointermove', this.getTouchMove, true);
this.e.addEventListener('pointerup', this.getTouchEnd, true);
this.e.addEventListener('pointercancel', this.getTouchEnd, true);
}
}

keyUp is triggering without keyPress

I am trying to have an event trigger if a key is held for a certain amount of time, not doing so if the user releases the key before the interval is over.
const characters = /([AEIOUYNCaeiouync!\\?\\"])/g;
var poppedUp = false;
$(document).ready(function () {
checkLetter();
});
function checkLetter() {
var interval;
$(document).on('keypress', function(e) {
if (interval == null && characters.test(String.fromCharCode(e.keyCode))) {
console.log('keypress');
interval = setInterval(function() {
popUp();
called = true;
}, 400);
}
}).keyup(function(e) {
clearInterval(interval);
console.log('keyup');
poppedUp = false;
interval = null;
});
}
function popUp() {
if (!poppedUp) {
document.querySelector(".modal-popup").style.display = "flex";
poppedUp = true;
}
document.addEventListener('click', function()
{
document.querySelector(".modal-popup").style.display = "none";
});
}
The first time I press a key, the console logs keyPress and keyUp properly. The second time (if I just press and immediately release), it only logs keyUp. This pattern then repeats. Here are the console logs. With two keyup events for every one keypress.

variable changing to true before setInterval is finished

showMoves is a function made to show flashing for a simon game.
When the flashing lights are over I clear the interval to stop it and then I set game.playerTurn to true so I can click on colors, but game.playerTurn is changing to true as soon as showMoves is activated.
I want game.playerTurn to stay false until the showMoves function is finished showing flashing.
Here are the functions I'm using game.playerTurn in -
game.playerTurn = false;
//for flashing lights
function showMoves() {
let i = 0;
const start = setInterval(function () {
if (i >= game.computerMoves.length) {
clearInterval(start);
game.playerTurn = true;
return;
}
const move = game.computerMoves[i];
setLight(move, true);
setTimeout(setLight.bind(null, move, false), 1000); //Using bind to preset arguments
i++;
}, 2000);
}
function setLight(color, isOn) {
if (isOn) {
sounds[color.id].play();
}
color.style.backgroundColor = isOn ? colors[0].get(color) : colors[1].get(color);
}
//compareMoves is fired everytime I click on a color
function compareMoves(e) {
if (e === game.computerMoves[game.counter]) {
game.counter++;
//This is if all the moves were chosen correctly
if (game.playerMoves.length === game.computerMoves.length && e === game.computerMoves[game.computerMoves.length - 1]) {
simonHTML.displayScore.textContent = ++game.score;
game.playerTurn = false;
resetMoves();
randomMoves(++game.turn);
showMoves();
game.counter = 0;
}
} else if (game.strict) {
//if your move was wrong do this
} else {
game.playerMoves = [];
game.counter = 0;
game.playerTurn = false;
showMoves();
return false;
}
}
I'd appreciate any help with this. Here is a link to the game and all the code https://codepen.io/icewizard/pen/JLBpNQ
Where are you setting game.playerTurn back to false?
function showMoves() {
game.playerTurn = false;
let i = 0;
const start = setInterval(function() {
if (i >= game.computerMoves.length) {
clearInterval(start);
game.playerTurn = true;
return;
}
const move = game.computerMoves[i];
setLight(move, true);
setTimeout(setLight.bind(null, move, false), 1000); //Using bind to preset arguments
i++;
}, 2000);
}
Seems to work for me in the codepen example you provided

Continuously do something on jstree using mousedown

How can I modify the code below to continually scroll the objects when mouse is on hold? This code is fine with clicks.
.on("click.jstree", ".down-arrow", $.proxy(function (e) {
var obj = this.get_element(e.target);
obj["page_num"] += 1;
obj["arrow"] = true;
this.draw_next(obj);
}, this))
I tried using mousedown.jstree and setInterval() but it didn't worked.
.on("mousedown.jstree", ".down-arrow", $.proxy(function (e) {
var interval;
interval = setInterval (function () {
var obj = this.get_element(e.target);
obj["page_num"] += 1;
obj["arrow"] = true;
this.draw_next(obj);
}, 50);
}, this))
.on("mouseup", ".down-arrow", $.proxy(function (e)) {
clearInterval(interval);
}, this))
Set a flag, then use a while() loop to keep doing whatever you need to do. Then eventually set the flag back to false!
// set a flag
var mouseIsDown = false;
// create function to do "stuff" when mouse is down
function mouseDownAction(){
while(mouseIsDown){
// do some code
}
}
// set event listener to set flag to true and fire function
$(some_selector).on('mousedown', function(){
mouseIsDown = true;
mouseDownAction();
});
// change flag to false on mouseup
$(some_selector).on('mouseup',function(){ mouseIsDown = false; });

Tap event firing X times a second in jquery

I'm trying to make touch controls for a little game I'm writting with the help of jquery. But i just can't figure out how to write a function that basicly does the same thing that happens when you keep a key pressed.
Could you please help me?
PS. its not originaly my code source
jQuery.fn.mousehold = function(timeout, f) {
if (timeout && typeof timeout == 'function') {
f = timeout;
timeout = 100;
}
if (f && typeof f == 'function') {
var timer = 0;
var fireStep = 0;
return this.each(function() {
jQuery(this).mousedown(function() {
fireStep = 1;
var ctr = 0;
var t = this;
timer = setInterval(function() {
ctr++;
f.call(t, ctr);
fireStep = 2;
}, timeout);
})
clearMousehold = function() {
clearInterval(timer);
if (fireStep == 1) f.call(this, 1);
fireStep = 0;
}
jQuery(this).mouseout(clearMousehold);
jQuery(this).mouseup(clearMousehold);
})
}
}
$.fn.extend({
disableSelection: function() {
this.each(function() {
this.onselectstart = function() {
return false;
};
this.unselectable = "on";
$(this).css('-moz-user-select', 'none');
$(this).css('-webkit-user-select', 'none');
});
}
});
Well the question is, how often do you want to check for a change in user input. You are quite limited when it comes to the resolution of a timer in JS. Although be aware that everything is running in sequence and thus events are queued and potentially sum up. This is especially true for setInterval() as it rigorously queues new events, even when previously triggered events were not yet processed.
Something like this works:
var pressed; // flag for continous press between mousedown and timer-events
var duration; // number of times the timer fired for a continous mousedown
var timeout; // reference to timer-event used to reset the timer on mouseup
$(document).mousedown = function(){
pressed = true;
handleMousedown(false);
}
function handleMousedown(continued){
if(pressed){ // if still pressed
if(continued){ // and fired by the timer
duration++;
// measure time, use duration
// do anything
}
timeout = setTimeout('handleMousedown(true)', 100); // wait for another 100ms then repeat
}
}
$(document).mouseup = function() {
// do sth on mouseup
pressed = false; // reset flag for continous mousedown
clearTimeout(timeout); // abandon the timer
}
$(document).mouseout = function() { // $(document).mouseenter = function(){
// do sth on mouse leave or mouse entering again according to how your game should behave
pressed = false; // reset flag for continous mousedown
clearTimeout(timeout); // abandon the timer
}

Categories