Incorporate hover and click functionality to the dropdown button using JQuery

Recently, I implemented hover and click events to trigger the opening of a dropdown content

The functionality is mostly working as expected but there is a slight issue

When hovering over the element, the content opens and closes properly

However, on the first click, it opens correctly but on the second click, it doesn't close immediately, requiring me to exit the hover state to see the effect of the second click

Here is the HTML structure:

<html>
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<style>
.dropdown {
    position: relative;
    display: inline-block;
}

.dropdown-content {
    display: none;
    position: absolute;
    background-color: #f9f9f9;
    min-width: 160px;
    box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
    padding: 12px 16px;
    z-index: 1;
}

.dropdown:hover .dropdown-content {
    display: block;
}

.openCont{
  display:block !important;
}

.closeCont{
  display: none !important;
}
</style>
</head>
<body>

<h2>Hoverable Dropdown</h2>
<p>Move the mouse over the text below to open the dropdown content.</p>

<div class="dropdown">
  <button>Mouse over me</button>
  <div class="dropdown-content">
    <p>Hello World!</p>
  </div>
</div>

  <div class="dropdown">
  <button>Mouse over me</button>
  <div class="dropdown-content">
    <p>Hello World!</p>
  </div>
</div>

</body>
</html>

And this is the JavaScript function that handles the click event:

$(".dropdown").click(function(){
    console.log('toggle')
    $(this).find("div.dropdown-content").toggleClass('openCont');

});

Answer №1

If you follow these steps, it should work smoothly. Simply incorporate a mouseout handler.

$(".dropdown").mouseout(function(){
    $(this).find("div.dropdown-content").removeClass('closeCont');
});

Update your JavaScript code as shown below:

$(this).find("div.dropdown-content").toggleClass('openCont closeCont');
if ($(this).is(":hover")) {
  $(this).find("div.dropdown-content").addClass('closeCont');
}

Make sure to update your CSS by modifying the following rule:

.dropdown:hover .dropdown-content:not(.closeCont) {
    display: block;
}

Also, remember to switch the order of these two rules so that openCont comes last (and remove !important):

.closeCont{
  display: none;
}
.openCont{
  display:block;
}

What makes it effective is that after hiding upon clicking, moving the mouse outside removes the closeCont class, allowing it to function properly when hovered over again.

Check out the Stack snippet provided for reference.

$(".dropdown").click(function(){
    console.log('toggle')
    $(this).find("div.dropdown-content").toggleClass('openCont closeCont');
    if ($(this).is(":hover")) {
      $(this).find("div.dropdown-content").addClass('closeCont');
    }
});

