3

$("#prev").click(function() {
  var elems = $('#smallTitle li a');
  var prev = elems.filter('.action');
  if ( prev.length === 0 ) prev = elems.last();

  elems.not( prev.addClass('action') ).removeClass('action');
});

$("#next").click(function() {
  var elems = $('#smallTitle li a');
  var next = elems.filter('.action').next();
  if ( next.length === 0 ) next = elems.first();

  elems.not( next.addClass('action') ).removeClass('action');
});
.SwitchURL-small-list{
    display:flex;
    list-style:none;
    font-size: 22px;
    font-weight:bold;
}

.SwitchURL-smaill-item{
    border-bottom: 0px solid#AE96DA;
    padding: 0 1%;
    margin-bottom: 1%;
    font-size: 20px;
}

.SwitchURL-small-link{
    color: #CFC1E9;
    margin-right: 15px;
    margin-left: 15px;
}

.SwitchURL-small-link:hover{
    color: #AE96DA;
}

.SwitchURL-small-link.action {
    border-bottom: 2px solid#AE96DA;
    color: #AE96DA;
    margin-right: 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<ul class="SwitchURL-small-list" id="smallTitle">
  <button id="prev" type="button"> > </button>

  <li class="SwitchURL-small-item">
    <a href="AA" class="SwitchURL-small-link action" id="SwitchURL0">AA</a>
  </li>
  <li class="SwitchURL-small-item">
      <a href="BB" class="SwitchURL-small-link" id="SwitchURL1">BB</a>
  </li>
  <li class="SwitchURL-small-item">
      <a href="CC" class="SwitchURL-small-link" id="SwitchURL2">CC</a>
  </li>
  <li class="SwitchURL-small-item">
      <a href="DD" class="SwitchURL-small-link" id="SwitchURL3">DD</a>
  </li>
  <li class="SwitchURL-small-item">
      <a href="EE" class="SwitchURL-small-link" id="SwitchURL4">EE</a>
  </li>

  <button id="next" type="button"> > </button>
</ul>

I have a <li> element, and inside the <li> is use href to let user click to the corresponding file,

The <li> is look like:

enter image description here

Now <li> selection is "AA", then when I click the next(>) button,

<li> selection will be dynamic change to "BB", like this image:

enter image description here

or when I click the previous(<) button,

<li> selection will be dynamic change to "EE", like this image:

enter image description here

And the AA file which is display now will also dynamic change to BB or EE file, too.

Tips: it may be will use removeClass("action") and addClass("action") to make <li> change, but I try many times, it cannot achieve my target.

Can anyone help me? Thank you ;]

Mister Jojo
  • 20,093
  • 6
  • 21
  • 40
ChaCha
  • 67
  • 5

5 Answers5

2

Best way I can think of to do this is keep track of the current "action" index, increment / decrement that when clicking the buttons and iterate the list of links, toggling the action class based on the index.

const links = $(".SwitchURL-small-link")
const modulo = links.length
let selectedIndex = links.index(".action")

$("#smallTitle button").on("click", function() {
  const inc = this.id === "next" ? 1 : -1
  selectedIndex = (((selectedIndex + inc) % modulo) + modulo) % modulo
  
  links.each((index, link) => {
    link.classList.toggle("action", index === selectedIndex)
  })
})
.SwitchURL-small-list {
  list-style: none;
  display: flex;
  justify-content: space-evenly;
  margin: 0;
  padding: 0;
}

.SwitchURL-small-link.action {
  border-bottom: 2px solid#AE96DA;
  color: #AE96DA;
}
<!-- minified the HTML from your question -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <ul class="SwitchURL-small-list" id="smallTitle"><li class="SwitchURL-smaill-item"> <button id="prev" type="button"> &lt; </button></li><li class="SwitchURL-small-item"> <a href="AA" class="SwitchURL-small-link action" id="SwitchURL0">AA</a></li><li class="SwitchURL-small-item"> <a href="BB" class="SwitchURL-small-link" id="SwitchURL1">BB</a></li><li class="SwitchURL-small-item"> <a href="CC" class="SwitchURL-small-link" id="SwitchURL2">CC</a></li><li class="SwitchURL-small-item"> <a href="DD" class="SwitchURL-small-link" id="SwitchURL3">DD</a></li><li class="SwitchURL-small-item"> <a href="EE" class="SwitchURL-small-link" id="SwitchURL4">EE</a></li><li class="SwitchURL-smaill-item"> <button id="next" type="button"> &gt; </button></li></ul>

See JavaScript % (modulo) gives a negative result for negative numbers regarding the fancy modulo arithmetic.

Phil
  • 157,677
  • 23
  • 242
  • 245
1

I suppose this should work. The comments should help you understand the steps. You can remove them once you understand how the code works.

For your JavaScript:

$('#prev').click(function () {
  // the array of all five links
  var elems = $('#smallTitle li a');
  // get the index of the currently active link
  var activeIndex;
  for (var i = 0; i < elems.length; i++) {
    if (elems[i].classList.contains('action')) {
      activeIndex = i;
      break;
    }
  }
  
  // get the index of the previous link
  var prevIndex = activeIndex - 1;
  if (prevIndex === -1) prevIndex = elems.length - 1;
  
  // change the active classes
  elems[activeIndex].classList.remove('action');
  elems[prevIndex].classList.add('action');
});

$('#next').click(function () {
  // the array of all five links
  var elems = $('#smallTitle li a');
  // get the index of the currently active link
  var activeIndex;
  for (var i = 0; i < elems.length; i++) {
    if (elems[i].classList.contains('action')) {
      activeIndex = i;
      break;
    }
  }

  // get the index of the next link
  var nextIndex = activeIndex + 1;
  if (nextIndex === elems.length) nextIndex = 0;

  // change the active classes
  elems[activeIndex].classList.remove('action');
  elems[nextIndex].classList.add('action');
});
Obum
  • 1,485
  • 3
  • 7
  • 20
0

so simple in JS:

(function() // IIFE closure to protect variables
  {
  const
    links    = [...document.querySelectorAll('.SwitchURL-small-list >li > a.SwitchURL-small-link')]
  , len      = links.length
  , setActiv = n => links.forEach((el,ix)=> el.classList.toggle('action', ix===n))
    ;
  let  activItem = 0
  setActiv(activItem)
 
  document.querySelector('#prev').onclick = () =>
    {
    activItem = (activItem -1 + len) % len
    setActiv(activItem)
    }
  document.querySelector('#next').onclick = () =>
    {
    activItem = (activItem +1) % len
    setActiv(activItem)
    } 
  }
)()
ul {
  list-style  : none;
  font-size   : 2em;
  font-family : Arial, Helvetica, sans-serif;
  }
li {
  display : inline-block;
  width   : 1.3em;
  }
li a {
  color           : #d2bfe7;
  text-decoration : none;
  }
li a.action {
  color : #c249a4
  }
button {
  color      :  #7f7f7f;
  border     : none;
  background : none;
  font-size  : 1.4em;
  }
<ul class="SwitchURL-small-list" id="smallTitle">
  <button id="prev" type="button"> &lt; </button>

  <li class="SwitchURL-small-item">
    <a href="AA" class="SwitchURL-small-link" >AA</a>
  </li>
  <li class="SwitchURL-small-item">
    <a href="BB" class="SwitchURL-small-link" >BB</a>
  </li>
  <li class="SwitchURL-small-item">
    <a href="CC" class="SwitchURL-small-link" >CC</a>
  </li>
  <li class="SwitchURL-small-item">
    <a href="DD" class="SwitchURL-small-link" >DD</a>
  </li>
  <li class="SwitchURL-small-item">
    <a href="EE" class="SwitchURL-small-link" >EE</a>
  </li>

  <button id="next" type="button"> &gt; </button>
</ul>
Mister Jojo
  • 20,093
  • 6
  • 21
  • 40
0

Here is a vanilla JavaScript example. I added a data-id attribute to each list-item that corresponds with its index for that nodeList. I also added a class to all potential clickable items including buttons, buttons I added the class button and btn, so we can evaluate classList containing next, prev and buttons to add proper logic to conditionals. We also wrap our buttons in list-item tags.

Then I used the [nodeList.length - 1] as index to get last list-item and nodeList[0] to get first list-item. We run conditionals for both next and prev buttons => if e.target.classList.contains('next') we check the current list-item, current = document.querySelector('.action'), is the last, if it is, we set the index to 0. If prev is in classList, and index is 0, we set index to [nodeList.length - 1]. We then either increment on next or decrement on prev. It the event.target is a list-item we set the event.target.classList.add('action').

const buttons = document.querySelectorAll('.btn')
const smallItem = document.querySelectorAll('.SwitchURL-small-item')

function moveSelection(e) {
  // define the current set listitem
  let current = document.querySelector('.action')
  // remove the current actions class
  current.classList.remove('action')
  // define the event target
  const target = e.target
  // get the list-items dataset id
  let data = parseInt(current.parentNode.dataset.id)
  // conditional to check for next and prev buttons
  target.classList.contains('button') ?
    // conditional for next buttons
    target.classList.contains('next') ?
    // check if the list-item is the last one
    data === smallItem.length - 1 ?
    // lets add the action to the first list-item
    smallItem[0].children[0].classList.add('action') :
    // else lets add the data-id by one 
    // to get the index of the next element
    smallItem[data + 1].children[0].classList.add('action') : // we have the previous button
    // if we are on the first list-item
    data === 0 ?
    // set the action class to the last list-item
    // using smallItem.length - 1 to match 
    // proper index, 5 - 1 = 4 
    smallItem[smallItem.length - 1].children[0].classList.add('action') :
    // else we decrement the index by one
    smallItem[data - 1].children[0].classList.add('action') :
    // event target is a "small item" simply assign
    // it to the event target using classList.add()
    target.classList.add('action')
}

