将悬停区域扩展到外部元素

Ari*_*ian 12 javascript css jquery javascript-events hover

我有一个下拉菜单,其子菜单放在不同的元素上.所以基本上当鼠标离开菜单项时,子菜单立即关闭,因为子菜单不是孩子.

var menuItem = $(".menu-item");


menuItem.hover(hoverIn, hoverOut);

function hoverIn() {
  var mnItemMeta = $(this)[0].getBoundingClientRect();

  $(".sub-menu").css({
    opacity: 1,
    left: mnItemMeta.left
  })
}

function hoverOut() {
  $(".sub-menu").css({
    opacity: 0
  })
}
Run Code Online (Sandbox Code Playgroud)
html,body{background-color: #efefef;}
.menu {
  list-style: none;
  padding-left: 0;
  display: flex;
  justify-content: center;
}
a {
  display: block;
  padding: 10px 20px;
  text-decoration: none;
  color: inherit;
}
.sub-menu {
  opacity: 0;
  background-color: white;
  position: absolute;
  transition: .2s ease;
}
.sub-menu-list {
  list-style: none;
  padding-left: 0;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="menu">
  <li class="menu-item"><a href="#">Menu Item</a>
  </li>
</ul>
<div class="sub-menu">
  <ul class="sub-menu-list">
    <li><a href="#">Sub Menu 1</a>
    </li>
    <li><a href="#">Sub Menu 2</a>
    </li>
    <li><a href="#">Sub Menu 3</a>
    </li>
    <li><a href="#">Sub Menu 4</a>
    </li>
  </ul>
</div>
Run Code Online (Sandbox Code Playgroud)

https://jsfiddle.net/yans_fied/6wj0of90/

问题是如何扩展悬停区域,因此当光标指向子菜单时,它会忽略hoverOut操作.

注意:不要告诉我将子菜单放在菜单项中,我已经知道它是如何工作的.这是针对不同的情况,需要将子菜单放在菜单项之外.谢谢 :)

eis*_*ehr 6

你可以把它sub-menu放在menu-item.

var menuItem = $(".menu-item");
menuItem.hover(hoverIn, hoverOut);

function hoverIn() {
  var mnItemMeta = $(this)[0].getBoundingClientRect();

  $(".sub-menu").css({
    opacity: 1,
    left: mnItemMeta.left
  })
}

function hoverOut() {
  $(".sub-menu").css({
    opacity: 0
  })
}
Run Code Online (Sandbox Code Playgroud)
html, body {
  background-color: #efefef;
}
.menu {
  list-style: none;
  padding-left: 0;
  display: flex;
  justify-content: center;
}
a {
  display: block;
  padding: 10px 20px;
  text-decoration: none;
  color: inherit;
}
.sub-menu {
  opacity: 0;
  background-color: white;
  position: absolute;
  transition: .2s ease;
}
.sub-menu-list {
  list-style: none;
  padding-left: 0;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<ul class="menu">
  <li class="menu-item"><a href="#">Menu Item</a>
    <div class="sub-menu">
      <ul class="sub-menu-list">
        <li><a href="#">Sub Menu 1</a></li>
        <li><a href="#">Sub Menu 2</a></li>
        <li><a href="#">Sub Menu 3</a></li>
        <li><a href="#">Sub Menu 4</a></li>
      </ul>
    </div>
  </li>
</ul>
Run Code Online (Sandbox Code Playgroud)

另一种方法是检查hover的状态.menu-item.sub-menu.你需要在这里使用一点暂停,以防止它提前关闭.

var timeout,
    hovered = false,
    menuItem = $(".menu-item, .sub-menu").hover(hoverIn, hoverOut);;

function hoverIn() {
    hovered = true;

    var mnItemMeta = this.getBoundingClientRect();

    $(".sub-menu").show().css({
        opacity: 1,
        left: mnItemMeta.left,
    });
}

function hoverOut() {
  hovered = false;

    clearTimeout(timeout);
    timeout = setTimeout(function() {
        if (!hovered) {
            $(".sub-menu").css({
                opacity: 0,
            }).hide()
        }
    }, 100);
}
Run Code Online (Sandbox Code Playgroud)
html, body {
  background-color: #efefef;
}
.menu {
  list-style: none;
  padding-left: 0;
  display: flex;
  justify-content: center;
}
a {
  display: block;
  padding: 10px 20px;
  text-decoration: none;
  color: inherit;
}
.sub-menu {
  opacity: 0;
  background-color: white;
  position: absolute;
  transition: .2s ease;
}
.sub-menu-list {
  list-style: none;
  padding-left: 0;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<ul class="menu">
  <li class="menu-item"><a href="#">Menu Item</a></li>
</ul>
<div class="sub-menu">
  <ul class="sub-menu-list">
    <li><a href="#">Sub Menu 1</a></li>
    <li><a href="#">Sub Menu 2</a></li>
    <li><a href="#">Sub Menu 3</a></li>
    <li><a href="#">Sub Menu 4</a></li>
  </ul>
</div>
Run Code Online (Sandbox Code Playgroud)


Ari*_*ian -4

好的,我已经找到解决方案了。感谢大家提供一些建议,但我无法接受你们的答案,因为解决方案需要更多解决方法。

所以,基本上 ai 创建了两个函数,即startCloseTimeout()stopCloseTimout(),并将其绑定在 和menu-itemsubmenu

这是函数本身:

var startCloseTimeout = function (){
    closeDropdownTimeout = setTimeout( () => closeDropdown() , 50 );
},

stopCloseTimeout   = function () {
    clearTimeout( closeDropdownTimeout );
};
Run Code Online (Sandbox Code Playgroud)

这是我绑定鼠标事件的方法:

//- Binding mouse event to each menu items
menuItems.forEach( el => {

    //- mouse enter event
    el.addEventListener( 'mouseenter', function() {
        stopCloseTimeout();
        openDropdown( this );
    }, false );

    //- mouse leave event
    el.addEventListener( 'mouseleave', () => startCloseTimeout(), false);

} );

//- Binding mouse event to each sub menus
menuSubs.forEach( el => {

    el.addEventListener( 'mouseenter', () => stopCloseTimeout(), false );
    el.addEventListener( 'mouseleave', () => startCloseTimeout(), false );

} );
Run Code Online (Sandbox Code Playgroud)

那么,这段代码是如何工作的呢?

通过创建关闭超时处理程序,我们可以控制下拉列表何时关闭或不关闭。

当鼠标进入菜单项时,会发生以下情况: 1. 停止当前运行closeDropdownTimout 2. 打开相关下拉菜单

当鼠标离开菜单项时,它会启动closeDropdownTimout.

但下拉菜单怎么仍然打开呢?由于我们在下拉菜单上设置了相同的操作,因此closeDropdownTimout井被清除并取消关闭操作。

如需完整源代码,您可以在 codepen 上查看:http://codepen.io/ariona/pen/pENkXW

谢谢。