使用箭头键进行导航

16
问:我是否可以通过箭头键导航在使用JS(使用jQuery)创建的表格中跳转单元格?这个脚本是为Greasemonkey编写的。
答:我想知道是否有可能通过箭头键在我使用JS(使用jQuery)创建的表格中进行导航,也就是跳转单元格...该脚本是为Greasemonkey编写的。
然而,弹出警告可行。只是我不知道如何使它运作良好。
$(document).keydown(function(e){
    if (e.keyCode == 37) { 
       alert( "left pressed " );
       return false;
    }
    if (e.keyCode == 38) { 
       alert( "up pressed " );
       return false;
    }
    if (e.keyCode == 39) { 
       alert( "right pressed " );
       return false;
    }
    if (e.keyCode == 40) { 
       alert( "down pressed " );
       return false;
    }
});
;

希望能得到任何提示或建议。 提前感谢, Faili

更新

看起来我表达得有误。再试一次: 演示

这个可能会给你一个想法。在选择一个输入字段后,可以使用箭头键进行导航。 我的问题是,我无法通过GM和jQuery实现它。 有什么想法吗?

再次感谢您的时间和努力。

最终结果就像这样:


function myTest_analysis1(e,leftkey,up,right,down){
    myTest(e,'','','field_analysis2','field_communication1')

function myTest(e,leftkey,up,right,down)
{
  if (!e) e=window.event;
  var selectArrowKey;
  switch(e.keyCode)
  {
  case 37:
    // Key left.
    selectArrowKey = leftkey;
    break;
  case 38:
    // Key up.
    selectArrowKey = up;
    break;
  case 39:
    // Key right.
    selectArrowKey = right;
    break;
  case 40:
    // Key down.
    selectArrowKey = down;
    break;
  }
  if (!selectArrowKey) return;  
  var controls = window.document.getElementById(selectArrowKey);
  if (!controls) return;
  controls.focus();
}
}
 $('#field_analysis1').keydown (myTest_analysis1);

我个人是这样做的。我相信有更聪明的解决方案,但我现在还想不出来。

非常感谢您的时间和努力。


1
请解释一下“浏览表格”的含义。 - Gabriele Petrioli
我有一个包含许多行和单元格的表格。例如,按左箭头键应将焦点从当前单元格更改为左侧相邻单元格。 - Faili
这样导航的目的是什么?单元格中有可激活链接吗?单元格本身不是天然的焦点元素。您可以通过编写tabIndex属性并使用:focus规则进行样式设置来将其变为可聚焦元素,但聚焦单元格可能会有哪些交互? - bobince
我会尽快回复你。我工作的房间太暖了。 - Faili
3个回答

21
这里有一个版本可以实现以下功能:
  1. 在表格开头和结尾(第一个和最后一个单元格)施加约束
  2. 在每行末尾换行并移动到下一行
  3. 如果需要滚动才能看到当前单元格,则滚动它以使其可见
  4. 支持用鼠标点击选中单元格

演示见https://jsfiddle.net/BdVB9/


使用的 HTML 结构如下:

<table id="navigate">
    <tbody>
        <tr>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
        <tr>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
        </tr>
    </tbody>
</table>

还有JavaScript

var active = 0;

$(document).keydown(function(e){
    reCalculate(e);
    rePosition();
    return false;
});
    
$('td').click(function(){
   active = $(this).closest('table').find('td').index(this);
   rePosition();
});


function reCalculate(e){
    var rows = $('#navigate tr').length;
    var columns = $('#navigate tr:eq(0) td').length;
    //alert(columns + 'x' + rows);
    
    if (e.keyCode == 37) { //move left or wrap
        active = (active>0)?active-1:active;
    }
    if (e.keyCode == 38) { // move up
        active = (active-columns>=0)?active-columns:active;
    }
    if (e.keyCode == 39) { // move right or wrap
       active = (active<(columns*rows)-1)?active+1:active;
    }
    if (e.keyCode == 40) { // move down
        active = (active+columns<=(rows*columns)-1)?active+columns:active;
    }
}

function rePosition(){
    $('.active').removeClass('active');
    $('#navigate tr td').eq(active).addClass('active');
    scrollInView();
}

function scrollInView(){
    var target = $('#navigate tr td:eq('+active+')');
    if (target.length)
    {
        var top = target.offset().top;
        
        $('html,body').stop().animate({scrollTop: top-100}, 400);
        return false;
    }
}

11

你应该能够聚焦在不同的单元格上,我将使用 .focus() 来举例。

这是示例:

请记住...

a) 这个示例中没有阻止你越界的代码,你需要限制 currentRow 和 currentCell 的值以避免超出单元格数量并防止它们小于 0。

b) 目前还没有代码来移除绿色文本,这是我用来显示当前焦点的。这意味着会留下一条绿色轨迹。

你可以相当容易地解决以上两个问题,但这会使示例变得更复杂...

    var currentRow = 0;
    var currentCell = 0;

    function ChangeCurrentCell() {
        var tableRow = document.getElementsByTagName("tr")[currentRow];
        var tableCell = tableRow.childNodes[currentCell];
        tableCell.focus();
        tableCell.style.color = "Green";
    }
    ChangeCurrentCell();

    $(document).keydown(function(e){
        if (e.keyCode == 37) { 
           currentCell--;
           ChangeCurrentCell();
           return false;
        }
        if (e.keyCode == 38) { 
           currentRow--;
           ChangeCurrentCell();
           return false;
        }
        if (e.keyCode == 39) { 
           currentCell++;
           ChangeCurrentCell();
           return false;
        }
        if (e.keyCode == 40) { 
           currentRow++;
           ChangeCurrentCell();
           return false;
        }
    });

我觉得我没有很好地解释清楚自己。无论如何,谢谢你给了一些提示 :-) - Faili
我将此标记为已解决,因为它易于理解并可能对他人有所帮助。 - Faili
@sohnee,我需要你的帮助。假设所有的<td>都有输入文本框,如何在它们之间移动呢?谢谢。 - aas

10

这是我的版本...

演示

var active;
$(document).keydown(function(e){
    active = $('td.active').removeClass('active');
    var x = active.index();
    var y = active.closest('tr').index();
    if (e.keyCode == 37) { 
       x--;
    }
    if (e.keyCode == 38) {
        y--;
    }
    if (e.keyCode == 39) { 
        x++
    }
    if (e.keyCode == 40) {
        y++
    }
    active = $('tr').eq(y).find('td').eq(x).addClass('active');
});​

2
有两件事情需要注意:第一,在事件处理程序中需要使用 return false; 来阻止页面在有滚动条的情况下滚动;第二,如果当前激活的单元格不可见,则需要将其滚动到屏幕上可见的位置。示例 - Andy E
干得好,Reigel。我需要一个帮忙,假设所有的td都有输入文本框,如何在它们之间移动呢?谢谢。 - aas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接