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

javascript - On hover of child <ul> <li> element change styles of parent <ul><l

programmeradmin4浏览0评论

no jquery please

I have the following menu with class=menu-list, I want that on hover of nested/child ul li item, to change background color to white of parent li element

Code and working demo:

   nav .menu-list{
        background: white;
        position: absolute;
        margin-top: 60px;
        padding: 12px 0;
        display: none;
        width: 68vw;
        height: 100vh;

    }

    nav .menu-list li{
        background: white;
        display: block;
        color: #000000;
        position: relative;
        padding: 0;
        border-left: 24px white solid;
    }

    nav .menu-list li:hover{
        background: #eee;
        border-left: 24px #eee solid;
    }

    nav ul li:focus {
        background: white;
    }

    nav ul li:focus ul {
        display: block;
        position: relative;
        left: 0;
        margin-left: -24px;
    }

    nav ul li ul li:hover  {
        background: white;
    }
<nav>
  <ul class="menu-list" style="display: block;">
    <li tabindex="1" onclick="location.href='#/work'; dimScreen()">Work</li>
    <li tabindex="2" onclick="dimScreen()">About
      <ul>
        <li onclick="location.href='#/about/what-we-do'">What we do</li>
        <li onclick="location.href='#/about/how-we-work'">How we work</li>
        <li onclick="location.href='#/about/leadership'">Leadership</li>
      </ul>
    </li>
  </ul>
</nav>

no jquery please

I have the following menu with class=menu-list, I want that on hover of nested/child ul li item, to change background color to white of parent li element

Code and working demo:

   nav .menu-list{
        background: white;
        position: absolute;
        margin-top: 60px;
        padding: 12px 0;
        display: none;
        width: 68vw;
        height: 100vh;

    }

    nav .menu-list li{
        background: white;
        display: block;
        color: #000000;
        position: relative;
        padding: 0;
        border-left: 24px white solid;
    }

    nav .menu-list li:hover{
        background: #eee;
        border-left: 24px #eee solid;
    }

    nav ul li:focus {
        background: white;
    }

    nav ul li:focus ul {
        display: block;
        position: relative;
        left: 0;
        margin-left: -24px;
    }

    nav ul li ul li:hover  {
        background: white;
    }
<nav>
  <ul class="menu-list" style="display: block;">
    <li tabindex="1" onclick="location.href='#/work'; dimScreen()">Work</li>
    <li tabindex="2" onclick="dimScreen()">About
      <ul>
        <li onclick="location.href='#/about/what-we-do'">What we do</li>
        <li onclick="location.href='#/about/how-we-work'">How we work</li>
        <li onclick="location.href='#/about/leadership'">Leadership</li>
      </ul>
    </li>
  </ul>
</nav>

Lame paint screenshot to explain better:

Share Improve this question asked Oct 11, 2015 at 22:20 JekaJeka 1,7003 gold badges23 silver badges38 bronze badges 2
  • 1 As a short rundown of what you can do, you want to bind a mouseover event on your child element. In that event, you want to find the parent, in some form of var parent = evt.parentNode, and then you can manipulate the style by parent.style.background='some hex color' – David Li Commented Oct 11, 2015 at 22:33
  • I wrote out a javascript solution for your reference – David Li Commented Oct 11, 2015 at 22:43
Add a ment  | 

4 Answers 4

Reset to default 2

First thing, you can't do this with CSS. CSS has no concept of what it's parent element is.

As for javascript, you can use mouse events. Here's an example:

var parentOn = function(e) {
    e.target.parentNode.style.backgroundColor = '#9d7';
}
var parentOff = function(e) {
    e.target.parentNode.style.backgroundColor = '#97a';
}

var children = document.querySelectorAll('.child');    
for (var x = 0; x < children.length; x ++) {
    children[x].addEventListener('mouseover', parentOn);
    children[x].addEventListener('mouseout', parentOff);
};

