I am working on a game-webpage, and I need to know of a way to capture keyboard input, ie up, down, left right and feed that into my location variable but I don't want to use a text box, in my HTML code for input. I'm already using a element to draw my world. Is there any way that when the game is open on a tab, that all keyboard input apart from and the various browser operator keys will will be capturable without having to have the user click on a specific spot on the screen. I've a very limited experience with HTML, and only need a cone of answer as I am building the game in python in a way that it builds itself into HTML.
I am also using a timed loop, and need to be able to have an onkeypress event to be capturable inside the timed loop.
Which element should I use? Which properties of the element?
In order to capture your presses specifically inside your loop, you'll have to store the currently held keys somewhere, and use the document.onkeydown and document.onkeyup to change them.
var heldKeys = [];
document.onkeydown = function(ev) {
heldKeys.push(ev.keyCode);
}
document.onkeyup = function(ev) {
var i = heldKeys.indexOf(ev.keyCode);
if (i != -1) {
heldKeys.splice(i, 1);
}
}
Now inside your loop, you check the contents of heldKeys. You can just loop through it and act on each key.
Remember that the keyCodes won't correspond exactly to "a" "b" etc, they'll be ascii codes. And you may or may not run into browser compatibility issues.
Related
I've been using the following code in JavaScript for several months and it appears to work without issue, but I started to wonder why it works and whether or not it is a safe method.
The purpose is simply to keep track of the currently selected HTML element and not perform the function code triggered by an event if the user clicks again upon the currently selected element.
function elem_mouse_evt( evt )
{
if ( evt.currentTarget === elem_mouse_evt.e ) return;
elem_mouse_evt.e = evt.currentTarget;
/* ... */
}
This may be a rather stupid question on my part but why is this different than comparing two objects for equivalence? How does JavaScript make this comparison, since each represents a collection of values?
Thank you.
Addition I left out a very important point that came to mind while considering the posted answer, which is that the function property e has a larger purpose. There is a menu of actions that the user can choose to perform on the current selection and/or its content. I thought it would be more efficient to store the reference in the function property rather than traversing the DOM to search for it by one of its unique attributes. Is that a reasonable method?
The purpose is simply to keep track of the currently selected HTML element and not perform the function code triggered by an event if the user clicks again upon the currently selected element.
Rather than doing what you're asking (uniquely identifying an element), I'd flag that element in some way. One way to do that is to add something to its dataset. I'm guessing though that you'll want to change the styling of this selected element at some point though anyway so that users see it's already selected. In that case, we'll add a class.
// Add an event listener on the container for these elements.
// It's more efficient to have just one event listener, rather than thousands.
document.querySelector('.parent').addEventListener('click', (e) => {
// Ensure what's actually clicked meets the filter
if (!e.currentTarget.matches('.selectable')) {
return;
}
// If it's already selected, don't do anything else! (You can combine this with above.)
if (e.currentTarget.matches('.selected')) {
return;
}
e.currentTarget.classlist.add('selected');
// Perform your other actions here
});
Background:
I am writing a Chrome extension that programmatically replaces abbreviations with snippets of text. Like, it can auto-replace "brb" with "be right back".
The way (simplified to this question) I insert this snippet expansion is like this:
var newFullText = textBeforeAbbrev + expansionText + textAfterAbbrev;
textarea.value = newFullText; // OR
div.innerHTML = newFullText;
Problem:
The problem here is that although this correctly inserts the expanded text, the website does not catch it as an update to the textarea/div contents.
Some sites internally keep a track of textarea/div contents, updating it on input events. That means, if I do this expansion and submit the form, on some sites (like Facebook, Hipchat), this newFullText won't be registered - because it wasn't a user input event - so the website didn't catch it either!. So, the submitted value would be having the text prior to this expansion.
My attempts:
I've already tried firing the keydown and input events - on the concerned textareas - in this manner with NO luck at all:
function triggerKeypress(keyCode){
var ev = new Event("input");
ev.keyCode = keyCode;
this.dispatchEvent(ev);
}
My question:
Is these a way to achieve what I am requesting? Specifically:
Simulate a user keypress/keydown/input/whatever_necessary on the textarea/div/input element, so that the website internally catches it as an input/keypress(whatever event it is supposedly looking for), and updates its internal text, so that the submitted text correctly shows up
I'm looking for a native JS solution. My app is a Chrome extension so naturally I plan to support Chrome code, although cross-browser support is appreciated.
Minimum viable code sample:
Here's the zip file of the minimum code (11KB) you need to reproduce the issue. Please run it and try changing those two methods in the code to get them work, as stated in this question. I've confirmed the linked code does STILL NOT work on Hipchat, Facebook posts and comments. More details inside file README.txt.
How to use it?
1. Open Hipchat team chat, or Facebook.
2. Type "brb" into the team chat box/Facebook post/comments.
3. Press Shift+Space.
4. The expanded text "be right back" would clearly show up inside the textarea.
5. Press enter.
6. The submitted value will show up as "brb" instead of "be right back"
This question is not a duplicate question: please note that the other questions are about:
1. firing a keydown that fires their own custom handler, and which naturally do NOT work here
2. are way too out-dated and have become convoluted over time
3. use deprecated methods like Document.createEvent
Please let me know for more clarification. Thanks!
I have deduced that the spell check function, as handled by most browsers, only works when the user inputs text and then moves to the next word. I have also deduced that you can "query" the spellchecker by simply move the cursor through a word (i.e clicking the first word and then scrolling down).
I have a tool that takes input text and then produces it in an altered form for the user to see. I want the output text to be subjected to the spell checker.
I am aware of the fact that I could use a javascript spellchecking tool, but I'd like to avoid that if I can get the native tool to work (in large part because users can then define their native spell checker however they'd like).
Two specific questions:
1) Is there any easy way to trigger the spell checker to query every word in an element? Setting spellcheck to "true" does not do this.
2) I think my next best option is to programmatically run the cursor of the list of words, is there a good approach for doing this?
I have the same question. I solved this by focussing on an element and a timeout. It's cerainly not the (best) way to go, but it does it's job.
What it does: it get's the elements (all elements have the not-focussed class on them). While looping through (in reverse, bottom->up), it waits 20 miliseconds in order for the spellchecker to execute.
function enableSpellcheck()
{
setTimeout(function () {
var items = $(".not-focussed").reverse();
if(items.length > 0)
{
var target = items[0];
$(target).focus();
$(target).removeClass("not-focussed");
enableSpellcheck();
}
}, 20);
}
I'm trying to create code that allows me to press a button on the keyboard and have a corresponding circle appear on the screen. The position would be relevant to the key pressed. For example, the letter a would be different from b. Here's what I have so far:
<script>
$(document).bind('keyup',function(event){
var keyCode = event.keyCode;
var theObjectCoorespondingToTheKeyTheyPressed = _.where(keyPlacementMap,{keycode:keyCode});
theObjectCoorespondingToTheKeyTheyPressed = theObjectCoorespondingToTheKeyTheyPressed[0];
console.log(event);
})
</script>
I'll change the variable names eventually; it's just useful for me to have them named as such for now.
I'm also using jquery and underscore, and I have an array that holds all the keycodes, as well as a randomized x and y variable.
Add x/y positions to your keymap. Two separate classes is the best way to accomplish this because it allows you style the selected and unselected keys anyway you like (including hide and show them)
I did a small QWERTY sample here
http://jsbin.com/ivuseh/2
CodeView:
http://jsbin.com/ivuseh/2/edit
The '.button' class can style pressed keys however you like bigger, colorized, visible. In the example I'm redrawing all buttons on each keypress which isn't necessary. It pretty easy to separate those functions to optimize.
Is there a way to add keyboard navigation to links with just css3, without js or any js library? specifically, I have created a pure css3 lightbox effect with a bunch of images but I want to navigate between images using left and right keys without clicking anywhere on the screen and use escape to get the effect of "cancel" button (similar to Close)
What you are asking for is literally impossible with Cascading Style Sheets , You can animate your sequences for timing or do stuff like animating , transitions with CSS but you cannot do what you want to do with CSS only!.
Reasons
Cascading Style Sheets were made for making the visual elements of the page and not the UX
Css has no method for interaction with Keyboard.
You can either add a little bit of javascript for making this happen . But as you don't wanna use javascript you are stuck !
Checkbox hack
With checkbox radio box something like this is attainable but then again the focus initially
requires to be brought . which can be done using autofocus attribute ..
So this fiddle should solve your issue.
http://jsfiddle.net/darkyen/NUtnX/
But i want to warn you before hand any "blur" will cause this to fail. so the better javascript code varient is listed below
JavaScript Code
The javascript code for achieving what you want will contain very minimal javascript
Say your markup is
So you can simply assign a lil javascript
(function(){
var slide = 0, // Current slide
max = 10, // Maximum Number of slides
ele = document.getElementById("show");
document.addEventListener('keydown',function(e){
e.preventDefault();
e.stopPropagation(); // To stop more event stuff and default behaviour
key = e.keyCode; // To find out what key is this
if( key === 39 ){
// Right arrow
// Aha we incremented the value!
slide++;
slide %= (max+1);
// Increase the value of slide by 1 and keep em in limits
}else if( key === 37){
slide = (--slide >= 0)?slide: ( slide + max );
// Will decrement the slide value by 1 and if they are less then 0 then will cycle it to the last slide
}
ele.className.replace(/slide[0-9]/gi,'slide'+slide);
// wasn't hard now was it ?
});
})();
The minimal javascript above will do the task of changing your slides or you can always see the source code of impress.js