按下回车键时如何将焦点移到下一个字段?

Posted

技术标签:

【中文标题】按下回车键时如何将焦点移到下一个字段?【英文标题】:How to move focus on next field when enter is pressed? 【发布时间】:2014-08-04 06:21:47 【问题描述】:

你能告诉我按下回车键时如何将焦点移到下一个字段吗?我使用 dform 插件(将 JSON 转换为表单)。

我用谷歌搜索过,但这不起作用。为什么我的注意力没有转移到下一个领域?

JSFiddle:http://jsfiddle.net/5WkVW/1/

$(document).keypress(function(e) 
        if(e.which == 13) 
    
                // Do something here if the popup is open
                alert("dd")
                var index = $('.ui-dform-text').index(this) + 1;
                $('.ui-dform-text').eq(index).focus();
            
        
    );
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<form id="testSuiteConfigurationform" name="testSuiteConfigurationform" method="post" class="ui-dform-form" novalidate="novalidate">
    <label class="ui-dform-label">
        <h3>Configuration Parameters</h3>
    </label>
    <div class="ui-dform-div inputDiv">
        <fieldset class="ui-dform-fieldset">
            <input type="text" id="totalRetryCount" name="totalRetryCount" tabindex="1" onblur="validateElement('Configuration', 'testSuiteConfigurationform','totalRetryCount')" class="ui-dform-text valid">
            <legend class="ui-dform-legend">Total Retry Count</legend>
            <label for="totalRetryCount" class="checked">✔</label>
        </fieldset>
        <fieldset class="ui-dform-fieldset">
            <input type="text" id="totalRepeatCount" name="totalRepeatCount" tabindex="2" onblur="validateElement('Configuration', 'testSuiteConfigurationform','totalRepeatCount')" class="ui-dform-text">
            <legend class="ui-dform-legend">Total Repeat Count</legend>
        </fieldset>
        <fieldset class="ui-dform-fieldset">
            <select id="summaryReportRequired" name="summaryReportRequired" tabindex="3" onblur="validateElement('Configuration', 'testSuiteConfigurationform','summaryReportRequired')" class="ui-dform-select">
                <option class="ui-dform-option" value="true">true</option>
                <option class="ui-dform-option" value="false">false</option>
            </select>
            <legend class="ui-dform-legend">Summary Report Required</legend>
        </fieldset>
        <fieldset class="ui-dform-fieldset">
            <select id="postConditionExecution" name="postConditionExecution" tabindex="4" onblur="validateElement('Configuration', 'testSuiteConfigurationform','postConditionExecution')" class="ui-dform-select">
                <option class="ui-dform-option" value="ALWAYS">ALWAYS</option>
                <option class="ui-dform-option" value="ON_SUCCESS">ON_SUCCESS</option>
            </select>
            <legend class="ui-dform-legend">Post Condition Execution</legend>
        </fieldset>
    </div>
</form>

*注意(来自 cmets):它还需要在没有设置 tabindex 值的页面上工作

【问题讨论】:

我已经在所有 4 个 html 示例上测试了我的最终版本,它几乎可以在任何页面上运行。它使用我添加的自定义 jQuery 选择器。享受:) 【参考方案1】:

它失败了,因为this 是您代码中的document

您想使用当前焦点项目的索引 (document.activeElement),或者如果您使用委托事件,您可以确保 this 是当前项目。

无论有没有tabindexes,这个最终版本都有效。它也环绕:

JSFiddle 1:http://jsfiddle.net/TrueBlueAussie/5WkVW/11/

JSFiddle 2:http://jsfiddle.net/TrueBlueAussie/5WkVW/12/

他们都使用我添加的自定义 jQuery 选择器 :focusable 来选择所有可聚焦的元素(包括链接):

// register jQuery extension
jQuery.extend(jQuery.expr[':'], 
    focusable: function (el, index, selector) 
        return $(el).is('a, button, :input, [tabindex]');
    
);

$(document).on('keypress', 'input,select', function (e) 
    if (e.which == 13) 
        e.preventDefault();
        // Get all focusable elements on the page
        var $canfocus = $(':focusable');
        var index = $canfocus.index(this) + 1;
        if (index >= $canfocus.length) index = 0;
        $canfocus.eq(index).focus();
    
);

如果您愿意,您可以在事件处理程序中使用相同的自定义选择器。然后它甚至可以在锚链接上工作(如果你将事件更改为 keydown 而不是 keypress):

例如

