Search code examples
javascriptjqueryhtmlcsspseudo-class

CSS active pseudo-class changing state swallows up onclick event


I'm adapting an example found here to be a little more like a "real" menu in that it should collapse on user clicks.

I rather like the fact that all of the visual aspects of the menu are dealt with in css, with javascript coming into play only to handle the action required when a user selects an option. i feel this is the most appropriate approach for my particular application.

However, I'm finding the onclick event I'm assigning to each link is being deleted (or ignored) when the menu is put away.

I'm posting 2 versions, one that works in the respect that when users select an option, the desired onclick event is triggered, and another that nicely puts away the menu, but also swallows up the onclick event. I'm after a solution that will combine the 2 results into a working menu, which also satisfies the requirement of putting itself away after a click.

EDIT just noticed some extra code I have commented out (an earlier attempt before figuring out css only solution. i was calling mouseleave, with no effect.

The only difference between the 2 versions is the addition of a CSS clause:

#menuwrapper ul:active{
    display:none;
}

Version that "works", but doesn't collapse the menu

   var display = document.getElementById("display");
   $(document).ready(function() {
     $('li.menu_clickable').click(function() {
       if (this.children.length === 1) {
         //$(this).trigger('mouseleave');
         display.innerHTML = 'you clicked ' + this.innerHTML;
       }
     });
   });
/* Define the body style */

body {
  font-family: Arial;
  font-size: 12px;
}
#maindiv {
  position: absolute;
  left: 200px;
  top: 0px;
}
/* We remove the margin, padding, and list style of UL and LI components */

#menuwrapper ul,
#menuwrapper ul li {
  margin: 0;
  padding: 0;
  list-style: none;
}
/* We apply background color and border bottom white and width to 150px */

#menuwrapper ul li {
  background-color: #7f95db;
  border-bottom: solid 1px white;
  width: 150px;
  cursor: pointer;
}
/* We apply the background hover color when user hover the mouse over of the li component */

#menuwrapper ul li:hover {
  background-color: #6679e9;
  position: relative;
  z-index: 100;
}
/* We apply the link style */

#menuwrapper ul li a {
  padding: 5px 15px;
  color: #ffffff;
  display: inline-block;
  text-decoration: none;
}
/**** SECOND LEVEL MENU ****/

/* We make the position to absolute for flyout menu and hidden the ul until the user hover the parent li item */

#menuwrapper ul li ul {
  position: absolute;
  display: none;
}
/* When user has hovered the li item, we show the ul list by applying display:block, note: 150px is the individual menu width.  */

#menuwrapper ul li:hover ul {
  left: 150px;
  top: 0px;
  display: block;
}
/* we apply different background color to 2nd level menu items*/

#menuwrapper ul li ul li {
  background-color: #cae25a;
}
/* We change the background color for the level 2 submenu when hovering the menu */

#menuwrapper ul li:hover ul li:hover {
  background-color: #b1b536;
}
/* We style the color of level 2 links */

#menuwrapper ul li ul li a {
  color: #454444;
  display: inline-block;
  width: 120px;
}
/**** THIRD LEVEL MENU ****/

/* We need to hide the 3rd menu, when hovering the first level menu */

#menuwrapper ul li:hover ul li ul {
  position: absolute;
  display: none;
}
/* We show the third level menu only when they hover the second level menu parent */

#menuwrapper ul li:hover ul li:hover ul {
  display: block;
  left: 150px;
  top: 0;
}
/* We change the background color for the level 3 submenu*/

#menuwrapper ul li:hover ul li:hover ul li {
  background: #86d3fa;
}
/* We change the background color for the level 3 submenu when hovering the menu */

#menuwrapper ul li:hover ul li:hover ul li:hover {
  background: #358ebc;
}
/* We change the level 3 link color */

#menuwrapper ul li:hover ul li:hover ul li a {
  color: #ffffff;
}
/* Hide the menu when a link is clicked on */

/*
#menuwrapper ul:active{
    display:none;
}
*/

/* Clear float */

