【问题标题】:Prevent default behavior in text input while pressing arrow up按向上箭头时防止文本输入中的默认行为
【发布时间】:2010-11-08 00:12:01
【问题描述】:

我正在使用带有数值的基本 HTML <input type="text"/> 文本字段。

我正在添加 JavaScript 事件 keyup 以查看用户何时按下向上箭头键 (e.which == 38) - 然后我增加数值。

代码运行良好,但有一件事让我很头疼。当我按向上箭头键时,Safari/Mac 和 Firefox/Mac 都会在最开始移动光标。据我所知,这是每个 <input type="text"/> 文本字段的默认行为,这是有道理的。

但这不会产生光标前后跳动的美学效果(在更改值之后)。

一开始的跳跃发生在keydown,但即使有了这些知识,我也无法阻止它发生。我尝试了以下方法:

input.addEventListener('keydown', function(e) {
    e.preventDefault();
}, false);

e.preventDefault() 放入keyup 事件也无济于事。

有什么办法可以防止光标移动吗?

【问题讨论】:

    标签: javascript events input keyboard default


    【解决方案1】:

    可能不会。相反,您应该寻求一种解决方案,将光标移回其所在字段的末尾。对于用户来说效果是一样的,因为它太快而无法被人类感知。

    我搜索了一些并找到了这段代码。我现在无法测试它,据说它不适用于 IE 6。

    textBox.setSelectionRange(textBox.value.length, textBox.value.length);

    【讨论】:

    • 谢谢。实际上更新 input.value 将导致光标在最后移回。所以我可能会检测光标的位置,然后在更改后恢复它(例如,如果它在数字的中间)。但我仍在寻找更好的解决方案,如果有的话。
    【解决方案2】:

    我测试了代码,它似乎取消了该事件,但如果您在很短的时间内没有按下箭头 - 它会触发 keypress 事件并且该事件实际上会移动光标。只需在 keypress 事件处理程序中使用 preventDefault() 就可以了。

    【讨论】:

    • 不幸的是,e.preventDefault() 中的 keypress 事件阻止我在那里输入任何内容(我希望输入像在 Firebug 中一样工作)。它并没有解决我的问题,至少在我的浏览器中——光标仍然在一开始就跳动。
    【解决方案3】:

    要保留光标位置,请在更改值之前备份input.selectionStart

    问题在于 WebKit 对 keydown 做出反应,而 Opera 更喜欢 keypress,因此存在问题:两者都被处理和限制。

    var ignoreKey = false;
    var handler = function(e)
    {
        if (ignoreKey)
        {
            e.preventDefault();
            return;
        }
        if (e.keyCode == 38 || e.keyCode == 40) 
        {
            var pos = this.selectionStart;
            this.value = (e.keyCode == 38?1:-1)+parseInt(this.value,10);        
            this.selectionStart = pos; this.selectionEnd = pos;
    
            ignoreKey = true; setTimeout(function(){ignoreKey=false},1);
            e.preventDefault();
        }
    };
    
    input.addEventListener('keydown',handler,false);
    input.addEventListener('keypress',handler,false);
    

    【讨论】:

    • 搞砸了!非常感谢,很完美。 :)
    • 对“kludge”投赞成票!为我工作,感谢您的回答。
    【解决方案4】:

    我发现一个更好的解决方案就是return false;来防止默认的箭头键行为:

    input.addEventListener("keydown", function(e) {
        if (e.key === 'ArrowUp' || e.key === 'ArrowDown') return false;
    }, false);
    

    【讨论】:

    • 谢谢伙计。这个想法是使用 keydown 事件而不是 keyup。
    • 右 - keydown 是诀窍。请注意,返回 false 似乎完全停止了事件的传播,而 preventDefault() 将让输入框忽略该事件,同时仍然允许其他侦听器在它冒泡时对其进行处理。
    • @Lukas ,您的解决方案最适合我。但是,我打电话给e.preventDefault();,而不是返回false。后者没有实现向上箭头键行为的冻结。感谢您发布另一个更简单的解决方案。
    • 这是正确答案!我必须使用 keydown 事件来停止光标移动,然后在需要时使用 keyup 事件来获取输入值
    • 使用 e.code === 'ArrowUp' || e.code === 'ArrowDown' 将使代码更易于阅读。
    【解决方案5】:

    其实,有更好更简单的方法来完成这项工作。

    $('input').bind('keydown', function(e){
        if(e.keyCode == '38' || e.keyCode == '40'){
            e.preventDefault();
        }
    });
    

    是的,就是这么简单!

    【讨论】:

      【解决方案6】:

      在我的情况下(反应)帮助:

      onKeyDown = {
        (e) => {
          if (e.key === 'ArrowUp' || e.key === 'ArrowDown') e.preventDefault();
        }
      }
      

      onKeyUp 功能齐全

      【讨论】:

        猜你喜欢
        • 2011-09-07
        • 1970-01-01
        • 1970-01-01
        • 2018-12-13
        • 1970-01-01
        • 1970-01-01
        • 2019-12-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多