Dom Traversal to automate keyboard focus - spatial navigation

I'm going to start with a little background, which I hope will help my question make more sense.

I am developing a television application. The concept is simple and basically works by laying a browser on the video plane of the TV. Now, being a TV, there is no mouse or additional pointing device. All interaction is carried out using the remote control. Therefore, the user should be able to visually determine which element they are currently focused on. To indicate that the element is focused, I am currently adding a color transparent image above the element to indicate focus.

Now that the user presses the arrow keys, I need to answer by focusing on the correct elements according to the pressed key. So, if the down arrow is pressed, I need to focus on the next custom element in the DOM tree (which can be a child or sibling), and if they fall into the up arrow, I need to answer the previous element. This essentially mimics the spatial navigation in the browser.

I am currently setting the attribute (focusable = true) for any DOM elements that should be able to receive focus. What I would like to do is define the previous or next custom item (i.e. the focusable = true attribute) and apply focus to the item.

I was hoping to cross the DOM tree to define the following and previously custom elements, but I'm not sure how to do this in jQuery or at all.

I was leaning towards trying to use the Jawery methods of the JQuery tree, such as next (), prev (), etc. What approach could you take to solve this problem?

thanks

+4
source share
4 answers

I know this has already been answered, but I just stumbled upon this plugin - http://mike-hostetler.com/jquery-keyboard-navigation-plugin

Looks interesting, right?

+2
source

The trick you may encounter is that it is “down” versus “right” and “left,” etc. if you have content laid out in a table (using an HTML table) (3x3, like a tic-tac-toe board), and you are in the central cell ...

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

the squares 1,2,3,4 will be where you move if you press up, left, right, down ... but in the DOM order they are determined in the order 1,2,3,4

thus, “down” you would need to know to skip “3” and go to “4” ... even worse, there can be any number of “focusable” elements between 3 and 4 if you have a large table. (my simple case is a 3x3 table, but you can have all kinds of nodes, trays, floating nodes, etc.)

HTML example:

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

You might be better off making every custom a button element in which it will be (or you can set) tabIndex ... and then you can use the arrows to move forward / backward (only) through the controls.

Otherwise, you will need to create something smart in order to know "geometrically" what is below, left, up ... from where you are.

+2
source

If you offer a rude answer, do you consider pre-counting the names of the controls?

+1
source

You can use $(element).offset().top and $(element).offset().left to get the absolute positions of all the focusable elements on the page. Then you need to compare the position / size of the [x, w, width, height] element with the elements of the current focused element, taking into account the intended direction of navigation.

For example: If you press UP, you will need to find all the elements ABOVE the current focused element by comparing their offset().top+height() with the focused element offset().top , and then determine which of these elements is closest [to the current focused element]

I started writing code for this, but it seems rather complicated. The idea is this:

 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"); } 

The code above does not actually work ... but it can set you in the right direction.

+1
source

Source: https://habr.com/ru/post/1308898/


All Articles