最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - group-hover does not work when hover is manually added with JS - Stack Overflow

programmeradmin2浏览0评论

I'm attempting to have the nav anchor tag go in the hover state based on the user's section in the viewport. The Tailwind CSS is working when I manually hover over these nav items but does not work when I add the hover class using Javascript.

I looked into variants but from the docs this should be supported out of the box.

I also added this into my style sheet and again it only changes the background color to red when I manually hover over the element, not when the hover class is added with JS

      .nav-indicator:hover {
         background-color: red;
      }

Is there a way to add the hover force element state with Tailwind?

<li>
   <a id="about" class="nav-indicator group" href="#about-screen" data-ref="about-screen">
   <span class="group-hover:w-16 group-hover:bg-red-200 group-focus-visible:w-16 group-focus-visible:bg-red-200"></span>
   <span class="group-hover:text-red-200 group-focus-visible:text-red-200">About</span></a>
</li>

Here is the whole tailwind code:

Below is my JS that currently correctly adds the hover class depending on the viewport:

  const sections = document.querySelectorAll('section');
  const config = {
    rootMargin: '-50px 0px -55%'
  };

  let observer = new IntersectionObserver(function (entries, self) {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        intersectionHandler(entry); 
      }
    });
  }, config);

  sections.forEach(section => {
    observer.observe(section);
  });

  function intersectionHandler(entry) {
    const id = entry.target.id;

    const currentlyActive = document.querySelector('nav ul li a');
    const shouldBeActive = document.querySelector('nav ul li a[data-ref=' + id + ']');

    if (currentlyActive) {
      currentlyActive.classList.remove('hover');
      // console.log("removed");
      // console.log(currentlyActive);

    }
    if (shouldBeActive) {
      shouldBeActive.classList.add('hover');
      console.log("added");
      console.log(shouldBeActive);

    }
  }

I'm attempting to have the nav anchor tag go in the hover state based on the user's section in the viewport. The Tailwind CSS is working when I manually hover over these nav items but does not work when I add the hover class using Javascript.

I looked into variants but from the docs this should be supported out of the box.

I also added this into my style sheet and again it only changes the background color to red when I manually hover over the element, not when the hover class is added with JS

      .nav-indicator:hover {
         background-color: red;
      }

Is there a way to add the hover force element state with Tailwind?

<li>
   <a id="about" class="nav-indicator group" href="#about-screen" data-ref="about-screen">
   <span class="group-hover:w-16 group-hover:bg-red-200 group-focus-visible:w-16 group-focus-visible:bg-red-200"></span>
   <span class="group-hover:text-red-200 group-focus-visible:text-red-200">About</span></a>
</li>

Here is the whole tailwind code: https://play.tailwindcss.com/rzNXqvfcln?layout=horizontal

Below is my JS that currently correctly adds the hover class depending on the viewport:

  const sections = document.querySelectorAll('section');
  const config = {
    rootMargin: '-50px 0px -55%'
  };

  let observer = new IntersectionObserver(function (entries, self) {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        intersectionHandler(entry); 
      }
    });
  }, config);

  sections.forEach(section => {
    observer.observe(section);
  });

  function intersectionHandler(entry) {
    const id = entry.target.id;

    const currentlyActive = document.querySelector('nav ul li a');
    const shouldBeActive = document.querySelector('nav ul li a[data-ref=' + id + ']');

    if (currentlyActive) {
      currentlyActive.classList.remove('hover');
      // console.log("removed");
      // console.log(currentlyActive);

    }
    if (shouldBeActive) {
      shouldBeActive.classList.add('hover');
      console.log("added");
      console.log(shouldBeActive);

    }
  }
Share Improve this question edited 7 hours ago Trav asked 7 hours ago TravTrav 1431 gold badge2 silver badges11 bronze badges 2
  • @DarkBee Thanks, i have included more reproducible code for context – Trav Commented 7 hours ago
  • Instead of trying to force the :hover state, consider creating an actual class, e..g. hover with the same styles as :hover and assign that class to the element. Related: stackoverflow.com/questions/6406976/… and stackoverflow.com/questions/17226676/… – DarkBee Commented 6 hours ago
Add a comment  | 

1 Answer 1

Reset to default 0

You could here go for another approach where you add the class in utility in tailwind based on whether the nav-indicator is being hovered or not.

When adding this with js, you probably have to tweak a bit for it to work perfectly based on the content you want in your sections, and to make sure that the hover class is being removed when its not active.

