Опера клавиатура навигации - PullRequest
1 голос
/ 07 января 2010

Мне интересно, как браузер Opera реализует навигацию с помощью клавиатуры, где вы можете сделать Shift + ( & uarr; , & darr; , & larr ; или & rarr; ) и вы путешествуете по ряду или столбцу.

Как бы вы реализовали это в JavaScript?

Ответы [ 3 ]

5 голосов
/ 07 января 2010

Вот отправная точка:

function getCentrePosition(el) {
    var x= el.offsetWidth/2, y= el.offsetHeight/2;
    while (el!==null && el.nodeType==1) {
        x+= el.offsetLeft;
        y+= el.offsetTop;
        el= el.offsetParent;
    }
    return [x, y];
}

function arrowKeyHandler(event) {
    if (event===undefined) event= window.event;
    if (!event.shiftKey) return true;

    // Detect which arrow key is pressed. Make a matrix to rotate each
    // case onto the default case for left-pressed.
    //
    var m;
    if (event.keyCode===37) m= [[1,0], [0,1]]; // left
    else if (event.keyCode===38) m= [[0,1], [-1,0]]; // up
    else if (event.keyCode===39) m= [[-1,0], [0,-1]]; // right
    else if (event.keyCode===40) m= [[0,-1], [1,0]]; // down
    else return true;

    // Find link with shortest distance in left and vertical directions.
    // Disregard any links not left of the current link.
    //
    var pos= getCentrePosition(this);
    var bestlink= null, bestdist= null;
    for (var i= document.links.length; i-->0;) {
        var otherpos= getCentrePosition(document.links[i]);
        var dx= (otherpos[0]-pos[0])*m[0][0] + (otherpos[1]-pos[1])*m[0][1];
        var dy= (otherpos[0]-pos[0])*m[1][0] + (otherpos[1]-pos[1])*m[1][1];
        if (dx>=0) continue;
        var dist= Math.abs(dx)+Math.abs(dy)*3; // arbitrary biasing factor
        if (bestdist===null || dist<bestdist) {
            bestlink= document.links[i];
            bestdist= dist;
        }
    }

    // Focus closest link in that direction, if any
    //
    if (bestlink!==null)
        bestlink.focus();
    return false;
}

// Add to each link on-page, except on Opera which already does it
//
if (!window.opera)
    for (var i= document.links.length; i-->0;)
        document.links[i].onkeydown= arrowKeyHandler;

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

0 голосов
/ 05 августа 2016

Это можно быстро и легко сделать в CSS. Прочитайте здесь:

https://dev.opera.com/tv/tweaking-spatial-navigation-for-tv-browsing/

<a id="1" href="#" style="nav-up: #3; nav-right: #2;">Link 1</a>
<a id="2" href="#">Link 2</a>
<a id="3" href="#">Link 3</a>

В этом примере, если фокус был на Link 1, а пользователь удерживал Shift и нажимал Right, фокус переместился бы на Link 2. Если пользователь удерживал Shift и нажимал Up, фокус переместился бы на Link 3, независимо от того, где ссылки были расположены на странице.

0 голосов
/ 13 сентября 2011

Вы также можете вызывать такие функции, как document.moveFocusUp () и document.moveFocusDown () ... но это будет немного обманывать, я думаю, и это будет работать только в Opera;)

(эти методы подключаются к встроенной логике для «пространственной навигации», т. Е. Перемещая фокус на ссылку или кнопку Opera считает наилучшее совпадение в заданном направлении)

...