键盘导航:如何使用箭头键转到下一个和上一个元素?

时间:2012-02-04 23:14:02

标签: javascript arrays keyboard navigation

我正在尝试使用键盘导航构建网站。我希望用户能够使用左箭头和右箭头浏览五到六页的菜单。 无论用户在哪个页面上,我都希望他/她在按下左/右箭头时在菜单中返回/前进。

假设水平菜单以这种方式构建:
[主页/随机页面/某些页面/另一页/等等]

显然它不起作用。以下是我到目前为止的情况:

document.onkeyup = KeyCheck;       

var pages = ["index.php", "random-page.php", "some-page.php", "another-page.php", "and-so-on.php"];

function leftarrowpressed() {
    location.href = pages[0]-1;
}

function rightarrowpressed() {
    location.href = pages[0]+1;
    }
} 

function KeyCheck(e)
    {
       var KeyID = (window.event) ? event.keyCode : e.keyCode;

       switch(KeyID)
       {

 // left arrow key
         case 37:
         leftarrowpressed()    
          break;

//  right arrow key
          case 39:
          rightarrowpressed() 
          break;

       }
    }

谢谢大家的帮助。

3 个答案:

答案 0 :(得分:1)

pages[0]-1将评估为"index.php"-1 NaN。您不希望从页面URL中减去1(基本上不能从字符串中减去) - 而是从索引中减去1以获取上一页。另外,守护边界:

location.href = pages[ Math.max(0, 0 - 1) ];

location.href = pages[ Math.min(pages.length - 1, 0 + 1) ];

我猜您会自动将0替换为当前页面的索引。

其次,您似乎在}中有一个无关的rightarrowpressed

答案 1 :(得分:1)

好吧,我检查了你的网站并稍微修改/扩展了我的代码,试图(几乎)实现我认为你想做的事情。我将把未经编辑的其他答案留下来,因为它显示了这可能是一个更好的方法...这个解决方案相当黑客,只是一种说明这个概念的方法。

要查看它,请转到您的任何页面(博客页面除外),然后打开webkit检查器(我的代码只能在WebKit(chrome / safari)中使用),尽管它很容易使其工作任何浏览器)并在javascript控制台中输入以下内容:

    document.querySelector("footer").setAttribute("style","position:fixed;bottom:0px;width:100%;");
    document.querySelector("header").setAttribute("style","position:fixed;top:0px;width:100%;");

    var pages           =       ["accueil","references","cv","contact","aide","blog"],
    classNames          =       ["accueil","ref","cv","contact","aide","blog"],
    pageUrls            =       ["","references.php","cv.php","contact.php","aide.php","blog/"]
    baseUrl             =       "http://maximelaforet.com/",
    currentPageIndex    =       pageUrls.indexOf(window.location.href.replace(baseUrl,"")),
    pageDivs            =       [1,1,1,1,1,1];

    pageDivs[currentPageIndex] = document.querySelector("div.content");
    pageDivs[currentPageIndex].id = pages[currentPageIndex]+"Page";
    pageDivs[currentPageIndex].setAttribute("style","-webkit-transition:all 1s ease-in-out;position:fixed;top:63px;width:100%;height:"+(window.innerHeight - 270)+"px;overflow:scroll;");

    for (var i=0; i<pageUrls.length;i++)
    {
        if (i!=currentPageIndex)
        {
            var pageGrabber = new XMLHttpRequest();
            pageGrabber.open("GET","http://maximelaforet.com/" + pageUrls[i], false);
            pageGrabber.send(null);

            if (pageGrabber.status==200)
            {
                var temp = document.createElement("div");
                temp.innerHTML = pageGrabber.response;

                if (pages[i]!="blog")
                pageDivs[i] = temp.querySelector("div.content").cloneNode(true);
                else
                pageDivs[i] = temp.querySelector("div#page").cloneNode(true);
            }

            pageDivs[i].id = pages[i]+"Page";
            pageDivs[i].setAttribute("style","-webkit-transition:-webkit-transform 1s ease-in-out;position:fixed;top:63px;width:100%;height:"+(window.innerHeight - 270)+"px;overflow:scroll;");
            if (i<currentPageIndex)
            pageDivs[i].style.webkitTransform = "translate3d(-100%,0,0)";
            else
            pageDivs[i].style.webkitTransform = "translate3d(100%,0,0)";

            document.body.appendChild(pageDivs[i]);
        }
    }

    window.addEventListener("keyup", KeyCheck, true);
    function KeyCheck(e)
    {
        e.preventDefault();
        e.stopPropagation();
        var KeyID = (window.event) ? event.keyCode : e.keyCode;

        switch(KeyID)
        {
            // left arrow key
            case 37:
            if (currentPageIndex == 0)//we're at the first page, go to the last
            currentPageIndex = pages.length - 1;//-1 to account for first index being "0"
            else//go to the previous page
            pageDivs[currentPageIndex].style.webkitTransform = "translate3d(100%,0,0)";
            pageDivs[currentPageIndex-1].style.webkitTransform = "translate3d(0,0,0)";
            document.querySelector("header").classList.remove(classNames[currentPageIndex]);
            document.querySelector("header").classList.add(classNames[currentPageIndex-1]);

            if (classNames[currentPageIndex] == "accueil")
            document.querySelector("li > a[class~='"+classNames[currentPageIndex]+"']").classList.toggle("current_acc");
            else
            document.querySelector("li > a[class~='"+classNames[currentPageIndex]+"']").classList.toggle("current_"+classNames[currentPageIndex]);
            if (classNames[currentPageIndex] == "accueil")
            document.querySelector("li > a[class~='"+classNames[currentPageIndex-1]+"']").classList.toggle("current_acc");
            else
            document.querySelector("li > a[class~='"+classNames[currentPageIndex-1]+"']").classList.toggle("current_"+classNames[currentPageIndex-1]);

            currentPageIndex--;
            break;
            //  right arrow key
            case 39:
            if (currentPageIndex == (pages.length - 1))//if we're at the last page, go to the first
            currentPageIndex = 0;
            else//go to the next page
            pageDivs[currentPageIndex].style.webkitTransform = "translate3d(-100%,0,0)";
            pageDivs[currentPageIndex+1].style.webkitTransform = "translate3d(0,0,0)";

            document.querySelector("header").classList.remove(classNames[currentPageIndex]);
            document.querySelector("header").classList.add(classNames[currentPageIndex+1]);

            if (classNames[currentPageIndex] == "accueil")
            document.querySelector("li > a[class~='"+classNames[currentPageIndex]+"']").classList.toggle("current_acc");
            else
            document.querySelector("li > a[class~='"+classNames[currentPageIndex]+"']").classList.toggle("current_"+classNames[currentPageIndex]);
            if (classNames[currentPageIndex] == "accueil")
            document.querySelector("li > a[class~='"+classNames[currentPageIndex+1]+"']").classList.toggle("current_acc");
            else
            document.querySelector("li > a[class~='"+classNames[currentPageIndex+1]+"']").classList.toggle("current_"+classNames[currentPageIndex+1]);

            currentPageIndex++;
            break;
            default:
            var noChange = true;//just so we can ignore the rest if a boring key
        }

    }

