【问题标题】: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 选择器。享受:)

标签: javascript jquery jquery-mobile


【解决方案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 版本,只要你有一个现代浏览器,它应该是防弹的

          这是发生了什么:

          1. 选择元素、输入等...(不包括禁用、隐藏等...)
          2. 使用展开语法,将数组(NodeList)转换为对象(这里是NodeObject)
          3. 循环遍历对象,也就是元素,也就是节点
          4. 每次迭代都会将当前元素 (Node) 和下一个元素 (NextNode) 传递给箭头函数。
          5. 如果 NextNode 是元素则继续
          6. 然后给当前元素添加按键事件
          7. 活动内部:
            • 仅在按下回车键时继续(使用 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 });
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-01-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-09-16
            相关资源
            最近更新 更多