简体   繁体   中英

How can I identify the previous/next link in a sequence of unordered and/or nested lists using vanilla Javascript?

I'm trying to wrap my head around this scenario.

Using vanilla Javascript, I need to identify the previous and next <a> elements, given any given link within n -number of unordered lists of n depth.

So here's an example structure of what I mean:

<ul>
    <li><a href="http://www.example.com/">Link 1</a></li>
    <li><a href="http://www.example.com/">Link 2</a></li>
    <li><a href="http://www.example.com/">Link 3</a></li>
</ul>

<ul>
    <li><a href="http://www.example.com/">Link 4</a></li>
    <li><a href="http://www.example.com/">Link 5</a>

    <ul>
        <li><a href="http://www.example.com/">Link 6</a></li>
        <li><a href="http://www.example.com/">Link 7</a></li>
    </ul></li>

    <li><a href="http://www.example.com/">Link 8</a></li>
</ul>

<ul>
    <li><a href="http://www.example.com/">Link 9</a></li>
</ul>

Link 8's previous is Link 7 and its next is Link 9.

Link 9's previous is Link 8 and its next is Link 1.

And so on.

At one level of structure, I was able to work this out with something like this:

function linkNext(currentFocus) {

    currentFocus = currentFocus || document.activeElement;

    var theNextElement;

    if (currentFocus.parentNode.nextElementSibling === null) { // Last <li> in list.
        if (currentFocus.parentNode.parentNode.nextElementSibling === null) { // Last list in bar.
            theNextElement = window.barbarbar.querySelector('a');
        } else {
            theNextElement = currentFocus.parentNode.parentNode.nextElementSibling.querySelector('a');
        }
    } else {
        theNextElement = currentFocus.parentNode.nextElementSibling.querySelector('a');
    }

    return theNextElement;

}

function linkPrev(currentFocus) {

    currentFocus = currentFocus || document.activeElement;

    var thePrevElement;

    if (currentFocus.parentNode.previousElementSibling === null) { // First <li> in list.
        if (currentFocus.parentNode.parentNode.previousElementSibling === null) { // First list in bar.
            thePrevElement = window.barbarbar.querySelector('a:last-of-type');
        } else {
            thePrevElement = currentFocus.parentNode.parentNode.previousElementSibling.querySelector('li:last-of-type a');
        }
    } else {
        thePrevElement = currentFocus.parentNode.previousElementSibling.querySelector('a');
    }

    return thePrevElement;

}

But this stops working beyond that single level of depth and I'm having difficulty wrapping my head around a potential solution. And even if I were using jQuery (which I'm not), even something like .closest() or .parents() doesn't seem like it would quite fit.

Is there perhaps a better method of doing this? Do I really even need to do tree traversal here?

It seems to me that you just need to keep a list of all links and find the position of the current link:

var links = Array.prototype.slice.call(document.querySelectorAll('a'));
var index = links.indexOf(currentFocus);
// nextLink = links[index - 1];
// previousLink = links[index + 1];

(plus some logic for wrapping around)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM