skip to Main Content

in this menu i can put the class ‘active’ on the clicked and remove it from the others element, set the href but the href is not oppening. Where is the problem ?

const li = document.querySelectorAll('.list-item');
const arr = ['Home', 'About', 'Contact', 'Projects'];

li.forEach((elementul, index) => {
    elementul.setAttribute('href', arr[index].toLocaleLowerCase() + '.html');

    elementul.addEventListener('click', function (e) {
        e.preventDefault();

        li.forEach(liElement => {
            liElement.classList.remove('active');
        });

        elementul.classList.add('active');

        console.log(elementul.href);
    });
});
html :
<li class='pagini' > 
 <a class='list-item'href='#' >${element} </a>            
</li>

2

Answers


  1. How have you got the array of elements, I would but a class on each li element then do var li = document.getElementsByClassName("ClassNameOfli")

    if that doesn’t work try putting the the code in a async function

    li.forEach((elementul, index) => {
    elementul.setAttribute(‘href’, arr[index].toLocaleLowerCase() + ‘.html’);

    elementul.addEventListener('click', function (e) {
            e.preventDefault();
            addActive(elementul);
        });
    });
    
    
    async function addActive(elementul)
    {    
        var li = document.getElementsByClassName("ClassNameOfli")
        await li.forEach(liElement => {
            liElement.classList.remove('active');
        });
    
        elementul.classList.add('active');
    
        console.log(elementul.href);
    }
    
    Login or Signup to reply.
  2. By calling event.preventDefault() inside the click event listener, you are preventing the link from taking you where it would otherwise lead. Because when a new page is loaded your old script disappears, the approach you are taking should be to mark the active element on page load instead. Luckily enough, you can easily do that with your existing code:

    const menuLinks = document.querySelectorAll( '.list-item' );
    const arr = [ 'Home', 'About', 'Contact', 'Projects' ];
    
    menuLinks.forEach((a, index) => {
        
      const name = arr[index];
      const url = name.toLocaleLowerCase() + '.html';
      // Add the active class only if the 'path' (the part after the .com (TLD) in the domain) ends with the url to your page
      const isActive = location.pathname.endsWith( url );
      
      a.textContent = name;
      a.setAttribute( 'href', url );
      a.classList.toggle( 'active', isActive );
      
    });
    <li class="pagini"> 
      <a class="list-item" href="#">First Link</a>            
    </li>

    I did make a few tweaks that I feel might put you on the right path to naming things: when selecting all your <a> it might be best to not name the array li, since its multiple <a> elements. And when looping over them you should probably use a or anchor instead elementul, as ul feels to refer to an <ul>, which isn’t the element you are getting in your loop. This is not the point, but is worth having a think about to make your code easier to parse.

    In conclusion, keep in mind that following a link loads in fresh, new HTML and JS, so your old script and whatever it knew will be discarded (and even just stopped entirely as soon as you follow a link, your script isn’t persistent across pages).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search