I saw in your example that you did not have the nav-indicator class on all links, is there a reason for that? I have added it so make sure it works properly. Also the last section was id'ed as #project-screen instead of #projects-screen so i fixed that as well so it actually where connected with its ref.

I hope this helps you on the way. have a great day!

const sections = document.querySelectorAll('section');
const config = {
  rootMargin: '-50px 0px -55%',
  threshold: 0.8  // Trigger when 50% of the section is in the viewport
};

let observer = new IntersectionObserver(function (entries, self) {
  let mostVisibleSection = null;
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      if (!mostVisibleSection || entry.intersectionRatio > mostVisibleSection.intersectionRatio) {
        mostVisibleSection = entry;
      }
    }
  });

  if (mostVisibleSection) {
    intersectionHandler(mostVisibleSection);
  }
}, config);

sections.forEach(section => {
  observer.observe(section);
});

function intersectionHandler(entry) {
  const id = entry.target.id;

  // Remove hover from the currently active link
  const currentlyActive = document.querySelector('nav ul li a.hover');
  if (currentlyActive) {
    currentlyActive.classList.remove('hover');
  }

  // Add hover to the link corresponding to the most visible section
  const shouldBeActive = document.querySelector('nav ul li a[data-ref="' + id + '"]');
  if (shouldBeActive) {
    shouldBeActive.classList.add('hover');
    console.log("added hover to", shouldBeActive);
  }
}

// Scroll behavior
document.querySelectorAll('nav ul li a').forEach(link => {
  link.addEventListener('click', (e) => {
    e.preventDefault();
    const targetId = link.getAttribute('href').substring(1);
    const targetElement = document.getElementById(targetId);

    // Scroll the section into view, making sure it's at the top
    targetElement.scrollIntoView({ 
      behavior: 'smooth', 
      block: 'start' 
    });
  });
});
<script src="https://cdn.tailwindcss.com"></script>
<style type="text/tailwindcss">
    @layer utilities {
      .nav-indicator.hover {
        @apply [&>*:first-child]:w-16 [&>*:first-child]:bg-red-200 [&>*:last-child]:text-red-200
      }
    }
  </style>
<header class="sticky top-0">
  <nav class="nav block" aria-label="In-page jump links">
    <ul class="mt-4 lg:mt-16 w-max">
      <li>
        <a id="about" class="nav-indicator group flex items-center py-3" href="#about-screen" data-ref="about-screen">
          <span class="mr-4 h-px w-8 bg-red-600 transition-all group-hover:w-16 group-hover:bg-red-200 group-focus-visible:w-16 group-focus-visible:bg-red-200 motion-reduce:transition-none"></span>
          <span class="nav-text text-xs font-bold tracking-widest text-red-500 uppercase group-hover:text-red-200 group-focus-visible:text-red-200">About</span></a
        >
      </li>
      <li>
        <a id="experience" class="nav-indicator group flex items-center py-3" href="#experience-screen" data-ref="experience-screen">
          <span class="mr-4 h-px w-8 bg-red-600 transition-all group-hover:w-16 group-hover:bg-red-200 group-focus-visible:w-16 group-focus-visible:bg-red-200 motion-reduce:transition-none"></span>
          <span class="nav-text text-xs font-bold tracking-widest text-red-500 uppercase group-hover:text-red-200 group-focus-visible:text-red-200">EXPERIENCE</span></a
        >
      </li>
      <li>
        <a id="projects" class="nav-indicator group flex items-center py-3" href="#projects-screen" data-ref="projects-screen">
          <span class="mr-4 h-px w-8 bg-red-600 transition-all group-hover:w-16 group-hover:bg-red-200 group-focus-visible:w-16 group-focus-visible:bg-red-200 motion-reduce:transition-none"></span>
          <span class="nav-text text-xs font-bold tracking-widest text-red-500 uppercase group-hover:text-red-200 group-focus-visible:text-red-200">PROJECTS</span></a
        >
      </li>
    </ul>
  </nav>
