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

Keyboard navigation: how to go to the next and previous element with arrow keys?

本文关键字:下一个 元素 上一个 导航 何使用 键盘      更新时间:2023-09-26

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

假设水平菜单是这样构建的:
[主页/随机页面/某个页面/另一个页面/等等]

显然它不起作用。以下是我目前所拥有的:

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

谢谢大家的帮助。

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中似乎有一个无关的}

好吧,我检查了你的网站,并稍微修改/扩展了我的代码,试图(几乎)实现我认为你想做的事情。我将不编辑另一个答案,因为它显示了可能更好的方法。。。这个解决方案很有技巧,只是说明这个概念的一种方式。

要查看它,请转到您的任何页面(博客页面除外),然后打开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
        }
    }

不过,请记住,这是一种非常简单的方法,但它应该为你指明正确的方向。如果你还有其他问题,请告诉我。

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

我获取了您的代码,并对其进行了轻微修改,以展示如何使用localStorage。我补充了一些意见,但应该是相对不言自明的。这是:

//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效果——同样,假设你只需要支持更新的浏览器…)