【问题标题】:Navigate Two HTML Table with input text using arrow key使用箭头键导航两个带有输入文本的 HTML 表
【发布时间】:2016-11-25 06:42:51
【问题描述】:

在我的previous post 上,我询问了如何使用箭头键导航表格单元格。现在我正在尝试创建另一个与第一个行为相同的表。

如何做到这一点?

这是我目前所拥有的:

var active = 0;
//$('#navigate td').each(function(idx){$(this).html(idx);});
rePosition();

$(document).keydown(function(e) {
    var inp = String.fromCharCode(event.keyCode);
    if (!(/[a-zA-Z0-9-_ ]/.test(inp) || event.keyCode == 96)){
      reCalculate(e);
      rePosition();
      // if key is an arrow key, don't type the user input.
      // if it is any other key (a, b, c, etc)
      // edit the text
      if (e.keyCode > 36 && e.keyCode < 41) {
        return false;
      }
    }
});

$('td').click(function() {
    active = $(this).closest('table tbody').find('td').index(this);
    rePosition();
});


function reCalculate(e) {
    var rows = $('#navigate tbody tr').length;
    var columns = $('#navigate tbody tr:eq(0) td').length;
    var temp;

    if (e.keyCode == 37) { //move left or wrap
        temp = active;
        while (temp > 0) {
            temp = temp - 1;
            // only advance if there is an input field in the td
            if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) {
                active = temp;
                break;
            }
        }
    }
    if (e.keyCode == 38) { // move up
        temp = active;
        while (temp - columns >= 0) {
            temp = temp - columns;
            // only advance if there is an input field in the td
            if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) {
                active = temp;
                break;
            }
        }
    }
    if (e.keyCode == 39) { // move right or wrap
        temp = active;
        while (temp < (columns * rows) - 1) {
            temp = temp + 1;
            // only advance if there is an input field in the td
            if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) {
                active = temp;
                break;
            }
        }
    }
    if (e.keyCode == 40) { // move down
        temp = active;
        while (temp + columns <= (rows * columns) - 1) {
            temp = temp + columns;
            // only advance if there is an input field in the td
            if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) {
                active = temp;
                break;
            }
        }
    }
}

function rePosition() {
    console.log(active);
    $('.active').removeClass('active');
    $('#navigate tbody tr td').eq(active).addClass('active');
    $('#navigate tbody tr td').find('input').removeClass('textClass');
    $('#navigate tbody tr td').eq(active).find('input').addClass('textClass');
    $('#navigate tbody tr td').eq(active).find('input').select();
    var input = $('#navigate tbody tr td').eq(active).find('input').focus();
    scrollInView();
}

function scrollInView() {
    var target = $('#navigate tbody tr td:eq(' + active + ')');
    if (target.length) {
        var top = target.offset().top;

        $('html,body').stop().animate({
            scrollTop: top - 100
        }, 400);
        return false;
    }
}
td.active{
border:2px solid #2c3e50;
font-weight:bold;
background-color:#ddd;
}

.textClass{ 
    font-weight:bold; 
}

