Keep div:hover open when changing nested select bo

2019-01-20 01:18发布

问题:

This is an IE-only problem. You can see the problem here(dead link) with IE (wait for the page to load, and hover the NY Times icon in the bottom left toolbar. Then try to select a new option). The Layout: .toolTip becomes visible when it's parent div is hovered over. Inside of .toolTip is a select box. When the user opens the select box to make a selection, the parent element gets hidden.

Why is IE thinking that when I hover over the Select box, I am not over the parent div anymore?

Here is some relevant code (pared down for clarity):

#toolBar .toolTip {
    position: absolute;
    display:none;
    background: #fff;
    min-width: 300px;
    }   

#toolBar .socialIcon:hover .toolTip {
    display:block;
    }

and

<div id="toolBar">
<div class="socialIcon">
     <span class="toolTip">
         <h1>NY Times Bestsellers Lists</h1>
           <div id="nyTimesBestsellers">
             <?php include('/ny-times-bestseller-feed.php') ?>
           </div>

       <p>
          <select id="nyTimesChangeCurrentList" name="nyTimesChangeCurrentList"> 
            <option value="hardcover-fiction">Hardcover Fiction</option> 
            <option value="hardcover-nonfiction">Hardcover Nonfiction</option> 
            <option value="hardcover-advice">Hardcover Advice</option> 
          </select>
       </p>
     </span>
</div>
</div>

What I've Tried

Moving the select element in and out of other elements. Changing the position and display properties on the select, option, p, span, div, that are involved here.

回答1:

Solved this by adding a <a href="#" class="closeParentBox">close</a> to the .toolTip div and with

<!--[if IE]>
<script type="text/javascript">
  jQuery(function($){
    $('.toolTip select').focus(function(){
        $(this).parents('.toolTip').addClass('keepOpen');
    });
    $('.toolTip select').blur(function(){
        $(this).parents('.toolTip').removeClass('keepOpen');
    });

    $("a.closeParentBox").click(function(){
        $(this).parents('.toolTip').fadeOut();
        return false;
    });
  });
</script> 
<![endif]-->

Not pretty ... I'd love to hear better answers, though.



回答2:

I have been able to isolate your issue into this simple demo: http://jsfiddle.net/TnzS4/

In the demo, you have a gray box that contains a SELECT element. Whenever you hover the box, it turns red.

Now, the modern browsers (Chrome, FF, Safari, Opera) bahave like so: if you open the SELECT element and hover over its items (OPTION elements), the DIV box will keep its red background - which means that the :hover state is still active.

However, if you hover over the OPTION elements in IE, the box turns gray - which means that the :hover state is not active.

Conclusion: In IE, hovering over a drop-down list of a SELECT element will "kill" all :hover states that were active.

Now, I don't know if this is a bug, but you will have to find a solution to this IE-specific issue. Unfortunately, I don't know the solution.



回答3:

I can confirm. IE bug, from IE7 to IE9 9.0.7930.16406

I had a similar problem. The only way to resolve it, was using a Javascript to add/remove classes or changing the css properties on the fly!



回答4:

I have updated Sime Vidas's JSFiddle, to include my solution: http://jsfiddle.net/TnzS4/221/

Here it is in a nutshell:

$wrap = $('.wrap');
$dropdown = $('.dropdown');

$dropdown.focus(function() {
  $wrap.addClass('hover');
  $dropdown.one('change', function() {
    $wrap.removeClass('hover');
    $dropdown.blur();
  });
});
$dropdown.blur(function() {
  $wrap.removeClass('hover');
});

I add a 'hover' class when the user is focused on the dropdown, and remove the 'hover' class when the user selects an option or loses focus on the dropdown.

The .hover class mimics the CSS of the :hover pseudo-class.

The 'focus' event only fires once when you click on the dropdown, until it is blurred again. The solution is to blur() the dropdown after selecting an option, allowing the fix to work multiple times.

In my particular case, I had to put the $wrap.removeClass('hover') within a setTimeout, as shown below. This depends on your scenario so I left it out of the JSFiddle:

setTimeout(function() {
  $wrap.removeClass('hover');
}, 1000);