.clear {
  clear: both;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menuwrapper">
  <ul>
    <li class="menu_clickable"><a href="#">Home</a>
    </li>
    <li class="menu_clickable"><a href="#">Products</a>
      <ul>
        <li class="menu_clickable"><a href="#">Product 1</a>
          <ul>
            <li class="menu_clickable"><a href="#">Sub Product 1</a>
            </li>
            <li class="menu_clickable"><a href="#">Sub Product 2</a>
            </li>
            <li class="menu_clickable"><a href="#">Sub Product 3</a>
            </li>
          </ul>
        </li>
        <li class="menu_clickable"><a href="#">Product 2</a>
        </li>
        <li class="menu_clickable"><a href="#">Product 3</a>
        </li>
      </ul>
    </li>
    <li><a href="#">About Us</a>
      <ul>
        <li class="menu_clickable"><a href="#">Faqs</a>
        </li>
        <li class="menu_clickable"><a href="#">Contact Us</a>
        </li>
        <li class="menu_clickable"><a href="#">Where are we?</a>
        </li>
      </ul>
    </li>
    <li class="menu_clickable"><a href="#">Help</a>
  </ul>
</div>

<div id="maindiv">
  <div>
    <label id="display">click an option</label>
  </div>
  <div>
    <button onclick="alert('hey!');">
      some button
    </button>under the menu
  </div>
  <div>
    <input value="some input box">under the menu
  </div>
</div>

version that collapses the menu, but doesn't trigger the onclick

   var display = document.getElementById("display");
   $(document).ready(function() {
     $('li.menu_clickable').click(function() {
       if (this.children.length === 1) {
         //$(this).trigger('mouseleave');
         display.innerHTML = 'you clicked ' + this.innerHTML;
       }
     });
   });
/* Define the body style */

body {
  font-family: Arial;
  font-size: 12px;
}
#maindiv {
  position: absolute;
  left: 200px;
  top: 0px;
}
/* We remove the margin, padding, and list style of UL and LI components */

#menuwrapper ul,
#menuwrapper ul li {
  margin: 0;
  padding: 0;
  list-style: none;
}
/* We apply background color and border bottom white and width to 150px */

#menuwrapper ul li {
  background-color: #7f95db;
  border-bottom: solid 1px white;
  width: 150px;
  cursor: pointer;
}
/* We apply the background hover color when user hover the mouse over of the li component */

#menuwrapper ul li:hover {
  background-color: #6679e9;
  position: relative;
  z-index: 100;
}
/* We apply the link style */

#menuwrapper ul li a {
  padding: 5px 15px;
  color: #ffffff;
  display: inline-block;
  text-decoration: none;
}
/**** SECOND LEVEL MENU ****/

/* We make the position to absolute for flyout menu and hidden the ul until the user hover the parent li item */

#menuwrapper ul li ul {
  position: absolute;
  display: none;
}
/* When user has hovered the li item, we show the ul list by applying display:block, note: 150px is the individual menu width.  */

#menuwrapper ul li:hover ul {
  left: 150px;
  top: 0px;
  display: block;
}
/* we apply different background color to 2nd level menu items*/

#menuwrapper ul li ul li {
  background-color: #cae25a;
}
/* We change the background color for the level 2 submenu when hovering the menu */

#menuwrapper ul li:hover ul li:hover {
  background-color: #b1b536;
}
/* We style the color of level 2 links */

#menuwrapper ul li ul li a {
  color: #454444;
  display: inline-block;
  width: 120px;
}
/**** THIRD LEVEL MENU ****/

/* We need to hide the 3rd menu, when hovering the first level menu */

#menuwrapper ul li:hover ul li ul {
  position: absolute;
  display: none;
}
/* We show the third level menu only when they hover the second level menu parent */

#menuwrapper ul li:hover ul li:hover ul {
  display: block;
  left: 150px;
  top: 0;
}
/* We change the background color for the level 3 submenu*/

#menuwrapper ul li:hover ul li:hover ul li {
  background: #86d3fa;
}
/* We change the background color for the level 3 submenu when hovering the menu */

#menuwrapper ul li:hover ul li:hover ul li:hover {
  background: #358ebc;
}
/* We change the level 3 link color */

#menuwrapper ul li:hover ul li:hover ul li a {
  color: #ffffff;
}
/* Hide the menu when a link is clicked on */


#menuwrapper ul:active{
    display:none;
}


/* Clear float */