</header>
<main class="[&>*]:max-w-4xl max-h-[400px] overflow-y-auto">
  <section id="about-screen">
    <h1>ABOUT</h1>
    <p class="mb-4">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse vel ipsum id mi semper hendrerit. Quisque tempus mi at nunc mattis, sit amet pretium enim malesuada. Phasellus eu libero eu arcu facilisis eleifend sed sed purus. Donec ac eros non felis pharetra ultricies. Suspendisse eu lobortis erat. Vivamus fringilla nec ante at pellentesque. Nullam ultricies semper ligula, at posuere sapien placerat ac. Pellentesque vulputate eros erat, at laoreet purus rhoncus nec.</p>
    <p class="mb-4">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse vel ipsum id mi semper hendrerit. Quisque tempus mi at nunc mattis, sit amet pretium enim malesuada. Phasellus eu libero eu arcu facilisis eleifend sed sed purus. Donec ac eros non felis pharetra ultricies. Suspendisse eu lobortis erat. Vivamus fringilla nec ante at pellentesque. Nullam ultricies semper ligula, at posuere sapien placerat ac. Pellentesque vulputate eros erat, at laoreet purus rhoncus nec.</p>
    <p class="mb-4">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse vel ipsum id mi semper hendrerit. Quisque tempus mi at nunc mattis, sit amet pretium enim malesuada. Phasellus eu libero eu arcu facilisis eleifend sed sed purus. Donec ac eros non felis pharetra ultricies. Suspendisse eu lobortis erat. Vivamus fringilla nec ante at pellentesque. Nullam ultricies semper ligula, at posuere sapien placerat ac. Pellentesque vulputate eros erat, at laoreet purus rhoncus nec.</p>
  </section>
  <section id="experience-screen">
    <h1>EXPERIENCE</h1>

    <p class="mb-4">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse vel ipsum id mi semper hendrerit. Quisque tempus mi at nunc mattis, sit amet pretium enim malesuada. Phasellus eu libero eu arcu facilisis eleifend sed sed purus. Donec ac eros non felis pharetra ultricies. Suspendisse eu lobortis erat. Vivamus fringilla nec ante at pellentesque. Nullam ultricies semper ligula, at posuere sapien placerat ac. Pellentesque vulputate eros erat, at laoreet purus rhoncus nec.</p>
    <p class="mb-4">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse vel ipsum id mi semper hendrerit. Quisque tempus mi at nunc mattis, sit amet pretium enim malesuada. Phasellus eu libero eu arcu facilisis eleifend sed sed purus. Donec ac eros non felis pharetra ultricies. Suspendisse eu lobortis erat. Vivamus fringilla nec ante at pellentesque. Nullam ultricies semper ligula, at posuere sapien placerat ac. Pellentesque vulputate eros erat, at laoreet purus rhoncus nec.</p>
    <p class="mb-4">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse vel ipsum id mi semper hendrerit. Quisque tempus mi at nunc mattis, sit amet pretium enim malesuada. Phasellus eu libero eu arcu facilisis eleifend sed sed purus. Donec ac eros non felis pharetra ultricies. Suspendisse eu lobortis erat. Vivamus fringilla nec ante at pellentesque. Nullam ultricies semper ligula, at posuere sapien placerat ac. Pellentesque vulputate eros erat, at laoreet purus rhoncus nec.</p>
  </section>
  <section id="projects-screen">
    <h1>PROJECTS</h1>

    <p class="mb-4">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse vel ipsum id mi semper hendrerit. Quisque tempus mi at nunc mattis, sit amet pretium enim malesuada. Phasellus eu libero eu arcu facilisis eleifend sed sed purus. Donec ac eros non felis pharetra ultricies. Suspendisse eu lobortis erat. Vivamus fringilla nec ante at pellentesque. Nullam ultricies semper ligula, at posuere sapien placerat ac. Pellentesque vulputate eros erat, at laoreet purus rhoncus nec.</p>
    <p class="mb-4">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse vel ipsum id mi semper hendrerit. Quisque tempus mi at nunc mattis, sit amet pretium enim malesuada. Phasellus eu libero eu arcu facilisis eleifend sed sed purus. Donec ac eros non felis pharetra ultricies. Suspendisse eu lobortis erat. Vivamus fringilla nec ante at pellentesque. Nullam ultricies semper ligula, at posuere sapien placerat ac. Pellentesque vulputate eros erat, at laoreet purus rhoncus nec.</p>
    <p class="mb-4">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse vel ipsum id mi semper hendrerit. Quisque tempus mi at nunc mattis, sit amet pretium enim malesuada. Phasellus eu libero eu arcu facilisis eleifend sed sed purus. Donec ac eros non felis pharetra ultricies. Suspendisse eu lobortis erat. Vivamus fringilla nec ante at pellentesque. Nullam ultricies semper ligula, at posuere sapien placerat ac. Pellentesque vulputate eros erat, at laoreet purus rhoncus nec.</p>
  </section>
</main>

发布评论

评论列表(0)

  1. 暂无评论