Suppose I have a basic HTML page with five text boxes and one button at the end.
Now I want to go to the next HTML element, let's say next TextBox (same as the Tab does), on press of key code 412 and on press of key code 417, I should be able to go back to the previous element (same as Shift + Tab).
Now I can not use Tab or you can say Tab key is absent on my keyboard. Any help?
Well the code to detect key press 开发者_如何学运维is below:
document.onkeyup = KeyCheck;
function KeyCheck()
{
var KeyID = event.keyCode;
document.Form1.KeyName.value = event.keyCode;
switch(KeyID)
{
case 412:
document.Form1.KeyName.value = "Rewind Pressed";
break;
case 417:
document.Form1.KeyName.value = "Forward Pressed";
break;
....................
}
Now I want to do the Next and Prev on Key code 412 and 417
First, build array with all the elements in the desired order:
var _arrElements = [ "myInput1", "myInput2", "myInput3" ];
Second, change your code to detect the textbox from which key was pressed, find its ID in the array and focus the proper textbox before or after it:
function KeyCheck(evt) {
if (typeof evt == "undefined" || !evt)
evt = window.event; //IE...
var KeyID = evt.which || evt.keyCode;
var flag = 0;
switch(KeyID) {
case 34:
flag = -1; //Backward
break;
case 33:
flag = 1; //Forward
break;
}
if (flag == 0)
return; //key is not relevant
var sender = evt.target || evt.srcElement;
if (!sender)
return; //key up did not come from valid element
var nIndex = -1;
for (var i = 0; i < _arrElements.length; i++) {
if (sender.id == _arrElements[i]) {
nIndex = i;
break;
}
}
if (nIndex < 0)
return; //key up did not come from valid textbox
var newIndex = nIndex + flag;
if (newIndex >= _arrElements.length)
newIndex = 0;
if (newIndex < 0)
newIndex = _arrElements.length - 1;
document.getElementById(_arrElements[newIndex]).focus();
}
Live test case with the complete code is available here: http://jsfiddle.net/yahavbr/vAh8R/
In the example I'm using Page Up
/Page Down
, no idea what keys produce the codes you gave.
Edit: you can put ID of every focusable element you want in the array, it doesn't have to be only textbox.
Wrap the elements in a div
and add a keypress
event handler to it.
This page has an example at the bottom: http://www.quirksmode.org/js/keys.html
You can access the previous and next DOM siblings (if any) with the previousSibling
and nextSibling
properties, the previous and next element siblings (if any) with the previousElementSibling
and nextElementSibling
properties. If the elements you want to move between aren't all sibling of each other, this becomes trickier. A JS library would be a big help, simplifying traversal.
You could also pre-process forms using the elements
property, creating a collection of inputs in tabIndex
order and keeping track of the current input, updating whenever the user presses the appropriate key or when an input gains or loses focus.
DOM based approach (untested, possiblyprobably buggy):
if (! Array.prototype.append) {
Array.prototype.append = function(arr) {
this.push.apply(this, arr);
}
}
if (! Array.prototype.each) {
Array.prototype.each = function(f) {
for (var i=0; i < this.length; ++i) {
f(this[i], i);
}
}
}
if (! Array.prototype.filter) {
Array.prototype.filter = function(f) {
var other = [];
if (!f) {
f = function (x) {return x;};
}
for (var i=0; i < this.length; ++i) {
if (f(this[i])) {
other.push(this[i]);
}
}
return other;
}
}
// call this on the form element
function keyNavigation(form, nextKey, prevKey, modifier) {
if (nextKey) {
nextKey = nextKey.toLowerCase();
} else {
nextKey = 'n';
}
if (prevKey) {
prevKey = prevKey.toLowerCase();
} else {
prevKey = 'p';
}
switch (modifier) {
case 'ctrlKey':
case 'altKey':
case 'metaKey':
break;
case 'ctrl':
case 'alt':
case 'meta':
modifier += 'Key';
break;
default:
modifier = 'ctrlKey';
break;
}
var inputs=[], assigned = [], unassigned=[], input, j=0;
for (var i=0; i < form.elements.length; ++i) {
input = form.elements[i];
if (input.tabIndex) {
j = input.tabIndex;
while(assigned[j]) {++j}
assigned[j] = input;
} else if (!input.disabled) {
unassigned.push(input);
}
}
inputs = assigned.filter();
inputs.append(unassigned);
inputs.each(function (input, keyedIdx) {
input.keyedIdx = keyedIdx;
});
var currIdx;
form.gotoNextInput = function() {
// if currIdx is undefined, comparison should be false
if (currIdx+1 < inputs.length) {
inputs[++currIdx].focus();
}
}
form.gotoPreviousInput = function() {
// if currIdx is undefined, comparison should be false
if (currIdx && currIdx > 0) {
inputs[++currIdx].focus();
}
}
form.addEventListener('keypress', function (evt) {
if (evt[modifier]) {
switch (String.fromCharCode(evt.keyCode).toLowerCase()) {
case nextKey:
evt.stopPropagation();
evt.preventDefault();
this.gotoNextInput();
return false;
case prevKey:
evt.stopPropagation();
evt.preventDefault();
this.gotoPreviousInput();
return false;
}
}
}, true);
// programmatic setting of focus above should invoke this
// handler. Wasteful, but not problematic.
form.addEventListener('focus', function (evt) {
if (typeof evt.target.keyedIdx == 'number') {
currIdx = evt.target.keyedIdx;
}
}, true);
form.addEventListener('blur', function (evt) {
delete currIdx;
}, true);
}
精彩评论