$(document).on('keydown', ':focusable', function (e) 

链接示例:http://jsfiddle.net/5WkVW/15/

这也使用了一个委托on,监听document 上的keydown 事件。它然后 应用jQuery 选择器,它然后 将函数应用到导致事件的任何匹配元素。这更有效,因为它只在事件时应用选择器(而不是对每个 DOM 匹配元素应用多个事件处理程序)。


以下旧版本:

JSFiddle:http://jsfiddle.net/TrueBlueAussie/5WkVW/3/

$(document).keypress(function(e) 
    if(e.which == 13) 

            // Do something here if the popup is open
            //alert("dd")
            var index = $('.ui-dform-text').index(document.activeElement) + 1;
            $('.ui-dform-text').eq(index).focus();

    
);

*注意:警报会干扰focus,因此请使用console.log 进行类似的输出并在大多数浏览器的调试窗口中查看(如Chrome 的F12 调试工具)。

更新:http://jsfiddle.net/TrueBlueAussie/5WkVW/4/

这个从最后一个回绕到第一个项目,也适用于选择(默认行为被阻止,因此您只能使用空间来打开或向上/向下选择选项。

$('input,select').on('keypress', function (e) 
    if (e.which == 13) 
        e.preventDefault();
        var $next = $('[tabIndex=' + (+this.tabIndex + 1) + ']');
        console.log($next.length);
        if (!$next.length) 
            $next = $('[tabIndex=1]');
        
        $next.focus();
    
);

请求的“文档”版本:http://jsfiddle.net/TrueBlueAussie/5WkVW/5/

$(document).on('keypress', 'input,select', function (e) 
    if (e.which == 13) 
        e.preventDefault();
        var $next = $('[tabIndex=' + (+this.tabIndex + 1) + ']');
        console.log($next.length);
        if (!$next.length) 
            $next = $('[tabIndex=1]');
        
        $next.focus();
    
);

【讨论】:

完成...适用于两者..应该适用于任何东西! :) @Gone Coding:我不小心击中了箭头并给你投了反对票,但我刚刚注意到并且现在无法更改。对于那个很抱歉。显然,如果帖子被编辑,我可以删除它,所以如果你想做一个琐碎的编辑,我会这样做。 @Gone Coding:谢谢,我已经改了。 @GoneCoding 当下一个元素是禁用的输入元素时,此代码不起作用。有什么办法可以在 ":focusable" 列表中只添加 'not-disabled' 元素?? 我得到了答案。我刚刚将 ':input' 替换为 ':enabled' 并且它起作用了!谢谢!【参考方案2】:

我创建了一个非 jQuery 版本。所以只有纯javascript; https://jsfiddle.net/mm0uctuv/2/

Javascript:

var inputs = document.querySelectorAll("input,select");
for (var i = 0 ; i < inputs.length; i++) 
   inputs[i].addEventListener("keypress", function(e)
      if (e.which == 13) 
         e.preventDefault();
         var nextInput = document.querySelectorAll('[tabIndex="' + (this.tabIndex + 1) + '"]');
         if (nextInput.length === 0) 
            nextInput = document.querySelectorAll('[tabIndex="1"]');
         
         nextInput[0].focus();
      
   )

HTML:

<form>
   Field 1: <input type="text" tabindex="1"><br>
   Field 3: <input type="text" tabindex="3"><br>
   Field 2: <input type="text" tabindex="2">
</form>

【讨论】:

避免使用大于 0 的 tabindex 值。这样做会使依赖辅助技术的人难以导航和操作页面内容。 From MDN Web Docs【参考方案3】:

在***div上,添加onKeyDown=this.onKeyDown.bind(this)并将以下方法(ES6)添加到与div相同的类中:

onKeyDown(event) 
    if (event.keyCode === 13) 
        event.preventDefault()
        const inputs =
            Array.prototype.slice.call(document.querySelectorAll("input"))
        const index =
            (inputs.indexOf(document.activeElement) + 1) % inputs.length
        const input = inputs[index]
        input.focus()
        input.select()
    

【讨论】:

【参考方案4】:

下面的代码应该可以做到;它使用tabIndex 属性。如果这是不可接受的,请告诉我们:

$(function() 
    $('input').on('keypress', function(e) 
        e.which !== 13 || $('[tabIndex=' + (+this.tabIndex + 1) + ']')[0].focus();
    );
);

下拉菜单已经有用于打开下拉菜单的输入键。

JS FIDDLE DEMO

为了能够在移动到下一个表单元素之前做一些事情,您可以使用以下版本:

$(function() 
    $(document).on('keypress', function(e) 
        var that = document.activeElement;
        if( e.which == 13 ) 
            e.preventDefault();
            alert( "dd" );
            $('[tabIndex=' + (+that.tabIndex + 1) + ']')[0].focus();
                    
    );
);

DEMO

【讨论】:

我们可以在我的代码上更改您的代码吗?使用文档? like $(document).keypress(function(e) if(e.which == 13) // 如果弹出窗口打开,则在此处执行一些操作 alert("dd") var index = $('.ui-dform-text').index(this) + 1; $('.ui-dform-text').eq(index).focus(); ); 当然可以,让我看看我能把什么放在一起。 这很好(在发现 tabindex 存在时做得很好),但它不会环绕或允许在选择时输入。 @user2535959 这是可以理解的,这可以通过使用e.preventDefault() 阻止选择的默认行为来完成。查看我的更新版本。【参考方案5】:

尝试以下我从您的小提琴中修改的 JavaScript 代码。选择元素的默认行为是在按键上展开。 +$(this).attr("tabindex") 开头的加号

将文本属性值转换为int。

$(".ui-dform-text").keypress(function(e) 
    if(e.which == 13) 

        // Do something here if the popup is open
        alert($(this).attr("tabindex"));
        var index = +$(this).attr("tabindex") + 1;


        $("[tabindex='" + index +"']").focus();
    
);

【讨论】:

不幸的是(如果您关注 cmets),它还需要在没有 tabindex 属性的页面上工作:(【参考方案6】:

看起来一样,但我提供了一些简单、可能有用且易于记忆的东西,这就是我使用的东西

html

<input placeholder="nama">
<input placeholder="email">
<input placeholder="password">
<button>MASUK<button>

js

$('INPUT').keydown( e => e.which === 13?$(e.target).next().focus():"");

【讨论】:

【参考方案7】:
// 这会起作用;在您的就绪函数中添加此代码并定义您的父元素,其中包括要关注的子元素。

const mainDiv = document.getElementById(`auto-focuser`); //here your parent element you need to focus
const keyDownEvent = (event) => 
    if (event.key === "Enter") 
        if (event.target.tagName === "TEXTAREA" && (event.target.innerHTML !== "" && event.target.innerHTML.substr(-1) !== "\n"))
            return;
        if (event.target.attributes.tabindex) 
            const nextElm = mainDiv.querySelectorAll(`[tabindex='$parseInt(event.target.attributes.tabindex.value) + 1']`).item(0)
            if (nextElm) 
                nextElm.focus()
                if (nextElm.tagName === "INPUT" || nextElm.tagName === "TEXTAREA") 
                    nextElm.select()
                    nextElm.selectionStart = nextElm.selectionEnd = nextElm.value.length;
                
                event.preventDefault()
            
        
    

mainDiv?.addEventListener('keydown', keyDownEvent);

【讨论】:

【参考方案8】:

1.first = 你应该在你的类名上输入'textbox'

2.second = 为每个输入输入特定的 id

然后编写此代码以选择该元素并转到下一个元素。

我通过每个 id 选择每个元素,并将 next() 函数放在每个输入的按键上。

function next(event,elem)
if ( event.keyCode == 13)

    var list = document.getElementsByClassName("textbox");
    for (var i=0 ; i<list.length ; i++)
    
        if (elem.id == list[i].id)
        
            var index = i + 1;
            list[index].focus();
        
    
  


事件参数用于按键// elem args 用于我们按下 eneter 的元素

【讨论】:

【参考方案9】:

这主要是个玩笑,但这里是一个使用最新 API 的 Vanilla JS 版本,只要你有一个现代浏览器,它应该是防弹的

这是发生了什么:

    选择元素、输入等...(不包括禁用、隐藏等...) 使用展开语法,将数组(NodeList)转换为对象(这里是NodeObject) 循环遍历对象,也就是元素,也就是节点 每次迭代都会将当前元素 (Node) 和下一个元素 (NextNode) 传递给箭头函数。 如果 NextNode 是元素则继续 然后给当前元素添加按键事件 活动内部: 仅在按下回车键时继续(使用 e.key NOT e.keyCode 或 e.which -- 已弃用) 停止提交表单 关注下一个元素 如果可以,选择下一个节点中的文本

就像你有一些非常不可读的代码,主要是括号和箭头函数:)

// NodeList of applicable inputs, select, button
let NodesArray = document.querySelectorAll(`
                  #form input:not([disabled])[type]:not([type=\"hidden\"]),
                  #form select:not([disabled]),
                  #form button:not([disabled])[type=\"submit\"]
                `);

// Spread the array to an object so we can load the next node without 
// keeping track of indexes (barf)
(NodesObject => 

  // Node and NextNode are Elements.
  // You can update and get data if you want
  Object.keys(NodesObject).forEach(i => (( Node, NextNode ) => 

    // Break if we dont have a NextNode
    if (NextNode === false) return;


    Node.addEventListener('keypress', KeyboardEvent => 

      // Only continue if event.key was "Enter"
      if (KeyboardEvent.key !== "Enter") return;

      // Dont submit, thx
      KeyboardEvent.preventDefault();

      // Do the thing
      NextNode.focus();

      // Not all elements have a select method
      if (typeof NextNode.select === 'function') NextNode.select();
    );


  )(
    Node:     NodesObject[i],
    NextNode: NodesObject[(parseInt(i) + 1)] ?? false
  ));

)( ...NodesArray );

【讨论】:

以上是关于按下回车键时如何将焦点移到下一个字段?的主要内容,如果未能解决你的问题,请参考以下文章

按下 Enter 时将焦点转移到下一个字段

cxGrid 单元格回车移到下一行,当移到最后一个单元格时回车新增一行

html表单 - 按下回车时自动按钮焦点

将 Enter 解释为带有选择的 Tab

如何杀死 MFC 向导按钮的焦点

cxgrid中回车键光标移到下列