.clear {
  clear: both;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menuwrapper">
  <ul>
    <li class="menu_clickable"><a href="#">Home</a>
    </li>
    <li class="menu_clickable"><a href="#">Products</a>
      <ul>
        <li class="menu_clickable"><a href="#">Product 1</a>
          <ul>
            <li class="menu_clickable"><a href="#">Sub Product 1</a>
            </li>
            <li class="menu_clickable"><a href="#">Sub Product 2</a>
            </li>
            <li class="menu_clickable"><a href="#">Sub Product 3</a>
            </li>
          </ul>
        </li>
        <li class="menu_clickable"><a href="#">Product 2</a>
        </li>
        <li class="menu_clickable"><a href="#">Product 3</a>
        </li>
      </ul>
    </li>
    <li><a href="#">About Us</a>
      <ul>
        <li class="menu_clickable"><a href="#">Faqs</a>
        </li>
        <li class="menu_clickable"><a href="#">Contact Us</a>
        </li>
        <li class="menu_clickable"><a href="#">Where are we?</a>
        </li>
      </ul>
    </li>
    <li class="menu_clickable"><a href="#">Help</a>
  </ul>
</div>

<div id="maindiv">
  <div>
    <label id="display">click an option</label>
  </div>
  <div>
    <button onclick="alert('hey!');">
      some button
    </button>under the menu
  </div>
  <div>
    <input value="some input box">under the menu
  </div>
</div>


Solution

  • you could try to use mousedown instead of click

       var display = document.getElementById("display");
       $(document).ready(function() {
         $('li.menu_clickable').mousedown(function() {
           if (this.children.length === 1) {
             //$(this).trigger('mouseleave');
             display.innerHTML = 'you clicked ' + this.innerHTML;
           }
         });
       });
    /* Define the body style */
    
    body {
      font-family: Arial;
      font-size: 12px;
    }
    #maindiv {
      position: absolute;
      left: 200px;
      top: 0px;
    }
    /* We remove the margin, padding, and list style of UL and LI components */
    
    #menuwrapper ul,
    #menuwrapper ul li {
      margin: 0;
      padding: 0;
      list-style: none;
    }
    /* We apply background color and border bottom white and width to 150px */
    
    #menuwrapper ul li {
      background-color: #7f95db;
      border-bottom: solid 1px white;
      width: 150px;
      cursor: pointer;
    }
    /* We apply the background hover color when user hover the mouse over of the li component */
    
    #menuwrapper ul li:hover {
      background-color: #6679e9;
      position: relative;
      z-index: 100;
    }
    /* We apply the link style */
    
    #menuwrapper ul li a {
      padding: 5px 15px;
      color: #ffffff;
      display: inline-block;
      text-decoration: none;
    }
    /**** SECOND LEVEL MENU ****/
    
    /* We make the position to absolute for flyout menu and hidden the ul until the user hover the parent li item */
    
    #menuwrapper ul li ul {
      position: absolute;
      display: none;
    }
    /* When user has hovered the li item, we show the ul list by applying display:block, note: 150px is the individual menu width.  */
    
    #menuwrapper ul li:hover ul {
      left: 150px;
      top: 0px;
      display: block;
    }
    /* we apply different background color to 2nd level menu items*/
    
    #menuwrapper ul li ul li {
      background-color: #cae25a;
    }
    /* We change the background color for the level 2 submenu when hovering the menu */
    
    #menuwrapper ul li:hover ul li:hover {
      background-color: #b1b536;
    }
    /* We style the color of level 2 links */
    
    #menuwrapper ul li ul li a {
      color: #454444;
      display: inline-block;
      width: 120px;
    }
    /**** THIRD LEVEL MENU ****/
    
    /* We need to hide the 3rd menu, when hovering the first level menu */
    
    #menuwrapper ul li:hover ul li ul {
      position: absolute;
      display: none;
    }
    /* We show the third level menu only when they hover the second level menu parent */
    
    #menuwrapper ul li:hover ul li:hover ul {
      display: block;
      left: 150px;
      top: 0;
    }
    /* We change the background color for the level 3 submenu*/
    
    #menuwrapper ul li:hover ul li:hover ul li {
      background: #86d3fa;
    }
    /* We change the background color for the level 3 submenu when hovering the menu */
    
    #menuwrapper ul li:hover ul li:hover ul li:hover {
      background: #358ebc;
    }
    /* We change the level 3 link color */
    
    #menuwrapper ul li:hover ul li:hover ul li a {
      color: #ffffff;
    }
    /* Hide the menu when a link is clicked on */
    
    
    #menuwrapper ul:active{
        display:none;
    
    }
    
    
    /* Clear float */
    
    .clear {
      clear: both;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="menuwrapper">
      <ul>
        <li class="menu_clickable"><a href="#">Home</a>
        </li>
        <li class="menu_clickable"><a href="#">Products</a>
          <ul>
            <li class="menu_clickable"><a href="#">Product 1</a>
              <ul>
                <li class="menu_clickable"><a href="#">Sub Product 1</a>
                </li>
                <li class="menu_clickable"><a href="#">Sub Product 2</a>
                </li>
                <li class="menu_clickable"><a href="#">Sub Product 3</a>
                </li>
              </ul>
            </li>
            <li class="menu_clickable"><a href="#">Product 2</a>
            </li>
            <li class="menu_clickable"><a href="#">Product 3</a>
            </li>
          </ul>
        </li>
        <li><a href="#">About Us</a>
          <ul>
            <li class="menu_clickable"><a href="#">Faqs</a>
            </li>
            <li class="menu_clickable"><a href="#">Contact Us</a>
            </li>
            <li class="menu_clickable"><a href="#">Where are we?</a>
            </li>
          </ul>
        </li>
        <li class="menu_clickable"><a href="#">Help</a>
      </ul>
    </div>
    
    <div id="maindiv">
      <div>
        <label id="display">click an option</label>
      </div>
      <div>
        <button onclick="alert('hey!');">
          some button
        </button>under the menu
      </div>
      <div>
        <input value="some input box">under the menu
      </div>
    </div>