$(".dropdown").mouseout(function(){
    $(this).find("div.dropdown-content").removeClass('closeCont');
});
.dropdown {
    position: relative;
    display: inline-block;
}
.dropdown-content {
    display: none;
    position: absolute;
    background-color: #f9f9f9;
    min-width: 160px;
    box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
    padding: 12px 16px;
    z-index: 1;
}
.dropdown:hover .dropdown-content:not(.closeCont) {
    display: block;
}
.closeCont{
  display: none;
}
.openCont{
  display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

<h2>Hoverable Dropdown</h2>
<p>Move the mouse over the text below to open the dropdown content.</p>

<div class="dropdown">
  <button>Mouse over me</button>
  <div class="dropdown-content">
    <p>Hello World!</p>
  </div>
</div>

  <div class="dropdown">
  <button>Mouse over me</button>
  <div class="dropdown-content">
    <p>Hello World!</p>
  </div>
</div>

Answer №2

It's not a glitch: The issue arises when you set the instructions to "show panel on hover" and "show panel on first click, hide on second click," but the hover event is still triggered because you are still hovering over the button after clicking on it.

I have created a JSfiddle to demonstrate how I fixed this problem: https://jsfiddle.net/Voltra/v7q60217/1/

$(".dropdown").on("mouseover",function(){
    console.log('hovering');
    $(this).find("div.dropdown-content").css("display","block");
});

var cl = 0;

$(".dropdown").on("mouseleave",function(){
    console.log('not hovering');
    if(cl!=1){
        $(this).find("div.dropdown-content").css("display","none");
    }
});

$(".dropdown").on("click",function(){
    console.log('toggle')
    $(this).find("div.dropdown-content").toggleClass('openCont');
    cl+=1;
    if(cl == 2){
        cl=0;
        $(this).trigger("mouseleave");
    }
});

EDIT: Here is a revised version of the previous code that works correctly: https://jsfiddle.net/Voltra/v7q60217/3/

$(".dropdown").on("mouseover",function(){
    console.log('hovering');
    $(this).find("div.dropdown-content").css("display","block");
});


$(".dropdown").on("mouseleave",function(){
    console.log('not hovering');
    if($(this).prop('cl') != 1){
        $(this).find("div.dropdown-content").css("display","none");
    }
});

$(".dropdown").on("click",function(){
    if($(this).prop('cl') === undefined){
        $(this).prop('cl',0);
    }
    console.log('toggle');
    $(this).find("div.dropdown-content").toggleClass('openCont');
    $(this).prop('cl',$(this).prop('cl')+1);
    if($(this).prop('cl') == 2){
        $(this).prop('cl',0);
        $(this).trigger("mouseleave");
    }
});

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

Using AJAX/JQuery along with PHP to instantly send notifications without refreshing the page for a contact form

Website URL: This website was created by following two separate tutorials, one for PHP and the other for AJAX. The main objective was to develop a contact form that validates input fields for errors. If no errors are found, a success message is displayed ...

Show Zeroes in Front of Input Numbers

I am working with two input fields that represent hours and minutes separately. <input type="number" min="0" max="24" step="1" value="00" class="hours"> <input type="number" min="0" max="0.60" step="0.01" value="00" class="minutes"> This se ...

Adding hyperlinks to images on a Project Page in Squarespace with the help of JQuery

I'm currently creating a website on Squarespace and facing a challenge with the project pages. While Squarespace allows me to add images with titles and descriptions, I do not have direct access to edit the page. Unfortunately, the platform does not h ...

Rearrange the li elements within multiple ul lists using JavaScript

Is there a way to reorder multiple ul-lists on my website using JavaScript? An example of the lists may be as follows: $(document).ready(function() { var ul = $('ul.filelist'); for (let u = 0; u < ul.length; u++) { const element = ul[ ...

Changing the text alignment to justify in OWA - HTML emails

Having trouble navigating the Outlook Web App (OWA)? It seems like there are countless issues with different Outlook clients, but OWA is definitely the most poorly documented one. The snippet of code below functions flawlessly in all email clients such as ...

Issue with making a call to retrieve an image from a different directory in ReactJS

This is how it appears <img className='imgclass' src={"../" + require(aLc.value)} alt='' key={aLc.value} /> I am trying to create a path like ../m/b/image.jpg, where aLc.value contains the path /m/b/image.jpg. I need to add only ...

The left side of the form input material is obscured unless the necessary criteria are fulfilled

I am currently in the process of developing the front-end for a web application using the material library. The issue I am facing is that when a field does not meet its requirements, such as needing to enter a 'bedrijfsnaam', the border turns red ...

Trouble with CSS matching pattern - not functioning as expected

I am facing a requirement to customize the colors of ribbon styles instead of using the default ones. After researching pattern matching in CSS, I attempted the following code, but it did not work: This is my original CSS: .ms-cui-cg-**tl** .ms-cui-ct-f ...

Using jQuery to display items from GitHub API in a custom unordered list format

Attempting to access data from the GitHub API using jQuery (AJAX) and display it on a static webpage. Here are the HTML and JS code snippets: $(document).ready(function(){ $.ajax({ url: 'https://api.github.com/re ...

Problem encountered with JSON web service response compression triggered by JBOSS 4.2.3

Implemented Axis2 JSON web services in JBOSS Appserver and set up response compression in the connector (in the server.xml file). Successfully tested the service using a Java client and received the compressed (GZIP) response, monitored through a TCP/IP mo ...

Having difficulty altering the div color in real-time using VueJS

I'm currently in the process of building an application with Bootstrap and VueJS. My goal is to create a folder structure similar to Google Drive, where I want to make a div stand out in blue once it's selected. Below is the code snippet: ex ...

I have exhausted all possible solutions in my attempts to eliminate the whitespace below my footer. Is there something I have overlooked or not tried yet?

After updating the CSS stylesheet, I noticed a white space below my footer. A screenshot has been included for reference. Despite including a CSS reset, the issue still persists. /* html5doctor.com Reset Stylesheet v1.6.1 Last Updated: 2010-09-17 Author ...

Arranging div blocks in columns that are seamlessly aligned

I am dealing with a situation where I have several boxes or blocks arranged in a 3-column layout. These boxes are styled using properties like float: left, width: 33%, but they have varying heights. Is there a way to make sure that the boxes always fill i ...

Understanding the process of retrieving the value of an element produced in a PHP foreach loop

I am faced with an issue in my code where elements are being generated within a for loop using PHP. Here is the snippet of the code: for($i=0; $i < $count; $i++) { $member = $my_array[$i]; <td><span id="myspan"><input type="text" id= ...

Concealing and organizing navigation bar items for mobile devices

Currently, my navbar looks like this on a larger screen: But here's how it appears on a smaller screen (phone): What I'm hoping to achieve is to make the U logo on the top left disappear and align "get in touch" closer to the other elements. On ...

Is it permissible to employ both CSS pseudo-elements, namely before and after, on a single selector in this instance?

Seeking to create a visually appealing horizontal menu navigation resembling: {image1} ITEM1 [separator1] {image2} ITEM2 [separator2] etc. However, a constraint exists - the HTML structure must remain unchanged. Can this be achieved solely with CSS us ...

How does bootstrap-confirmation on datatable trigger server-side code without needing a click?

I am working on a bootstrap project and using the datatables plugin. I want to implement a confirmation message before deleting a row. I have successfully achieved this when populating the table using a repeater and linkButton. However, now I want to achie ...

Issue with parsing JSON data for heatmap in Mapbox

Here's the code I'm using: heat = L.heatLayer([], { maxZoom: 12 }).addTo(map); $.getJSON("js/example-single.geojson", function(data) { var geojsosn = L.geoJson(data, { onEachFeature: function (feature, layer) { console.log(f ...

Tips for ensuring the pop-up submenu remains visible even when the cursor is outside the parent container and submenu during hover

Is there a way to keep the pop submenu visible even when the mouse hovers outside of its parent container or the submenu? Currently, if the mouse doesn't move straight down from the parent container (B) .account-settings-container to the top arrow of ...

Tips for implementing varying styles depending on the number of columns in a table

I am working with multiple tables that share similarities, but differ in the number of columns each table has. I am looking to create a styling rule where depending on the number of columns, the width of each column will be set accordingly. For example, if ...