【问题标题】:How to set Focus on Input using Tab Key Press in Next Table Cell如何在下一个表格单元格中使用 Tab 键设置焦点输入
【发布时间】:2020-04-20 14:39:34
【问题描述】:

以下是我在 HTML 中使用 JQuery 实现的场景

  • 当用户双击表格单元格时,里面应该有一个新的输入 双击单元格 [完成]
  • 当用户 KeyPress [Tab] 并且它应该移动到下一个单元格 [Done] 时

在 2 场景的情况下,我需要在下一个 Cell 上触发 dblclick() 事件,该事件在其中创建输入元素,但它无法在输入元素内聚焦。

我已尝试调试该场景,但无法理解它发生的原因。

我创建了一个按钮并编写了触发 dblclick() 的点击函数,然后在输入元素内设置焦点。

我无法理解当用户使用鼠标单击/click() 时为什么将焦点设置在创建的输入元素上但为什么当我使用dblclick() 从代码触发双击时没有发生同样的情况/p>

以下是相同的代码:


//Global Variables
var TabEdit_sourceInput = null;
var TabEdit_currentTd = null;
var TabEdit_DOMtocheck = null;
var TabEdit_previousHour = null;
var gridRefreshFlag = false;

//Init Double Click Event on the Table TD
$('.custom-table-td').dblclick(function(event){
    var tableId = $(this).attr('id');
    var inputId = 'input-'+tableId;
    $(this).html('<input id="input-'+tableId+'" placeholder="Type Message" class="form-control" onkeydown="return initCheckKeypress();" tabindex="1"/>');
    
    //Focusing on Generated Event
    $('#'+inputId).focus();

    //Binding the Focus Out Event to
    $('#'+inputId).focusout(function(){
        debugger;
        $('.header').html($(this).val());
     });
     
});

//Click Event to trigger dblclick on td with id = 'tableData1'
$('.btn-trigger-dbclick').click(function(){
    $('#tableData1').dblclick();
});

//Function to check Tab is Press or not
function initCheckKeypress(evt) {
    "use strict";
    var e = event || evt; // for trans-browser compatibility
    var charCode = e.which || e.keyCode;
    if (charCode === 9) {
        gridRefreshFlag = true;
        TabEdit_sourceInput = $(e.target);
        TabEdit_currentTd = TabEdit_sourceInput.parent();
        TabEdit_DOMtocheck = TabEdit_currentTd.next('td');
        movetoNextTD();
    }
}


//Code to Click on Next Cell
function movetoNextTD() {
    if (gridRefreshFlag && TabEdit_DOMtocheck !== null) {
        TabEdit_currentTd.html("");
        TabEdit_DOMtocheck.dblclick();
        resetmovetoNextVariable();
    }
}

