【问题标题】:Dom Traversal to Automate Keyboard Focus - Spatial Navigation用于自动化键盘焦点的 Dom 遍历 - 空间导航
【发布时间】:2010-05-05 15:33:55
【问题描述】:

我将从一些背景知识开始,希望能帮助我的问题更有意义。

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

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

我目前正在为任何应该能够接收焦点的 DOM 元素设置一个属性 (focusable=true)。我想做的是确定上一个或下一个可聚焦元素(即属性focusable = true)并将焦点应用于元素。

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

我倾向于尝试使用 JQuery 树遍历方法,例如 next()、prev() 等。您会采取什么方法来解决此类问题?

谢谢

【问题讨论】:

  • 我们可以获取一些示例 HTML 吗?
  • 我建议将 CSS 类设置为“可聚焦”而不是属性,除非您选择 HTML5“数据”属性样式。
  • 出于好奇,为什么这两种方式都重要,因为两者本质上都是为了将​​元素标记为可聚焦的。
  • 因为它不是元素的实际有效属性。

标签: jquery dom navigation


【解决方案1】:

您可能会遇到的技巧是“向下”与“右”与“左”等。如果您将内容布置为表格(使用 HTML 表格)(3x3,如井字棋盘)并且您位于中心单元格中...

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

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

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

示例 HTML:

<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】:

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

    【讨论】:

    • 我不确定我理解你的意思。你能详细说明一下吗?
    • @Steve:我建议您在发出 HTML 时在 Web 服务器上解决此问题,而不是在 JS 中的 Web 客户端中解决。如果您的屏幕布局相当稳定,您可以硬编码任何给定控件的左、右、上和下“邻居”的 ID。然后 JS 将只需要检索该 ID 并使用它来查找控件。诚然,这很粗糙,可能难以维护,但我将其作为可行的解决方案提供。
    • 谢谢。这种方法的唯一问题(至少在我的情况下)是没有提供页面的 Web 服务器,我没有提到。这些页面本质上是静态的并安装在电视上,并且只能在客户端进行更新。
    • 如果它们真的是静态的,它们可以被硬编码。但如果它们是在客户端更新的,那么无论这种更新做什么都必须嵌入 LRUD 名称。
    【解决方案3】:

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

    例如:如果按下 UP,您将需要通过比较它们的 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");
    }
    

    上面的代码实际上并不能工作......但它可以让你朝着正确的方向前进。

    【讨论】:

      猜你喜欢
      • 2012-10-14
      • 1970-01-01
      • 2019-06-13
      • 1970-01-01
      • 2022-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多