Change the custom Navbar from hover to a Click event

Need some help with jQuery as I am still learning. I currently have a dropdown navbar menu that shows on hover. Everything is working fine, but I want to change it so the dropdown appears on click instead of hover. Additionally, I would like to hide the dropdown when clicking outside of the menu. I do not use any frameworks for this.

<ul class="tc-navigation">
  <li class="active">
    <a href="home.php">HOME</a>
  </li>
  <li>
    <a id="er">SERVICES</a>
    <ul>
      <li class="round"><a id="err">Transportation<i class="fa fa-angle-right"></i></a>
        <ul>
          <li class="round"><a href="bus.php">Bus</a></li>
          <li class="round"><a href="taxi.php">Taxi</a></li>
          <li class="round"><a href="air.php">Air</a></li>
        </ul>
      </li>
      <li class="round"><a href="car_rental_agencies.php">Car Rental Agencies</a></li>
      <li class="round"><a href="driving_licence.php">Driving Licence</a></li>
    </ul>
  </li>
  <li>
    <a id="er">ABOUT US</a>
    <ul>
      <li class="round"><a href="about_us.php">Who We are</a></li>
      <li class="round"><a href="our_vision.php">Our Vision</a></li>
      <li class="round"><a href="photo_gallery.php">Photo Gallery</a></li>
    </ul>
  </li>
  <li class="round"><a href="contact.php">CONTACT</a></li>
</ul>

CSS

.tc-navigation li>ul {
  list-style: none;
  margin: 0;
  padding: 0;
  top: 120%;
  border-top: 2px solid;
  border-radius: 0;
  position: absolute;
  width: 190px;
  visibility: hidden;
  opacity: 0;
  background: #fff;
  z-index: 10;
}

.tc-navigation li ul li {
  float: none;
  border-bottom: 1px solid #e1e1e1;
}

.tc-navigation li ul li:last-child {
  border: 0;
}

.tc-navigation li ul li a {
  width: 100%;
  color: #444;
  padding: 15px;
  text-transform: capitalize;
  text-align: center;
}

.tc-navigation li:hover>ul {
  visibility: visible;
  opacity: 1;
  top: 100%;
}

.tc-navigation li ul li a:hover {
  color: #fff;
}

.tc-navigation li ul li a:hover i {
  color: #fff;
}

.tc-navigation li ul li a i {
  color: #666;
  position: absolute;
  right: 10px;
  top: 50%;
  margin: -7px 0 0;
}


/* Sub Menu */

.tc-navigation li>ul li ul {
  left: 110%;
  top: 0!important;
}

.tc-navigation li ul li:hover>ul {
  visibility: visible;
  opacity: 1;
  left: 100%;
}

Answer №1

Utilizing the :hover state in CSS allows for specific rules to be applied to certain DOM elements based on user interaction. Since CSS doesn't inherently respond to click events (with the exception of the :active state for links and buttons), a simple solution would be to use click events to toggle a CSS class on the element. This class can then be utilized in the CSS in the same manner as the :hover state.

$('.tc-navigation > li').on("click", function(e) {
  $(this).toggleClass('showSubmenu');
  $(this).siblings().removeClass('showSubmenu'); // ensure only one submenu is open at a time
  return false; // prevent event bubbling 
});