请记住,这是一种非常黑客的做法,但它应该指向正确的方向。如果您有更多问题,请与我们联系。

答案 2 :(得分:0)

好吧,在我看来,你需要知道每次你当前在哪个页面上工作。为此,我建议使用window.localStorage if(且仅当)A)所有页面都来自同一个域,并且B)您不需要支持旧浏览器。如果其中任何一个都是不真实的,这个方法就行不通了,你需要做一些其他事情,比如解析URL字符串。

我拿了你的代码并稍微修改它以显示你如何使用localStorage。我添加了一些评论,但它应该是相对不言自明的。这是'tis:

//if current index don't exist, make it
if (!window.localStorage.currentPageIndex)
{
    window.localStorage.currentPageIndex = 0;//frustratingly, it gets stringified anyway - you have to parseInt later
}

//set up vars
var pages        = ["index.php", "random-page.php", "some-page.php", "another-page.php", "and-so-on.php"],
currentPageIndex = parseInt(window.localStorage.currentPageIndex);//as promised

//set event listener on window
window.addEventListener("keyup", KeyCheck);
function KeyCheck(e)
{
    var KeyID = (window.event) ? event.keyCode : e.keyCode;

    switch(KeyID)
    {
            // left arrow key
        case 37:
            if (currentPageIndex == 0)//we're at the first page, go to the last
                currentPageIndex = pages.length - 1;//-1 to account for first index being "0"
            else//go to the previous page
                currentPageIndex--;   
            break;
            //  right arrow key
        case 39:
            if (currentPageIndex == (pages.length - 1))//if we're at the last page, go to the first
                currentPageIndex = 0;
            else//go to the next page
                currentPageIndex++;
            break;
        default:
            var noChange = true;//just so we can ignore the rest if a boring key
    }

    if (!noChange)//haha, I love double negatives
    {
        //now dump the new current page index back into localStorage
        window.localStorage.currentPageIndex = currentPageIndex;

        //first, try it in your javascript console to make sure it works (refresh the page!)
        console.log(pages[currentPageIndex],currentPageIndex);
        //then use real urls and uncomment the next line to go to the new current page!
        //location.href = pages[currentPageIndex]
    }
}

但是 - 我要问 - 你真的想这样做吗?这是很多HTTP请求并刷新页面 - 页面是否足够小,你可以一次加载它们,而且一次只显示一个? (你甚至可以在页面之间做一个很酷的滑动或疯狂的3D效果 - 再次,假设你只需要支持更新的浏览器......)