Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
HTML/Javascript-停止左/右箭头更改下拉菜单选项_Javascript_Html_Drop Down Menu - Fatal编程技术网

HTML/Javascript-停止左/右箭头更改下拉菜单选项

HTML/Javascript-停止左/右箭头更改下拉菜单选项,javascript,html,drop-down-menu,Javascript,Html,Drop Down Menu,我正在用输入网格创建一个web表单,用于在Django中创建对象 似乎当焦点位于下拉菜单上时,向上和向左箭头选择上一项,右/向下箭头选择下一项 我想使用左/右箭头在网格上向左或向右移动焦点(有点像excel)。我是否可以禁止左/右箭头更改菜单选项(同时保留向上/向下箭头的功能)?更改控件的默认行为有时会让用户感到沮丧。但在其他情况下,用户希望它像excel一样工作(如您的情况:) 您可以这样做: var selects = document.getElementsByTagName('selec

我正在用输入网格创建一个web表单,用于在Django中创建对象

似乎当焦点位于下拉菜单上时,向上和向左箭头选择上一项,右/向下箭头选择下一项


我想使用左/右箭头在网格上向左或向右移动焦点(有点像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值更改下一个元素并返回到原始元素