HTML/Javascript-停止左/右箭头更改下拉菜单选项
我正在用输入网格创建一个web表单,用于在Django中创建对象 似乎当焦点位于下拉菜单上时,向上和向左箭头选择上一项,右/向下箭头选择下一项HTML/Javascript-停止左/右箭头更改下拉菜单选项,javascript,html,drop-down-menu,Javascript,Html,Drop Down Menu,我正在用输入网格创建一个web表单,用于在Django中创建对象 似乎当焦点位于下拉菜单上时,向上和向左箭头选择上一项,右/向下箭头选择下一项 我想使用左/右箭头在网格上向左或向右移动焦点(有点像excel)。我是否可以禁止左/右箭头更改菜单选项(同时保留向上/向下箭头的功能)?更改控件的默认行为有时会让用户感到沮丧。但在其他情况下,用户希望它像excel一样工作(如您的情况:) 您可以这样做: var selects = document.getElementsByTagName('selec
我想使用左/右箭头在网格上向左或向右移动焦点(有点像excel)。我是否可以禁止左/右箭头更改菜单选项(同时保留向上/向下箭头的功能)?更改控件的默认行为有时会让用户感到沮丧。但在其他情况下,用户希望它像excel一样工作(如您的情况:) 您可以这样做:
var selects = document.getElementsByTagName('select');
for (var i = 0; i < selects.length; i++){
selects[i].addEventListener('keydown',function(e){
var key = e.which || e.keyCode;
if(key == 37){
var previousSibling = this.previousSibling;
while(previousSibling && previousSibling.nodeType != 1) {
previousSibling = previousSibling.previousSibling
}
previousSibling.focus();
e.preventDefault();
}else if(key === 39){
var nextSibling = this.nextSibling;
while(nextSibling && nextSibling.nodeType != 1) {
nextSibling = nextSibling.nextSibling
}
nextSibling.focus();
e.preventDefault();
}
})
}
.addEventListener('keydown', function (event) {
switch (event.which || event.keyCode) {
case 37: // left arrow
case 39: // right arrow
event.preventDefault();
ensurePreventDefault(this);
break;
}
});
var-selects=document.getElementsByTagName('select');
对于(变量i=0;i
键37=← 关键39是→.e.preventDefault()代码>阻止您按下的键的默认行为
更改控件的默认行为有时会让用户感到沮丧。但在其他情况下,用户希望它像excel一样工作(如您的情况:)
您可以这样做:
var selects = document.getElementsByTagName('select');
for (var i = 0; i < selects.length; i++){
selects[i].addEventListener('keydown',function(e){
var key = e.which || e.keyCode;
if(key == 37){
var previousSibling = this.previousSibling;
while(previousSibling && previousSibling.nodeType != 1) {
previousSibling = previousSibling.previousSibling
}
previousSibling.focus();
e.preventDefault();
}else if(key === 39){
var nextSibling = this.nextSibling;
while(nextSibling && nextSibling.nodeType != 1) {
nextSibling = nextSibling.nextSibling
}
nextSibling.focus();
e.preventDefault();
}
})
}
.addEventListener('keydown', function (event) {
switch (event.which || event.keyCode) {
case 37: // left arrow
case 39: // right arrow
event.preventDefault();
ensurePreventDefault(this);
break;
}
});
var-selects=document.getElementsByTagName('select');
对于(变量i=0;i
键37=← 关键39是→.
e.preventDefault()代码>阻止您按下的键的默认行为
虽然它会执行要求的操作,但在Firefox中不起作用。这主要是因为事件。preventDefault
不会阻止← 和→ 在
节点上
变通办法
我为这个问题做了一个变通方法,可以用来改进A1rPun的答案以支持Firefox
function ensurePreventDefault(select) {
var selectedIndex, scrollTop;
function saveState() {
selectedIndex = select.selectedIndex;
scrollTop = select.scrollTop;
}
saveState();
if (!select.multiple && !select.size) {
select.addEventListener('change', saveState);
}
// use setTimeout to wait a frame and see if the selected index was changed
setTimeout(function () {
select.removeEventListener('change', saveState);
if (select.selectedIndex !== selectedIndex) {
// Damn you, Firefox!
select.selectedIndex = selectedIndex;
select.scrollTop = scrollTop;
}
});
}
短版本:存储所选索引
,并在一帧后恢复
长版本:存储selectedIndex
,以便我们稍后使用setTimeout
检查它是否被Firefox更改。您还需要将这些值存储在'change'
事件中,以完全支持下拉列表。同时存储scrollTop
,以防止Firefox在多选模式中滚动。它们呈现为列表,而不是下拉列表,导致Firefox在所选索引更改时向下或向上滚动。如果您不想收听它的'change'
事件,则在多选的情况下,这将产生相反的效果
用法
您可以这样使用它:
var selects = document.getElementsByTagName('select');
for (var i = 0; i < selects.length; i++){
selects[i].addEventListener('keydown',function(e){
var key = e.which || e.keyCode;
if(key == 37){
var previousSibling = this.previousSibling;
while(previousSibling && previousSibling.nodeType != 1) {
previousSibling = previousSibling.previousSibling
}
previousSibling.focus();
e.preventDefault();
}else if(key === 39){
var nextSibling = this.nextSibling;
while(nextSibling && nextSibling.nodeType != 1) {
nextSibling = nextSibling.nextSibling
}
nextSibling.focus();
e.preventDefault();
}
})
}
.addEventListener('keydown', function (event) {
switch (event.which || event.keyCode) {
case 37: // left arrow
case 39: // right arrow
event.preventDefault();
ensurePreventDefault(this);
break;
}
});
这在A1rPun的JSFiddle上进行了扩展。虽然执行了请求,但在Firefox中不起作用。这主要是因为事件。preventDefault
不会阻止← 和→ 在
节点上
变通办法
我为这个问题做了一个变通方法,可以用来改进A1rPun的答案以支持Firefox
function ensurePreventDefault(select) {
var selectedIndex, scrollTop;
function saveState() {
selectedIndex = select.selectedIndex;
scrollTop = select.scrollTop;
}
saveState();
if (!select.multiple && !select.size) {
select.addEventListener('change', saveState);
}
// use setTimeout to wait a frame and see if the selected index was changed
setTimeout(function () {
select.removeEventListener('change', saveState);
if (select.selectedIndex !== selectedIndex) {
// Damn you, Firefox!
select.selectedIndex = selectedIndex;
select.scrollTop = scrollTop;
}
});
}
短版本:存储所选索引
,并在一帧后恢复
长版本:存储selectedIndex
,以便我们稍后使用setTimeout
检查它是否被Firefox更改。您还需要将这些值存储在'change'
事件中,以完全支持下拉列表。同时存储scrollTop
,以防止Firefox在多选模式中滚动。它们呈现为列表,而不是下拉列表,导致Firefox在所选索引更改时向下或向上滚动。如果您不想收听它的'change'
事件,则在多选的情况下,这将产生相反的效果
用法
您可以这样使用它:
var selects = document.getElementsByTagName('select');
for (var i = 0; i < selects.length; i++){
selects[i].addEventListener('keydown',function(e){
var key = e.which || e.keyCode;
if(key == 37){
var previousSibling = this.previousSibling;
while(previousSibling && previousSibling.nodeType != 1) {
previousSibling = previousSibling.previousSibling
}
previousSibling.focus();
e.preventDefault();
}else if(key === 39){
var nextSibling = this.nextSibling;
while(nextSibling && nextSibling.nodeType != 1) {
nextSibling = nextSibling.nextSibling
}
nextSibling.focus();
e.preventDefault();
}
})
}
.addEventListener('keydown', function (event) {
switch (event.which || event.keyCode) {
case 37: // left arrow
case 39: // right arrow
event.preventDefault();
ensurePreventDefault(this);
break;
}
});
这在A1rPun的JSFiddle上进行了扩展。关于:仅当表单中有一个select时有效。如果有多个选择下拉列表,则可以使用以下版本:
$(document).on('keydown', 'select', function(event) {
var value = $(this).find('option:selected').val();
if ((event.which == 37 || event.which === 39)) {
setTimeout(function (obj, val) {
console.log(val)
return function() {
obj.find('option[value="' + val + '"]').prop("selected", true)
}
}($(this), value), 0);
}
});
关于:仅当您在表单中有一个select时有效。如果有多个选择下拉列表,则可以使用以下版本:
$(document).on('keydown', 'select', function(event) {
var value = $(this).find('option:selected').val();
if ((event.which == 37 || event.which === 39)) {
setTimeout(function (obj, val) {
console.log(val)
return function() {
obj.find('option[value="' + val + '"]').prop("selected", true)
}
}($(this), value), 0);
}
});
工作正常,但如果仔细观察,或者如果事件中运行了大量代码,则会看到select值更改下一个元素并返回到原始元素
这是一个在Firefox上运行的解决方案,在我看来更干净。未在其他浏览器中测试
诀窍就是在keydown事件中将select设置为disabled,然后在下一帧使用setTimeout重新启用它。在处理完事件处理程序中的所有代码之前,匿名函数不会运行,从而确保不会过早地重新启用select
mySelect.addEventListener('keydown',
function (event) {
switch (event.which || event.keyCode || event.charCode) {
case 33:
this.disabled = true;
setTimeout(function (elem) {elem.disabled = false;}, 0, this);
break;
case 34:
this.disabled = true;
setTimeout(function (elem) {elem.disabled = false;}, 0, this);
break;
}
});
下面是的工作原理,但是如果仔细观察,或者如果事件中运行了大量代码,您将看到select值更改下一个元素并返回到原始元素