A few things to note:

  • Any JavaScript DOM query will return an array of nodes, so you must iterate over them to avoid error. JQuery hides this nicely so it can be confusing.

  • the mouseenter and mouseleave bination is subtley different from mouseover and mouseout, you can find out more here

  • Working out how to use JavaScript to add and remove classes would be better than using inline styles. This answer will help. You'll be able to re-use the styles and it'll be easier to maintain - I'd such creating a utility function to handle this, like JQuery's addClass().

  • Using named function variables is a bit clearer than anonymous functions, and more re-usable.

https://jsfiddle/chwbuvum/6/

Here's a pure CSS solution

As Tony Leigh pointed out, you cannot do exactly what you asked using pure CSS, but you can make it look like you want.

The changed lines in the CSS are mented in the snippet, and the main change in the HTML is the addition of the span tag in the top-level list elements.

The main idea is that each top-level li remains white, while the enclosed span turns gray on hover. That way, hovering over a sub-list doesn't change color of the parent li.

Code Snippet

    nav .menu-list{
        background: white;
        position: absolute;
        margin-top: 60px;
        padding: 12px 0;
        display: none;
        width: 68vw;
        height: 100vh;

    }

    nav .menu-list li{
        background: white;
        display: block;
        color: #000000;
        position: relative;
        padding: 0;
        /* changed from border to background color
        border-left: 24px white solid;
        */
        padding-left:24px; /* added to put back the "border-left" area */
    }

    nav .menu-list li:hover{
        background: white; /*changed from #eee to white */
        /* changed from border to background color
        border-left: 24px #eee solid;
        */
    }

    /* start added blocks */
    nav .menu-list li span {
        width: 100%;
        display:block;
        position:relative;
        left:-24px;
        padding-left:24px;
    }

    nav .menu-list li span:hover{
        background: #eee;
    }
    /* end added blocks */

    nav ul li:focus {
        background: white;
    }

    nav ul li:focus ul {
        display: block;
        position: relative;
        left: 0;
        margin-left: -24px;
    }

    nav .menu-list li ul li:hover  {
        background: #eee;
    }
<nav>
  <ul class="menu-list" style="display: block;">
    <li tabindex="1" onclick="location.href='#/work'; dimScreen()"><span>Work</span></li>
    <li tabindex="2" onclick="dimScreen()"><span>About</span>
      <ul>
        <li onclick="location.href='#/about/what-we-do'">What we do</li>
        <li onclick="location.href='#/about/how-we-work'">How we work</li>
        <li onclick="location.href='#/about/leadership'">Leadership</li>
      </ul>
    </li>
  </ul>
</nav>

Thanks everyone for trying but I only needed to add this to make it work

  .menu-list li:hover {
        background: #eee;
    }

    .menu-list li:focus {
        background: white;
    }

Here's a code based solution:

JS

var listElements = document.getElementsByClassName('submenu');
for (var i = 0; i < listElements.length; i++) {
    listElements[i].addEventListener("mouseenter", function(evt) {   
        evt.target.parentNode.style.background = "red";
    });
    listElements[i].addEventListener("mouseleave", function(evt) {   
        evt.target.parentNode.style.background = "black";
    });
}

HTML CHANGE

<ul class="menu-list" style="display: block;">
  <li tabindex="1" onclick="location.href='#/work'; dimScreen()">Work</li>
  <li tabindex="2" onclick="dimScreen()">About
    <ul class='submenu'>
      <li onclick="location.href='#/about/what-we-do'">What we do</li>
      <li onclick="location.href='#/about/how-we-work'">How we work</li>
      <li onclick="location.href='#/about/leadership'">Leadership</li>
    </ul>
  </li>
</ul>

As you can see, for each of your submenus you will have, I added an additional submenu class to differentiate between the main menu and submenu. When you leave each element, it will change the background of the parent to black. When you enter, it will change it to red, based on the mouseenter and mouseleave events.

What it does is find the parent node and then manipulate the styling of that element.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论