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.
Related
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; });
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
})
i have scollable area , i want to user long press and then scroll to scroll that area.
is there any way to detect mouse / touch event movement after long press so that i may do above functionality
see : http://liveweave.com/ggfAdD
please help i am stucked up
belwo i code of longpress, what top add code to make it work where user long press and move up / down
(function($) {
$.fn.longpress = function(longCallback, shortCallback, duration) {
if (typeof duration === "undefined") {
duration = 500;
}
return this.each(function() {
var $this = $(this);
// to keep track of how long something was pressed
var mouse_down_time;
var timeout;
// mousedown or touchstart callback
function mousedown_callback(e) {
mouse_down_time = new Date().getTime();
var context = $(this);
// set a timeout to call the longpress callback when time elapses
timeout = setTimeout(function() {
if (typeof longCallback === "function") {
longCallback.call(context, e);
} else {
$.error('Callback required for long press. You provided: ' + typeof longCallback);
}
}, duration);
}
// mouseup or touchend callback
function mouseup_callback(e) {
var press_time = new Date().getTime() - mouse_down_time;
if (press_time < duration) {
// cancel the timeout
clearTimeout(timeout);
// call the shortCallback if provided
if (typeof shortCallback === "function") {
shortCallback.call($(this), e);
} else if (typeof shortCallback === "undefined") {
;
} else {
$.error('Optional callback for short press should be a function.');
}
}
}
// cancel long press event if the finger or mouse was moved
function move_callback(e) {
clearTimeout(timeout);
}
// Browser Support
$this.on('mousedown', mousedown_callback);
$this.on('mouseup', mouseup_callback);
$this.on('mousemove', move_callback);
// Mobile Support
$this.on('touchstart', mousedown_callback);
$this.on('touchend', mouseup_callback);
$this.on('touchmove', move_callback);
});
};
}(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
}
How can I track the browser idle time? I am using IE8.
I am not using any session management and don't want to handle it on server side.
Here is pure JavaScript way to track the idle time and when it reach certain limit do some action:
var IDLE_TIMEOUT = 60; //seconds
var _idleSecondsTimer = null;
var _idleSecondsCounter = 0;
document.onclick = function() {
_idleSecondsCounter = 0;
};
document.onmousemove = function() {
_idleSecondsCounter = 0;
};
document.onkeypress = function() {
_idleSecondsCounter = 0;
};
_idleSecondsTimer = window.setInterval(CheckIdleTime, 1000);
function CheckIdleTime() {
_idleSecondsCounter++;
var oPanel = document.getElementById("SecondsUntilExpire");
if (oPanel)
oPanel.innerHTML = (IDLE_TIMEOUT - _idleSecondsCounter) + "";
if (_idleSecondsCounter >= IDLE_TIMEOUT) {
window.clearInterval(_idleSecondsTimer);
alert("Time expired!");
document.location.href = "logout.html";
}
}
#SecondsUntilExpire { background-color: yellow; }
You will be auto logged out in <span id="SecondsUntilExpire"></span> seconds.
This code will wait 60 seconds before showing alert and redirecting, and any action will "reset" the count - mouse click, mouse move or key press.
It should be as cross browser as possible, and straight forward. It also support showing the remaining time, if you add element to your page with ID of SecondsUntilExpire.
The above code should work fine, however has several downsides, e.g. it does not allow any other events to run and does not support multiply tabs. Refactored code that include both of these is following: (no need to change HTML)
var IDLE_TIMEOUT = 60; //seconds
var _localStorageKey = 'global_countdown_last_reset_timestamp';
var _idleSecondsTimer = null;
var _lastResetTimeStamp = (new Date()).getTime();
var _localStorage = null;
AttachEvent(document, 'click', ResetTime);
AttachEvent(document, 'mousemove', ResetTime);
AttachEvent(document, 'keypress', ResetTime);
AttachEvent(window, 'load', ResetTime);
try {
_localStorage = window.localStorage;
}
catch (ex) {
}
_idleSecondsTimer = window.setInterval(CheckIdleTime, 1000);
function GetLastResetTimeStamp() {
var lastResetTimeStamp = 0;
if (_localStorage) {
lastResetTimeStamp = parseInt(_localStorage[_localStorageKey], 10);
if (isNaN(lastResetTimeStamp) || lastResetTimeStamp < 0)
lastResetTimeStamp = (new Date()).getTime();
} else {
lastResetTimeStamp = _lastResetTimeStamp;
}
return lastResetTimeStamp;
}
function SetLastResetTimeStamp(timeStamp) {
if (_localStorage) {
_localStorage[_localStorageKey] = timeStamp;
} else {
_lastResetTimeStamp = timeStamp;
}
}
function ResetTime() {
SetLastResetTimeStamp((new Date()).getTime());
}
function AttachEvent(element, eventName, eventHandler) {
if (element.addEventListener) {
element.addEventListener(eventName, eventHandler, false);
return true;
} else if (element.attachEvent) {
element.attachEvent('on' + eventName, eventHandler);
return true;
} else {
//nothing to do, browser too old or non standard anyway
return false;
}
}
function WriteProgress(msg) {
var oPanel = document.getElementById("SecondsUntilExpire");
if (oPanel)
oPanel.innerHTML = msg;
else if (console)
console.log(msg);
}
function CheckIdleTime() {
var currentTimeStamp = (new Date()).getTime();
var lastResetTimeStamp = GetLastResetTimeStamp();
var secondsDiff = Math.floor((currentTimeStamp - lastResetTimeStamp) / 1000);
if (secondsDiff <= 0) {
ResetTime();
secondsDiff = 0;
}
WriteProgress((IDLE_TIMEOUT - secondsDiff) + "");
if (secondsDiff >= IDLE_TIMEOUT) {
window.clearInterval(_idleSecondsTimer);
ResetTime();
alert("Time expired!");
document.location.href = "logout.html";
}
}
The refactored code above is using local storage to keep track of when the counter was last reset, and also reset it on each new tab that is opened which contains the code, then the counter will be the same for all tabs, and resetting in one will result in reset of all tabs. Since Stack Snippets do not allow local storage, it's pointless to host it there so I've made a fiddle:
http://jsfiddle.net/yahavbr/gpvqa0fj/3/
Hope this is what you are looking for
jquery-idletimer-plugin
Too late to reply, but this might help someone to write clean and practical solution. This is an ideal solution, when you do not need to display time left for session expire. Good to ignore setInterval(), which keeps on running the script through out the application running time.
var inactivityTimeOut = 10 * 1000, //10 seconds
inactivitySessionExpireTimeOut = '';
setSessionExpireTimeOut();
function setSessionExpireTimeOut () {
'use strict';
clearSessionExpireTimeout();
inactivitySessionExpireTimeOut = setTimeout(function() {
expireSessionIdleTime();
}, inactivityTimeOut);
}
function expireSessionIdleTime () {
'use strict';
console.log('user inactive for ' + inactivityTimeOut + " seconds");
console.log('session expired');
alert('time expired');
clearSessionExpireTimeout();
document.location.href = "logout.html";
}
function clearSessionExpireTimeout () {
'use strict';
clearTimeout(inactivitySessionExpireTimeOut);
}
Running example: Timeout alert will be popped up in 10 seconds
Here's an approach using jquery as I needed to preserve existing keyboard events on the document.
I also needed to do different things at different idle times so I wrapped it in a function
var onIdle = function (timeOutSeconds,func){
//Idle detection
var idleTimeout;
var activity=function() {
clearTimeout(idleTimeout);
console.log('to cleared');
idleTimeout = setTimeout(func, timeOutSeconds * 1000);
}
$(document).on('mousedown mousemove keypress',activity);
activity();
}
onIdle(60*60,function(){
location.reload();
});
onIdle(30,function(){
if(currentView!=='welcome'){
loadView('welcome');
}
});
I needed a similar thing and created this :https://github.com/harunurhan/idlejs
It simple, configurable and powerful in a way, without any dependencies. Here's an example.
import { Idle } from 'idlejs/dist';
// with predefined events on `document`
const idle = new Idle()
.whenNotInteractive()
.within(60)
.do(() => console.log('IDLE'))
.start();
You can also use custom event targets and events
const idle = new Idle()
.whenNot([{
events: ['click', 'hover'],
target: buttonEl,
},
{
events: ['click', 'input'],
target: inputEl,
},
])
.within(10)
.do(() => called = true)
.start();
(Written in typescript and compiled to es5)