//Reset Global Variable
function resetmovetoNextVariable(){
    TabEdit_sourceInput = null;
    TabEdit_currentTd = null;
    TabEdit_DOMtocheck = null;
    TabEdit_previousHour = null;
    gridRefreshFlag = false;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Focus Issue</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" >
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-lg-6">
                <div class="header"></div>
                <table class="table table-bordered">
                    <tbody>
                        <tr id="tableRow1">
                            <th id="tableHeader1" class="custom-table-th">TH 1</th>
                            <th id="tableHeader2" class="custom-table-th">TH 2</th>
                            <th id="tableHeader3" class="custom-table-th">TH 3</th>
                        </tr>
                        <tr id="tableRow2">
                            <td id="tableData1" class="custom-table-td"></td>
                            <td id="tableData2" class="custom-table-td"></td>
                            <td id="tableData3" class="custom-table-td"></td>
                        </tr>
                    </tbody>
                </table>
                <button class="btn btn-primary btn-trigger-dbclick">Trigger</button>
            </div>
        </div>
    </div>
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
</body>
</html>

【问题讨论】:

    标签: javascript jquery focus event-bubbling event-capturing


    【解决方案1】:

    发生了什么是这样的:

    • 双击 - 生成第一个输入并设置焦点,很好
    • 用户按下选项卡 - 检查选项卡的代码在系统事件处理程序之前启动并创建第二个输入并设置焦点 - 然后系统继续执行默认选项卡操作并关闭第二个输入的选项卡

    修复是在创建第二个输入后取消系统默认事件:

    e.preventDefault();
    

    更新了sn-p:

    //Global Variables
    var TabEdit_sourceInput = null;
    var TabEdit_currentTd = null;
    var TabEdit_DOMtocheck = null;
    var TabEdit_previousHour = null;
    var gridRefreshFlag = false;
    
    //Init Double Click Event on the Table TD
    $('.custom-table-td').dblclick(function(event){
        var tableId = $(this).attr('id');
        var inputId = 'input-'+tableId;
        $(this).html('<input id="input-'+tableId+'" placeholder="Type Message" class="form-control" onkeydown="return initCheckKeypress();" tabindex="1"/>');
        
        //Focusing on Generated Event
        $('#'+inputId).focus();
    
        //Binding the Focus Out Event to
        $('#'+inputId).focusout(function(){
            debugger;
            $('.header').html($(this).val());
         });
         
    });
    
    //Click Event to trigger dblclick on td with id = 'tableData1'
    $('.btn-trigger-dbclick').click(function(){
        $('#tableData1').dblclick();
    });
    
    //Function to check Tab is Press or not
    function initCheckKeypress(evt) {
        "use strict";
        var e = event || evt; // for trans-browser compatibility
        var charCode = e.which || e.keyCode;
        if (charCode === 9) {
            gridRefreshFlag = true;
            TabEdit_sourceInput = $(e.target);
            TabEdit_currentTd = TabEdit_sourceInput.parent();
            TabEdit_DOMtocheck = TabEdit_currentTd.next('td');
            movetoNextTD();
            e.preventDefault();
        }
    }
    
    
    //Code to Click on Next Cell
    function movetoNextTD() {
        if (gridRefreshFlag && TabEdit_DOMtocheck !== null) {
            TabEdit_DOMtocheck.dblclick();
            TabEdit_currentTd.html("");
            resetmovetoNextVariable();
        }
    }
    
    //Reset Global Variable
    function resetmovetoNextVariable(){
        TabEdit_sourceInput = null;
        TabEdit_currentTd = null;
        TabEdit_DOMtocheck = null;
        TabEdit_previousHour = null;
        gridRefreshFlag = false;
    }
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Focus Issue</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" >
    </head>
    <body>
        <div class="container">
            <div class="row">
                <div class="col-lg-6">
                    <div class="header"></div>
                    <table class="table table-bordered">
                        <tbody>
                            <tr id="tableRow1">
                                <th id="tableHeader1" class="custom-table-th">TH 1</th>
                                <th id="tableHeader2" class="custom-table-th">TH 2</th>
                                <th id="tableHeader3" class="custom-table-th">TH 3</th>
                            </tr>
                            <tr id="tableRow2">
                                <td id="tableData1" class="custom-table-td"></td>
                                <td id="tableData2" class="custom-table-td"></td>
                                <td id="tableData3" class="custom-table-td"></td>
                            </tr>
                        </tbody>
                    </table>
                    <button class="btn btn-primary btn-trigger-dbclick">Trigger</button>
                </div>
            </div>
        </div>
        <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
    </body>
    </html>

    【讨论】:

    • 这无济于事,因为您将 jquery 事件与 html 事件混合在一起,并且您的 html 事件在键 down 上,但您的 js 方法是键 press (onkeydown="return initCheckKeypress();") - 按键事件的工作方式与按键不同。
    • 使用setTimeout 是一种快速简便的解决方法,但它并不理想,最好知道它为什么不起作用。
    • 谢谢。它有很大帮助,但它不会让我触发我写在焦点事件上的函数。但为此,我可以使用 $('#'+inputid).focusout(); 手动触发它
    • 这是一个类似的问题——并不是它没有触发模糊——而是你在移除焦点之前移除了第一个输入。即按 Tab,删除第一个输入,创建第二个输入,聚焦到第二个输入,将模糊发送到当前输入...哦,当前输入不再存在,所以没有模糊事件。
    • 您可以通过在删除旧输入之前创建新输入+设置焦点来解决此问题 - 即交换这两行:TabEdit_DOMtocheck.dblclick(); TabEdit_currentTd.html(""); - 我已经更新了 sn-p。
    【解决方案2】:

    更改您的 initCheckKeyPress 函数实现会有所帮助。我通过添加以下内容来防止触发事件的默认行为来解决此问题:

    e.preventDefault();
    

    这是因为“tab”按键事件的默认行为是关注下一个键项。这发生在创建输入之前(正如 Freedomn-m 正确突出显示的那样)。因此,防止这种情况可以使这项工作发挥作用。

    您的最终代码如下所示:

    之前

    function initCheckKeypress(evt) {
    "use strict";
    var e = event || evt; // for trans-browser compatibility
    var charCode = e.which || e.keyCode;
    if (charCode === 9) {
        gridRefreshFlag = true;
        TabEdit_sourceInput = $(e.target);
        TabEdit_currentTd = TabEdit_sourceInput.parent();
        TabEdit_DOMtocheck = TabEdit_currentTd.next('td');
        movetoNextTD();
    }}
    

    之后:

    function initCheckKeypress(evt) {
    "use strict";
    var e = event || evt; 
    e.preventDefault();// for trans-browser compatibility
    var charCode = e.which || e.keyCode;
    if (charCode === 9) {
        gridRefreshFlag = true;
        TabEdit_sourceInput = $(e.target);
        TabEdit_currentTd = TabEdit_sourceInput.parent();
        TabEdit_DOMtocheck = TabEdit_currentTd.next('td');
        movetoNextTD();
    
    }}
    

    【讨论】:

    • 这发生在输入创建之前 - 抱歉,此信息不正确。还有一些其他类似代码的 SO 问题(添加一个输入,然后集中它),这些没有这个问题。问题是默认选项卡处理程序发生在之后输入具有焦点(因此不关注它),因为 OPs 代码是按下键(而不是按下键(虽然不确定这是否相关) ))。带有小提琴链接的示例问题:stackoverflow.com/questions/12052322/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-17
    • 2021-11-29
    • 1970-01-01
    相关资源
    最近更新 更多