// To hide menus when clicking outside them, you can apply this behavior to the entire page:
$(document).on('click', function(){
  $('.tc-navigation > li').removeClass('showSubmenu')
});
#container {position:relative}
body {background-color:#CCC}
.tc-navigation li>ul {
  list-style: none;
  margin: 0;
  padding: 0;
  top: 120%;
  border-top: 2px solid;
  border-radius: 0;
  position: absolute;
  width: 190px;
  visibility: hidden;
  opacity: 0;
  background: #fff;
  z-index: 10;
}

.tc-navigation li ul li {
  float: none;
  border-bottom: 1px solid #e1e1e1;
}

.tc-navigation li ul li:last-child {
  border: 0;
}

.tc-navigation li ul li a {
  width: 100%;
  color: #444;
  padding: 15px;
  text-transform: capitalize;
  text-align: center;
}

/* Css selector changed from li:hover to li.showSubmenu with no other changes made */
.tc-navigation li.showSubmenu>ul{
  visibility: visible;
  opacity: 1;
  top: 100%;
}

.tc-navigation li ul li a:hover {
  color: #fff;
}

.tc-navigation li ul li a:hover i {
  color: #fff;
}

.tc-navigation li ul li a i {
  color: #666;
  position: absolute;
  right: 10px;
  top: 50%;
  margin: -7px 0 0;
}


/* Sub Menu */

.tc-navigation li>ul li ul {
  left: 110%;
  top: 0!important;
}

.tc-navigation li ul li:hover>ul {
  visibility: visible;
  opacity: 1;
  left: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<ul class="tc-navigation">
  <li class="active">
    <a href="home.php">HOME</a>
  </li>
  <li>
    <a id="er">SERVICES</a>
    <ul>
      <li class="round"><a id="err">Transportation<i class="fa fa-angle-right"></i></a>
        <ul>
          <li class="round"><a href="bus.php">Bus</a></li>
          <li class="round"><a href="taxi.php">Taxi</a></li>
          <li class="round"><a href="air.php">Air</a></li>
        </ul>
      </li>
      <li class="round"><a href="car_rental_agencies.php">Car Rental Agencies</a></li>
      <li class="round"><a href="driving_licence.php">Driving License</a></li>
    </ul>
  </li>
  <li>
    <a id="er">ABOUT US</a>
    <ul>
      <li class="round"><a href="about_us.php">Who We are</a></li>
      <li class="round"><a href="our_vision.php">Our Vision</a></li>
      <li class="round"><a href="photo_gallery.php">Photo Gallery</a></li>
    </ul>
  </li>
  <li class="round"><a href="contact.php">CONTACT</a></li>
</ul>
</div>

(In order to prevent submenus from going off-screen, a container element was added. The positioning may not be perfect due to missing page elements in the provided example. Additionally, the only modification to your CSS was changing li:hover to li.showSubmenu.)

Answer №2

Alright, here is a glimpse of my menu

$('#cssmenu li.active').addClass('open').children('ul').show();
$('#cssmenu li.has-sub>a').on('click', function(){
  $(this).removeAttr('href');
  var element = $(this).parent('li');
  if (element.hasClass('open')) {
    element.removeClass('open');
    element.find('li').removeClass('open');
    element.find('ul').slideUp(200);
  } else {
    element.addClass('open');
    element.children('ul').slideDown(200);
    element.siblings('li').children('ul').slideUp(200);
    element.siblings('li').removeClass('open');
    element.siblings('li').find('li').removeClass('open');
    element.siblings('li').find('ul').slideUp(200);
  }
});
@import url(https://fonts.googleapis.com/css?family=Raleway:400,200);
#cssmenu,
#cssmenu ul,
#cssmenu ul li,
#cssmenu ul li a {
  margin: 0;
  padding: 0;
  border: 0;
  list-style: none;
  line-height: 1;
  display: block;
  position: relative;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
#cssmenu {
  width: 220px;
  font-family: Raleway, sans-serif;
  color: #ffffff;
}
#cssmenu ul ul {
  display: none;
}
#cssmenu > ul > li.active > ul {
  display: block;
}
.align-right {
  float: right;
}
#cssmenu > ul > li > a {
  padding: 16px 22px;
  cursor: pointer;
  z-index: 2;
  font-size: 16px;
  text-decoration: none;
  color: #ffffff;
  background: #bb0e0e;
  -webkit-transition: color .2s ease;
  -o-transition: color .2s ease;
  transition: color .2s ease;
}
#cssmenu > ul > li > a:hover {
  color: #d8f3f0;
}
#cssmenu ul > li.has-sub > a:after {
  position: absolute;
  right: 26px;
  top: 19px;
  z-index: 5;
  display: block;
  height: 10px;
  width: 2px;
  background: #ffffff;
  content: "";
  -webkit-transition: all 0.1s ease-out;
  -moz-transition: all 0.1s ease-out;
  -ms-transition: all 0.1s ease-out;
  -o-transition: all 0.1s ease-out;
  transition: all 0.1s ease-out;
}
... (content continues) ... 
<html lang="ru" dir="ltr">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- jQuery -->
<script src="http://code.jquery.com/jquery-latest.min.js"></script>

<!-- Icon Library -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
</head>
<body>
<div id="cssmenu">
  <ul>
     <li><a href="#" target="_blank"><i class="fa fa-fw fa-home"></i> Home</a></li>
     <li class="has-sub"><a href="#"><i class="fa fa-fw fa-bars"></i> Services</a>
        <ul>
           <li class="has-sub"><a href="#">Transportation</a>
              <ul>
                 <li><a href="#">Bus</a></li>
                 <li><a href="#">Taxi</a></li>
                 <li><a href="#">Air</a></li>
              </ul>
           </li>
           <li><a href="#">Car Rental Agencies</a></li>
           <li><a href="#">Driving Licence</a></li>
        </ul>
     </li>
     <li class="has-sub"><a href="#"><i class="fa fa-fw fa-cog"></i> Abut us</a>
        <ul>
           <li><a href="#">Who We are</a></li>
           <li><a href="#">Our Vision</a></li>
           <li><a href="#">Photo Gallery</a></li>
        </ul>
     </li>
     <li><a href="#"><i class="fa fa-fw fa-phone"></i> Contact</a></li>
  </ul>
</div>
</body>
</html>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for creating a dynamic route with NextJs 14 API

Looking to start a blog with Next.js 14 and I'm working on defining a function in api/posts/[postSlug]/route.js. How do I access the postSlug parameter within this function? Here's my current function code: // api/posts/[postSlug]/route.js impor ...

Implementing Passport authentication for Steam, transitioning from Express to NestJS

