Dom Traversal для автоматизации фокусировки клавиатуры - Пространственная навигация

Я собираюсь начать с небольшого фона, который, надеюсь, поможет моему вопросу иметь больше смысла.

Я разрабатываю приложение для телевидения. Концепция проста и в основном работает наложением браузера на видеоплоскость телевизора. Теперь, будучи телевизором, нет мыши или дополнительного указательного устройства. Все взаимодействие осуществляется через пульт дистанционного управления. Следовательно, пользователь должен иметь возможность визуально определить, на каком элементе он в данный момент сфокусирован. Чтобы указать, что элемент сфокусирован, я в настоящее время добавляю цветное прозрачное изображение поверх элемента, чтобы указать фокус.

Теперь, когда пользователь нажимает клавиши со стрелками, мне нужно ответить, сосредоточив внимание на правильных элементах в соответствии с нажатой клавишей. Итак, если нажата стрелка вниз, мне нужно сосредоточиться на следующем фокусируемом элементе в дереве DOM (который может быть дочерним или родным), а если они нажимают стрелку вверх, мне нужно ответить на предыдущий элемент. Это по существу имитирует пространственную навигацию в браузере.

В настоящее время я устанавливаю атрибут (focusable = true) для любых элементов DOM, которые должны иметь возможность получать фокус. Я хотел бы определить предыдущий или следующий фокусируемый элемент (то есть атрибут focusable = true) и применить фокус к элементу.

Я надеялся пройтись по дереву DOM, чтобы определить следующие и ранее фокусируемые элементы, но я не уверен, как это сделать в JQuery или вообще.

Я склонялся к попыткам использовать методы обхода дерева JQuery, такие как next (), prev () и т. д. Какой подход вы бы использовали для решения проблемы такого типа?

Спасибо

4 голоса | спросил Steve 5 Maypm10 2010, 19:33:55

3 ответа


0

Уловка, с которой вы можете столкнуться, это то, что «вниз» против «вправо» против «слева» и т. д. Например. если у вас есть содержимое в виде таблицы (с использованием таблицы HTML) (3х3, как в крестики-нолики), и вы находитесь в центральной ячейке ...

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

квадраты 1, 2, 3, 4 - это место, к которому вы переходите, если нажимаете вверх, влево, вправо, вниз ... но в порядке DOM они определены в порядке 1,2,3,4

Таким образом, «down» нужно знать, чтобы пропустить «3» и перейти к «4» ... еще хуже, может быть любое количество «фокусируемых» элементов от 3 до 4, если у вас таблица большего размера. (мой простой случай - таблица 3х3, но вы можете иметь все виды узлов, подузлов, плавающих узлов и т. д.)

Пример 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. .. а затем вы можете использовать стрелки для перехода вперед /назад (только) через элементы управления.

В противном случае вам нужно будет создать что-то достаточно умное, чтобы «геометрически» узнать, что внизу, слева, вверх… от того, где вы находитесь.

ответил scunliffe 5 Maypm10 2010, 19:47:30
0

Вы рискуете предложить грубый ответ? Рассматривали ли вы предварительный расчет названий элементов управления, к которым нужно перейти?

ответил Steven Sudit 5 Maypm10 2010, 19:48:50
0

Вы можете использовать $(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");
}

Приведенный выше код на самом деле не будет работать ... но он может направить вас в правильном направлении.

ответил David Murdoch 5 Maypm10 2010, 19:53:04

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132