input:focus {
    outline: none; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<table border="1" id="navigate">
    <thead>
            <th> CELL 1</th>
            <th> CELL 2</th>
            <th> CELL 3</th>
            <th> CELL 4</th>
            <th> CELL 5</th>
    </thead>
    <tbody>
        <tr>
            <td><input type="text" value="CELL 1" /></td>
            <td><input type="text" value="CELL 2" /></td>
            <td><input type="text" value="CELL 3" /></td>
            <td><input type="text" value="CELL 4" /></td>
            <td><input type="text" value="CELL 5" /></td>
        </tr>
        <tr>
            <td><input type="text" value="CELL 1" /></td>
            <td><input type="text" value="CELL 2" /></td>
            <td><input type="text" value="CELL 3" /></td>
            <td><input type="text" value="CELL 4" /></td>
            <td><input type="text" value="CELL 5" /></td>
        </tr>
        <tr>
            <td><input type="text" value="CELL 1" /></td>
            <td><input type="text" value="CELL 2" /></td>
            <td><input type="text" value="CELL 3" /></td>
            <td><input type="text" value="CELL 4" /></td>
            <td><input type="text" value="CELL 5" /></td>
        </tr>
        <tr>
            <td><input type="text" value="CELL 1" /></td>
            <td><input type="text" value="CELL 2" /></td>
            <td><input type="text" value="CELL 3" /></td>
            <td><input type="text" value="CELL 4" /></td>
            <td><input type="text" value="CELL 5" /></td>
        </tr>

    </tbody>
</table>

<br><br>

<table border="1" id="table2">
        <tr>
            <td><input type="text" value="CELL 1" /></td>
            <td><input type="text" value="CELL 2" /></td>
            <td><input type="text" value="CELL 3" /></td>
            <td><input type="text" value="CELL 4" /></td>
            <td><input type="text" value="CELL 5" /></td>
        </tr>
    <tbody>
        <tr>
            <td><input type="text" value="CELL 1" /></td>
            <td><input type="text" value="CELL 2" /></td>
            <td><input type="text" value="CELL 3" /></td>
            <td><input type="text" value="CELL 4" /></td>
            <td><input type="text" value="CELL 5" /></td>
        </tr>
        <tr>
             <td><input type="text" value="CELL 1" /></td>
            <td><input type="text" value="CELL 2" /></td>
            <td><input type="text" value="CELL 3" /></td>
            <td><input type="text" value="CELL 4" /></td>
            <td><input type="text" value="CELL 5" /></td>
        </tr>
        <tr>
            <td><input type="text" value="CELL 1" /></td>
            <td><input type="text" value="CELL 2" /></td>
            <td><input type="text" value="CELL 3" /></td>
            <td><input type="text" value="CELL 4" /></td>
            <td><input type="text" value="CELL 5" /></td>
        </tr>
        <tr>
            <td><input type="text" value="CELL 1" /></td>
            <td><input type="text" value="CELL 2" /></td>
            <td><input type="text" value="CELL 3" /></td>
            <td><input type="text" value="CELL 4" /></td>
            <td><input type="text" value="CELL 5" /></td>
        </tr>

    </tbody>
</table>

有关示例演示,请参阅此链接。

DEMO HERE

【问题讨论】:

  • 当您到达第一个表格的末尾时,您想在第二个表格中继续导航吗?

标签: javascript jquery html css


【解决方案1】:

经过一番辛勤的研究,找到了正确的解决方案。由于我们无法在任何其他表的 TD 内单击:我们需要更改查找td 索引的方式。

目前是这样的:

$(this).closest('table tbody').find('td').index(this);

这总是返回第一个表td 索引。

以下代码有助于找到当前焦点所在的 TD 的准确索引:

$('table td').index(this);

虽然它看起来是一条简单的线.. 很小的研究使它变得那么小...

Working DEMO

【讨论】:

  • @x'tian,既困难又耗时.. 所以作为新答案发布✍(◔◡◔) ...如果它杀死,请告诉我问题..
  • 真是个天才的把戏!谢谢你的朋友。这么晚才回复很抱歉。两天没联系了。
  • 嗨哥们我遇到了另一个问题,我试图禁用我的一些文本框。然后每次我删除选定的单元格然后尝试编辑它弹跳到编辑的文本框。
  • 我实际上在这里发布了新问题。 stackoverflow.com/questions/40903118/….
  • 我也试过这样做 if ($("#input1").prop("disabled", true)) { $(this).focus();}
【解决方案2】:

发送表格 id in $('td').click

$('td').click(function() {
    active = $(this).closest('table tbody').find('td').index(this);
    var tableid=$(this).closest('table').attr('id');
    console.log(tableid);
    rePosition(tableid);
});

并改变功能 rePosition()

function rePosition(tableid) {
    console.log(active);
    $('.active').removeClass('active');
    $('#'+tableid+' tbody tr td').eq(active).addClass('active');
    $('#'+tableid+' tbody tr td').find('input').removeClass('textClass');
    $('#'+tableid+' tbody tr td').eq(active).find('input').addClass('textClass');
    $('#'+tableid+' tbody tr td').eq(active).find('input').select();
    var input = $('#'+tableid+' tbody tr td').eq(active).find('input').focus();
    scrollInView(tableid);
}

现场演示 Here

片段示例

var active = 0;
//$('#navigate td').each(function(idx){$(this).html(idx);});
rePosition();

$(document).keydown(function(e) {
    var inp = String.fromCharCode(event.keyCode);
    if (!(/[a-zA-Z0-9-_ ]/.test(inp) || event.keyCode == 96)){
      reCalculate(e);
      rePosition();
      // if key is an arrow key, don't type the user input.
      // if it is any other key (a, b, c, etc)
      // edit the text
      if (e.keyCode > 36 && e.keyCode < 41) {
        return false;
      }
    }
});

$('td').click(function() {
    active = $(this).closest('table tbody').find('td').index(this);
    var tableid=$(this).closest('table').attr('id');
    console.log(tableid);
    rePosition(tableid);
});


function reCalculate(e) {
    var rows = $('#navigate tbody tr').length;
    var columns = $('#navigate tbody tr:eq(0) td').length;
    var temp;

    if (e.keyCode == 37) { //move left or wrap
        temp = active;
        while (temp > 0) {
            temp = temp - 1;
            // only advance if there is an input field in the td
            if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) {
                active = temp;
                break;
            }
        }
    }
    if (e.keyCode == 38) { // move up
        temp = active;
        while (temp - columns >= 0) {
            temp = temp - columns;
            // only advance if there is an input field in the td
            if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) {
                active = temp;
                break;
            }
        }
    }
    if (e.keyCode == 39) { // move right or wrap
        temp = active;
        while (temp < (columns * rows) - 1) {
            temp = temp + 1;
            // only advance if there is an input field in the td
            if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) {
                active = temp;
                break;
            }
        }
    }
    if (e.keyCode == 40) { // move down
        temp = active;
        while (temp + columns <= (rows * columns) - 1) {
            temp = temp + columns;
            // only advance if there is an input field in the td
            if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) {
                active = temp;
                break;
            }
        }
    }
}