I have embarked on the task of transitioning an express project to nestjs. How can I achieve the same functionality in Nestjs as shown in the working code snippet from Express below? (The code simply redirects to the Steam sign-in page) /* eslint-disable s ...

reconfigure keyboard shortcuts in web browser

In the popular web browser Google Chrome, users can quickly jump to the next tab by pressing CTRL + TAB. Is there a way to change or disable this shortcut? The provided code snippet does not seem to work as intended. $(document).keydown(function(e){ ...

Error: AngularJS throws an error when trying to use an undefined function

Encountering an error on an overview page I've developed. I added pagination to an overview table. The pagination functions properly, but upon loading the page, an error is thrown: "TypeError: undefined is not a function". I've been unable to ...

Error: The component passed is invalid and cannot be defined within kendo UI

Check out this example https://www.telerik.com/kendo-vue-ui/components/grid/ showcasing a computed method gridSearchMessage() { return provideLocalizationService(this).toLanguageString( "gridSearch", "Search in all colu ...

Implementing multiple-choice options in MCQs with JavaScript

I'm in the process of developing a program that can generate multiple choice questions. Below is a snippet of my code: <p>How many multiple choice options do you need?</p> <input type="text" id="question"></input> Currently, ...

Refresh the dataTable once all external data has been successfully fetched

I am struggling to find the correct method for reloading a datatable. Here is my current process: Retrieve data through ajax for specific columns Generate a table with the fetched data Initialize the datatable for the table Make a new ajax request using ...

jquery method to make entire navigation bar clickable

I have a single menu bar. I recently discovered an interesting way to make the entire menu bar area clickable using jQuery. Design code snippet: <%@ Control Language="C#" AutoEventWireup="true" CodeFile="MenuControl.ascx.cs" Inherits="MenuControl"%> ...

Using Ramda to retrieve objects from an array by comparing them with each element in a separate array

I have two arrays: ids = [1,3,5]; The second array is: items: [ {id: 1, name: 'a'}, {id: 2, name: 'b'}, {id: 3, name: 'c'}, {id: 4, name: 'd'}, {id: 5, name: 'e'}, {id: 6, name: 'f'} ]; I ...

"CI is unable to handle the array type data being returned from the AJAX request

My system has a car database integrated, and I'd like to share the code with you. AJAX $('#year').change(function() { $year=$("#year option:selected").text(); $('#make').html(""); $('#model').ht ...

Tips for adding/removing items in arrays using Ember.js

Is it possible to modify an array within an Ember object using methods like push and pop while still keeping the UI bindings updated? While I can easily display the contents of an array in an Ember object using Handlebars, making changes directly to the ...

Does anyone have any insight on why I can't seem to remove an item from my list of tasks?

Having trouble with my React todo list. After submitting, the list item looks fine. I expect to be able to delete it by clicking on the item, but nothing happens. When I try to add another item, the page refreshes and all items are removed. The console ...

Is it possible to include a delete option for removing the content within the input field?

Currently, I have set up an input form that consists of multiple input fields. In order to enhance user experience, I would like to provide a convenient option for users to delete the pre-populated content within the input fields. This can be achieved by ...

jQuery creates unique IDs for every keypress event triggered

Hey there, I'm currently working on developing a space shooting game using jquery and jquery-collision. I've made great progress so far, but I'm facing an issue. Whenever I press the spacebar to shoot, it keeps generating divs with the same ...

Heroku deployment failed: Push rejected due to lack of a Cedar-supported application

Trying to deploy my 3D game (created with three.js) on a Heroku server has brought up an issue. After running the command "git push heroku master," I encountered the following problem: Initializing repository, done. Counting objects: 252, done. Delta com ...

Creating a React component that initializes its state with an empty array

Currently, my component is designed to fetch data from an API and store a random selection of objects (currently set at 10) in an array called correctAnswerArray. To avoid selecting the same object more than once, I use the splice() method. After pushing t ...

Troubleshooting Failed Execution of ASP.net's (Document).ready() Function

I am working on an ASP.net MVC 4 web application using Visual Basic. In the _Layout.vbhtml shared view, I have a piece of javascript code at the bottom intended to hide a loading div and display the main content once everything has loaded. Here is a snipp ...

Ways to prevent a high-powered Javascript loop from causing the browser to freeze

I am currently utilizing Javascript to parse an XML document containing roughly 3,500 elements. I have implemented a jQuery "each" function for this purpose, although I remain open to considering alternative looping methods. One issue that has surfaced ...

Is there a reliable source for obtaining Bootstrap 3.0 code and documentation?

It appears that the code and documentation previously found on has vanished. Previously, I was able to visit: . ... However, these pages are now inaccessible. Does anyone know where they have been moved to? Or perhaps when Bootstrap 3.0 will be ...

determine the color of the pixel at the top left corner of a jpg image

If we were given a specific URL, for instance, "//upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg", how can we use javascript (specifically jQuery or Angular) to obtain the top left coordinates (or any (x,y) coordinates) of this image? Just to clarify, ...