// iterate over all buttons 
buttons.forEach(btn => {
  // add event listener to each button and pass in 
  // callback for logic to determine button being clicked
  btn.addEventListener('click', moveSelection)
})
.SwitchURL-small-list {
  display: flex;
  list-style: none;
  font-size: 22px;
  font-weight: bold;
}

.SwitchURL-small-item {
  border-bottom: 0px solid#AE96DA;
  padding: 0;
  margin-bottom: 0;
  font-size: 20px;
  flex: 0;
}

.SwitchURL-small-link {
  color: #CFC1E9;
}

.SwitchURL-small-link:hover {
  color: #AE96DA;
}

.SwitchURL-small-link.action {
  border-bottom: 2px solid#AE96DA;
  color: #AE96DA;
}


/* added to control width of buttons */

.btn {
  flex: 0;
}


/* added for left margin of all buttons execpt first one */

li~li {
  margin-left: 1rem;
}

.prev {}
<ul class="SwitchURL-small-list" id="smallTitle">
  <li>
    <button class="btn button prev"> prev </button>
  </li>

  <li data-id="0" class="btn SwitchURL-small-item">
    <a href="#" class="SwitchURL-small-link action" id="SwitchURL0">AA</a>
  </li>

  <li data-id="1" class="btn SwitchURL-small-item">
    <a href="#" class="SwitchURL-small-link" id="SwitchURL1">BB</a>
  </li>

  <li data-id="2" class="btn SwitchURL-small-item">
    <a href="#" class="SwitchURL-small-link" id="SwitchURL2">CC</a>
  </li>

  <li data-id="3" class="btn SwitchURL-small-item">
    <a href="#" class="SwitchURL-small-link" id="SwitchURL3">DD</a>
  </li>

  <li data-id="4" class="btn SwitchURL-small-item">
    <a href="#" class="SwitchURL-small-link" id="SwitchURL4">EE</a>
  </li>

  <li>
    <button class="btn button next"> next </button>
  </li>
</ul>
dale landry
  • 7,831
  • 2
  • 16
  • 28
0

You can use a combination of parent().children() to acess back and forth the children of the ul. Also, same functionality happens when clicking on previous or next buttons, so it's possible to encapsulate it in a single function. Observe:

function prevOrNext(str) {
  var temp, childType, nthChild;
  var elems = $('ul li');
  var current = elems.children('a.action').removeClass("action")

  if (str === "#prev") {
    temp = current.parent().prev()
    childType = ":first-child"
    nthChild = ":nth-last-child(2)";
  }
  if (str === "#next") {
    temp = current.parent().next()
    childType = ":last-child"
    nthChild = ":nth-child(2)";
  }

  if (temp.is(elems.parent().children(childType))) {
    elems.parent().children(nthChild).children('a').addClass('action')
  } else {
    temp.children('a').addClass("action")
  }
}

$("#prev").click(() => prevOrNext("#prev"))
$("#next").click(() => prevOrNext("#next"))
.SwitchURL-small-list{
    display:flex;
    list-style:none;
    font-size: 22px;
    font-weight:bold;
}

.SwitchURL-smaill-item{
    border-bottom: 0px solid#AE96DA;
    padding: 0 1%;
    margin-bottom: 1%;
    font-size: 20px;
}

.SwitchURL-small-link{
    color: #CFC1E9;
    margin-right: 15px;
    margin-left: 15px;
}

.SwitchURL-small-link:hover{
    color: #AE96DA;
}

.SwitchURL-small-link.action {
    border-bottom: 2px solid#AE96DA;
    color: #AE96DA;
    margin-right: 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><ul class="SwitchURL-small-list" id="smallTitle">  <li class="SwitchURL-small-item" id="front">   <button id="prev" type="button"> &lt; </button>  </li>  <li class="SwitchURL-small-item">   <a href="AA" class="SwitchURL-small-link " id="SwitchURL-leave">AA</a>  </li>  <li class="SwitchURL-small-item">   <a href="BB" class="SwitchURL-small-link" id="SwitchURL-leave">BB</a>  </li>  <li class="SwitchURL-small-item">   <a href="CC" class="SwitchURL-small-link action" id="SwitchURL-leave">CC</a>  </li>  <li class="SwitchURL-small-item">   <a href="DD" class="SwitchURL-small-link" id="SwitchURL-leave">DD</a>  </li>  <li class="SwitchURL-small-item">   <a href="EE" class="SwitchURL-small-link" id="SwitchURL-leave">EE</a>  </li>  <li class="SwitchURL-smaill-item" id="next">   <button id="next" type="button"> > </button>  </li></ul>
testing_22
  • 2,340
  • 1
  • 12
  • 28