function rePosition(tableid) {
    console.log(active);
    $('.active').removeClass('active');
    $('#'+tableid+' tbody tr td').eq(active).addClass('active');
    $('#'+tableid+' tbody tr td').find('input').removeClass('textClass');
    $('#'+tableid+' tbody tr td').eq(active).find('input').addClass('textClass');
    $('#'+tableid+' tbody tr td').eq(active).find('input').select();
    var input = $('#'+tableid+' tbody tr td').eq(active).find('input').focus();
    scrollInView(tableid);
}

function scrollInView(tableid) {
    var target = $('#'+tableid+' tbody tr td:eq(' + active + ')');
    if (target.length) {
        var top = target.offset().top;

        $('html,body').stop().animate({
            scrollTop: top - 100
        }, 400);
        return false;
    }
}
td.active{
    border:2px solid #2c3e50;
    font-weight:bold;
    background-color:#ddd;
}


.textClass{ 
	font-weight:bold; 
}

input:focus {
	outline: none; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table border="1" id="navigate">
	<thead>
			<th> CELL 1</th>
			<th> CELL 2</th>
			<th> CELL 3</th>
			<th> CELL 4</th>
			<th> CELL 5</th>
	</thead>
    <tbody>
        <tr>
            <td><input type="text" value="CELL 1" /></td>
            <td><input type="text" value="CELL 2" /></td>
            <td><input type="text" value="CELL 3" /></td>
            <td><input type="text" value="CELL 4" /></td>
            <td><input type="text" value="CELL 5" /></td>
        </tr>
        <tr>
            <td><input type="text" value="CELL 1" /></td>
            <td><input type="text" value="CELL 2" /></td>
            <td><input type="text" value="CELL 3" /></td>
            <td><input type="text" value="CELL 4" /></td>
            <td><input type="text" value="CELL 5" /></td>
        </tr>
        <tr>
            <td><input type="text" value="CELL 1" /></td>
            <td><input type="text" value="CELL 2" /></td>
            <td><input type="text" value="CELL 3" /></td>
            <td><input type="text" value="CELL 4" /></td>
            <td><input type="text" value="CELL 5" /></td>
        </tr>
        <tr>
            <td><input type="text" value="CELL 1" /></td>
            <td><input type="text" value="CELL 2" /></td>
            <td><input type="text" value="CELL 3" /></td>
            <td><input type="text" value="CELL 4" /></td>
            <td><input type="text" value="CELL 5" /></td>
        </tr>

    </tbody>
</table>

<br><br>

<table border="1" id="table2">
	 	<tr>
            <td><input type="text" value="CELL 1" /></td>
            <td><input type="text" value="CELL 2" /></td>
            <td><input type="text" value="CELL 3" /></td>
            <td><input type="text" value="CELL 4" /></td>
            <td><input type="text" value="CELL 5" /></td>
        </tr>
    <tbody>
        <tr>
            <td><input type="text" value="CELL 1" /></td>
            <td><input type="text" value="CELL 2" /></td>
            <td><input type="text" value="CELL 3" /></td>
            <td><input type="text" value="CELL 4" /></td>
            <td><input type="text" value="CELL 5" /></td>
        </tr>
        <tr>
             <td><input type="text" value="CELL 1" /></td>
            <td><input type="text" value="CELL 2" /></td>
            <td><input type="text" value="CELL 3" /></td>
            <td><input type="text" value="CELL 4" /></td>
            <td><input type="text" value="CELL 5" /></td>
        </tr>
        <tr>
            <td><input type="text" value="CELL 1" /></td>
            <td><input type="text" value="CELL 2" /></td>
            <td><input type="text" value="CELL 3" /></td>
            <td><input type="text" value="CELL 4" /></td>
            <td><input type="text" value="CELL 5" /></td>
        </tr>
        <tr>
            <td><input type="text" value="CELL 1" /></td>
            <td><input type="text" value="CELL 2" /></td>
            <td><input type="text" value="CELL 3" /></td>
            <td><input type="text" value="CELL 4" /></td>
            <td><input type="text" value="CELL 5" /></td>
        </tr>

    </tbody>
</table>

【讨论】:

    【解决方案3】:

    试试THIS DEMO

    如果两个表或更多...使用Class 来识别所有表

    我已经写了class="tblnavigate" 以在 Javascript 中调用表格单元格。

    所以,重新定位函数看起来像:

    function rePosition() {
        console.log(active);
        $('.active').removeClass('active');
        $('.tblnavigate tbody tr td').eq(active).addClass('active');
        $('.tblnavigate tbody tr td').find('input').removeClass('textClass');
        $('.tblnavigate tbody tr td').eq(active).find('input').addClass('textClass');
        $('.tblnavigate tbody tr td').eq(active).find('input').select();
        var input = $('.tblnavigate tbody tr td').eq(active).find('input').focus();
        scrollInView();
    }
    

    更新:

    退格键的行为必须与它的功能一致,因此,将其排除在keydown 函数中,

    if ((!(/[a-zA-Z0-9-_ ]/.test(inp) || e.keyCode == 96)) && e.keyCode != 8){ ... }
    

    UPDATED DEMO

    【讨论】:

    • 操作。另一个问题是,为什么当我输入所选单元格并尝试退格时,它会删除我输入的所有内容?
    • @x'tian,正在考虑回答您的其他未决问题 (>‿◠)✌
    • 我实际上遇到了另一个问题。呵呵。尝试使用鼠标单击单击第二个表。它失去了焦点,无法导航。是否有可能当我使用鼠标单击单元格时,它会聚焦并允许箭头键功能?
    【解决方案4】:

    用下面的代码替换你的函数并检查:

    function reCalculate(e) {
        var rows = $('#navigate tbody tr').length;
        var columns = $('#navigate tbody tr:eq(0) td').length;
        var temp;
    
        if (e.keyCode == 37) { //move left or wrap
            temp = active;
            while (temp > 0) {
                temp = temp - 1;
                // only advance if there is an input field in the td
                if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) {
                    active = temp;
                    break;
                }
            }
        }
        if (e.keyCode == 38) { // move up
            temp = active;
            while (temp - columns >= 0) {
                temp = temp - columns;
                // only advance if there is an input field in the td
                if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) {
                    active = temp;
                    break;
                }
            }
        }
        if (e.keyCode == 39) { // move right or wrap
            temp = active;
            while (temp < (columns * rows) - 1) {
                temp = temp + 1;
                // only advance if there is an input field in the td
                if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) {
                    active = temp;
                    break;
                }
            }
        }
        if (e.keyCode == 40) { // move down
            temp = active;
            while (temp + columns <= (rows * columns) - 1) {
                temp = temp + columns;
                // only advance if there is an input field in the td
                if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) {
                    active = temp;
                    break;
                }
            }
        }
    }
    
    function rePosition() {
        console.log(active);
        $('.active').removeClass('active');
        $('#navigate tbody tr td').eq(active).addClass('active');
        $('#navigate tbody tr td').find('input').removeClass('textClass');
        $('#navigate tbody tr td').eq(active).find('input').addClass('textClass');
        $('#navigate tbody tr td').eq(active).find('input').select();
        var input = $('#navigate tbody tr td').eq(active).find('input').focus();
        scrollInView();
    }
    
    function scrollInView() {
        var target = $('#navigate tbody tr td:eq(' + active + ')');
        if (target.length) {
            var top = target.offset().top;
    
            $('html,body').stop().animate({
                scrollTop: top - 100
            }, 400);
            return false;
        }
    }
    

    查看更新的演示:Click Here

    【讨论】:

    • 无法点击第二张桌子..你确定吗,答案有效..?
    【解决方案5】:

    我在最近的一个项目中使用了它,并且效果很好:https://gist.github.com/krcourville/7309218

    【讨论】:

      猜你喜欢
      • 2017-03-20
      • 1970-01-01
      • 2014-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多