代码之家  ›  专栏  ›  技术社区  ›  Steve

Dom遍历以自动化键盘焦点-空间导航

  •  4
  • Steve  · 技术社区  · 14 年前

    我正在为一台电视机开发一个应用程序。这个概念很简单,基本上是通过将浏览器覆盖在电视的视频平面上来实现的。现在作为一个电视,没有鼠标或额外的指向设备。所有的互动都是通过遥控器完成的。因此,用户需要能够直观地分辨出他们当前关注的元素。为了指示某个元素已聚焦,我当前在该元素上附加了一个彩色透明图像以指示聚焦。

    现在,当用户点击箭头键时,我需要根据所按下的键集中在正确的元素上。因此,如果按下向下箭头,我需要关注DOM树中的下一个可聚焦元素(可能是子元素或兄弟元素),如果他们按下向上箭头,我需要响应上一个元素。这实际上是在浏览器中模拟空间导航。

    我希望遍历DOM树来确定下一个和以前可聚焦的元素,但我不确定如何在JQuery中或一般情况下执行此操作。

    我倾向于尝试使用jquerytreetravesal方法,如next()、prev()等。您将采用什么方法来解决这类问题?

    谢谢

    3 回复  |  直到 14 年前
        1
  •  2
  •   scunliffe    14 年前

    你可能遇到的窍门是“向下”与“向右”与“向左”等。例如,如果你的内容以表格形式排列(使用HTML表格)(3x3类似于tic-tac趾板),而你在中心单元格中。。。

    +-----+-----+-----+
    |     |  1  |     |
    +-----+-----+-----+
    |  2  |  x  |  3  |
    +-----+-----+-----+
    |     |  4  |     |
    +-----+-----+-----+
    

    方块1,2,3,4将是你导航到如果你按下向上,左,右,下。。。但在DOM顺序中,它们的定义顺序是1、2、3、4

    因此,“向下”需要知道跳过“3”转到“4”。。。更糟糕的是,如果您有一个更大的表,那么在3到4之间可能有任意数量的“可聚焦”元素(我的简单例子是一个3x3表,但是可以有各种各样的节点、子节点、浮动节点等。)

    <table>
      <tr>
        <td></td>
        <td>1</td>
        <td></td>
      </tr>
      <tr>
        <td>2</td>
        <td>x</td>
        <td>3</td>
      </tr>
      <tr>
        <td></td>
        <td>4</td>
        <td></td>
      </tr>
    </table>
    

    你最好把每个可聚焦的元素 button ,它将有(或您可以设置)一个tabIndex。。。然后您可以使用箭头向前/向后(仅)通过控件。

        2
  •  1
  •   Steven Sudit    14 年前

    冒着给出粗略答案的风险,您是否考虑过预先计算要访问的控件的名称?

        3
  •  1
  •   David Murdoch    14 年前

    你可以用 $(element).offset().top $(element).offset().left 获取页面上所有可聚焦元素的绝对位置。然后您需要将元素的位置/尺寸[x,w,width,height]与当前聚焦的元素的位置/尺寸进行比较,并考虑导航的预期方向。

    offset().top+height() offset().top

    我开始为此编写代码,但它似乎相当复杂。这个想法是这样的:

    var keys = {"UP":40,"DOWN":38/*etc*/};
    var elements = $(".focusable");
    var focused = $(".focused");
    var positions = calculatePositions(elements); // returns [{"element":element,"dimensions":{"x": x, "y": y, "w": width, "h": height}];
    
    $(document).keypress(e){
        var keycode = e.keycode,
        var candidates;
        // up
        switch (keycode){
            case keys.UP :
                candidates = filterToElementsAbove(focused, positions);
            break;
            case keys.DOWN :
                candidates = filterToElementsBelow(focused, positions);
            break;
            // etc...
            default;
                return true;
        }
        focused.removeClass("focused");
        focused = findClosestElement(focused, candidates).addClass("focused");
    }
    

    上面的代码实际上是行不通的…但它可以为您指明正确的方向。