I am building a web app where I detect the headphones button event. I succeeded in capturing headphones button event when they are plugged in. Now I am trying to capture Bluetooth headphones next button event. Any help on this please?
Code for headphone button detection.
document.addEventListener('volumeupbutton', () => {
//Do something here
}, false);
I need something similar to this.
You can use keydown and keyup events for implementing the long press functionality.
// Imprementation of Long Press
const longPressTime = 1500;
let keyDownTimeout;
document.addEventListener('keydown', e => {
if (keyDownTimeout) {
return;
}
keyDownTimeout = setTimeout(() => {
// button was held for 1500ms, consider it a long-press
if (e.code === 'ArrowUp') {
console.log("Action Performed");
// do long-press action
} else {
console.log("Other action performed");
}
}, longPressTime);
});
document.addEventListener('keyup', e => {
clearTimeout(keyDownTimeout);
keyDownTimeout = 0;
});
Press any key
The above methods work for single key long press. Refer to KeyCode for key code.
Demo of above
I don't believe using the built-in volumeupbutton event will allow you to detect how long the click was, to determine if it should be treated as volume-up or skip-track. Instead you should be able to use the keyup/keydown events, combined with the keyCode property to determine if it is the volume button, like this:
const longPressTime = 1500;
let volumeUpButtonTimeout;
const volumeButtonKeyCode = 0; // you'll need to determine the key code
// cross platform way to get the key code
const getKeyCode = e => {
if (e.key !== undefined) {
return e.key;
} else if (e.keyIdentifier !== undefined) {
return e.keyIdentifier;
} else if (e.keyCode !== undefined) {
return e.keyCode;
}
}
document.addEventListener('keydown', e => {
if (getKeyCode(e) == volumeButtonKeyCode) {
volumeUpButtonTimeout = setTimeout(() => {
// button was held for 1500ms, consider it a long-press
// do long-press action
}, longPressTime)
}
});
document.addEventListener('keyup', e => {
if (getKeyCode(e) == volumeButtonKeyCode) {
clearTimeout(volumeUpButtonTimeout);
}
});
You could use this code to determine what keyCode corresponds to the volume up button:
document.addEventListener('keyup', e => {
console.log(e.keyCode);
});
Related
I am trying to stop a keydown event from repeating for a game. I am unable to use libraries due to it being part of a school project. I have tried most of the answers I can access but they don't work for my code, I also can't use MDN because it's blocked. Here is the code
window.addEventListener("keydown", function (e){
if (e.keyCode == 32) {
accelerateBy = -0.5
accelerate()
}
});
You may have to use some variable to save the state of you key. Here's an example:
let isKeyDown = false;
document.addEventListener("keydown", (event) => {
if (event.keyCode == 32) {
if (isKeyDown) { return; } // If key was already down, don't do anything
isKeyDown = true;
// do your stuff here
}
});
document.addEventListener("keyup", (event) => {
if (event.keyCode == 32) {
isKeyDown = false;
}
});
I'm kind of new to JS, I have searched the internet and I haven't got what I'm looking for, I want to run a function if the keys Shift and Enter were pressed, like a shortcut,
I have tried this but I think I killed JS with this code
document.addEventListener('keypress', function (e) {
if (e.key === 'Enter' + 'Shift') {
console.log("test");
}
});
anything would be helpful, thanks.
You can use e.shiftKey to see if shift is being pressed.
document.addEventListener('keypress', function(e) {
if (e.key === 'Enter' && e.shiftKey) {
console.log("test");
}
});
This is a pretty expandable solution because you can create shortcuts for many different keys.
const keysDown = {};
document.addEventListener('keydown', ({ key }) => {
keysDown[key] = true;
if (keysDown.Shift && keysDown.Enter) console.log("test");
});
document.addEventListener('keyup', ({ key }) => {
keysDown[key] = false;
});
So I'm trying something out, if you have two functions you want to call after the same key press like so:
var plus = function () {
document.addEventListener("keyup", function(e) {
if (/[+]/g.test(e.key)) {
console.log("plus");
}
})
}
plus();
var minus = function() {
document.addEventListener("keyup", function(e) {
if (/[-]/g.test(e.key)) {
console.log("minus");
}
});
}
minus();
function check() {
document.addEventListener("keyup", function(e) {
if(plus) {
if (e.keyCode == 13) {
console.log("enter pressed after plus");
plus = false;
minus = function() {
document.addEventListener("keyup", function(e) {
if (/[-]/g.test(e.key)) {
console.log("minus");
}
});
}
}
} else if(minus) {
if (e.keyCode == 13) {
console.log("enter pressed after minus");
minus = false;
plus = function () {
document.addEventListener("keyup", function(e) {
if (/[+]/g.test(e.key)) {
console.log("plus");
}
})
}
}
}
});
}
check();
If you press minus first then enter console.log("enter pressed after plus") always gets called first because of the code's order, even though what I want to do is that I want the enter to correspond to the key I'm pressing first, if I press plus first then I want console.log("enter pressed after plus") to get called, and if I press minus first then I want console.log("enter pressed after minus") to get called.
Any help would be appreciated and thanks in advance.
Oh also sorry about the stupid title, couldn't think of a better one.
To clean this up a bit (keep it DRY) you can move all the event handler logic into a single function and use a single listener.
To keep track of the last pressed key we can use a variable defined in the function's outer scope. And, update it after each event. Then, when "Enter" is pressed we can check what the last key was and log accordingly.
Also, the KeyboardEvent.keyCode property is depreciated. You should use KeyboardEvent.code property instead.
Example
const input = document.querySelector('input')
const log = document.getElementById('log')
function check() {
let lastKey = null
input.addEventListener('keyup', ({ key }) => {
if (['+', '-', 'Enter'].includes(key)) { // we only care about these keys
if (key === '+') log.textContent = 'plus'
if (key === '-') log.textContent = 'minus'
if (key === 'Enter') { // `Enter` was keyed, what was keyed last?
if (lastKey === '+') log.textContent = 'enter pressed after plus'
if (lastKey === '-') log.textContent = 'enter pressed after minus'
}
lastKey = key // current key becomes last key
}
})
}
check()
<input placeholder="Click here, then press and release a key." size="40">
<p id="log"></p>
My iframe game is reading the keyboard including space, but on some browsers (Firefox, Safari) pressing Space also scrolls my page down, that causes my game to partially go out of screen. Sometimes it seems the page even scrolls back up when some other keys are pressed...
My game handles keypresses on "keyup" event.
input.addEventListener("keyup", function (e) {
//game handles all keys including space here
}
Because of using keyup event, this answer is not suitable to prevent space ;
Pressing spacebar scrolls page down?
If I add this code, my game does not receive keyup events:
window.onkeydown = function(e) {
return !(e.keyCode == 32);
};
When I add this code above to parent html page, having ifreme, it only works if keyboard focus is clicked to parent html. When focus is inside iframe, the code does not work.
It seems above code fixed issue for Safari!
The onkeypress event fires the browser scrolling. You can call preventDefault in this event, and the keyup and keydown events will continue to fire as intended.
window.onkeypress = function(e) {
if (e.keyCode == 32) {
e.preventDefault();
}
};
window.onkeyup = function(e) {
console.log("Space key up!")
};
You need preventDefault
window.addEventListener('keydown', (e) => {
if (e.keyCode === 32) {
e.preventDefault();
}
});
See this codepen for a demo: https://codepen.io/xurei/pen/MWyveEp
You have to find the right window object first
function getIframeWindow(iframe_object) {
var doc;
if (iframe_object.contentWindow) {
return iframe_object.contentWindow;
}
if (iframe_object.window) {
return iframe_object.window;
}
if (!doc && iframe_object.contentDocument) {
doc = iframe_object.contentDocument;
}
if (!doc && iframe_object.document) {
doc = iframe_object.document;
}
if (doc && doc.defaultView) {
return doc.defaultView;
}
if (doc && doc.parentWindow) {
return doc.parentWindow;
}
return undefined;
}
var myFrame = document.getElementById('targetFrame');
var frame_win = getIframeWindow(myFrame);
and then add the listeners to stop the spacebar event from bubbling up.
if (frame_win) {
var preventSpace = (e) => {
if (e.keyCode === 32) {
e.preventDefault();
}
};
frame_win.addEventListener('keydown', preventSpace);
frame_win.addEventListener('keyup', preventSpace);
frame_win.addEventListener('keypress', preventSpace);
}
On Mac browsers, javascript does not receive keyup events for most keys (other modifier keys seem to be an exception) when the metakey is down. Use this jsfiddle to demonstrate (focus the result area and try something like cmd + x, the x will not receive a keyup event):
http://jsfiddle.net/mUEaV/
I've reproduced this in stable releases for Chrome, FF, Safari and Opera. The same thing does not seem to happen with the control key in Windows 7.
Is the OS hijacking the keyup event? This seems especially strange since commands that use the metakey such as save, find, cut, copy, etcetera all activate on keydown not on keyup, and can be hijacked by the javascript just fine.
It's simply not possible to get the onKeyUp events when meta is used, I learned today. Very unfortunate and difficult to work around. You'll have to emulate them some other way.
Edit: To clarify, this is only on Mac and occurs due to OS level handling of the event. It cannot be overridden. Sorry to be the bearer of bad news.
Although event.metaKey returns false, event.keyCode and event.key are still populated.
document.addEventListener('keyup', function(e) {
console.log(e.metaKey || e.key);
});
Click here then press the Command, Control, or Option keys.
Is the browser window retaining the focus when you press those keys? In windows you can get similar result when pressing windows+R or CTRL+ESC and similar key combinations that make browser to loose focus and that results in missed events.
While keyup events are indeed not available when the meta key is pressed, you can still get keydown events for all keys, as well as keyup events for the meta key itself.
This allows us to just simply keep track of the state of the meta key ourselves, like so:
let metaKeyDown = false;
window.addEventListener("keydown", event => {
if (event.key == 'Meta') { metaKeyDown = true; }
});
window.addEventListener("keyup", event => {
if (event.key == 'Meta') { metaKeyDown = false; }
});
By now additionally checking for the main key, plus cancelling the default behavior with Event.preventDefault() we can easily listen for key combinations (like here e.g. CMD+K) and prevent the browser from handling them:
let metaKeyDown = false;
window.addEventListener("keydown", event => {
if (event.key == 'Meta') { metaKeyDown = true; }
if (event.key == 'k' && metaKeyDown) {
event.preventDefault();
console.log('CMD+K pressed!');
}
});
window.addEventListener("keyup", event => {
if (event.key == 'Meta') { metaKeyDown = false; }
});
(Note the observation of the k key taking place already on keydown.)
Also, please be aware that when used incorrectly, this can break standard browser functionality (e.g. like CMD+C or CMD+R), and lead to poor user experience.
You can create an artificial keyup event by waiting for a certain period after the last keydown event. The only caveat is people will have different repeat rates on their os.
https://jsfiddle.net/u7t43coz/10/
const metaKeyCodes = ["MetaLeft", "MetaRight"];
const shiftKeyCodes = ["ShiftLeft", "ShiftRight"];
const ctrlKeyCodes = ["ControlLeft", "ControlRight"];
const altKeyCodes = ["AltLeft", "AltRight"];
const modifierKeyCodes = [
...metaKeyCodes,
...shiftKeyCodes,
...ctrlKeyCodes,
...altKeyCodes
];
// record which keys are down
const downKeys = new Set()
const artificialKeyUpTimes = {}
function onKeydown(e) {
downKeys.add(e.code);
// do other keydown stuff here
console.log("meta", e.metaKey, e.code, "down")
// check if metaKey is down
if (metaKeyCodes.some(k => downKeys.has(k))) {
downKeys.forEach(dk => {
// we want to exclude modifier keys has they dont repeat
if (!modifierKeyCodes.includes(dk)) {
// fire artificial keyup on timeout
if (!artificialKeyUpTimes[dk])
setTimeout(
() => fireArtificialKeyUp(dk, e),
500
);
artificialKeyUpTimes[dk] = Date.now();
}
});
}
}
function fireArtificialKeyUp(code, e) {
// if enough time has passed fire keyup
if (Date.now() - artificialKeyUpTimes[code] > 100) {
delete artificialKeyUpTimes[code];
//if key is still down, fire keyup
if (downKeys.has(code)) {
const eCode = isNaN(code) ? { code: code } : { keyCode: code };
document.dispatchEvent(
new KeyboardEvent("keyup", { ...e, ...eCode })
);
}
} else {
setTimeout(() => fireArtificialKeyUp(code, e), 100);
}
}
function onKeyup(e) {
downKeys.delete(e.code);
// do keyup stuff here
console.log("meta", e.metaKey, e.code, "up")
}
document.addEventListener("keydown", onKeydown)
document.addEventListener("keyup", onKeyup)