【问题标题】:mouseenter event handler does not work the first time the event is calledmouseenter 事件处理程序在第一次调用事件时不起作用
【发布时间】:2017-02-23 05:35:48
【问题描述】:

当鼠标进入 DOM 的某个部分以显示菜单时,我正在编写一个函数来删除具有内容 display:hidden; 的类。现在,当页面加载并且我最初将鼠标悬停在该区域上时,该事件不会触发。但是,如果我将鼠标移动一次,请移开,然后移回目标元素。它触发良好,菜单未隐藏。

codepen:http://codepen.io/anon/pen/EWYevq

jQuery:

$(document).ready(function() {
      $('#kDropdown, .hidden-dropdown' ).mouseleave(function(e) {
        window.k = setTimeout(function(){
           $('.hidden-dropdown').addClass("hide_k");
        }, 250)
      }).mouseenter(function(e) {
        if(window.k){
          console.log("test")
          clearTimeout(window.k)
          $(".hidden-dropdown").removeClass("hide_k");
        }
      });
    })

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    编辑:即使将window.k 与任何东西进行比较,它也能正常工作。我高度怀疑这个条件在这里是否是强制性的。

    在您的特定情况下:

    window.k 在您第一次悬停该框时返回 undefined (false) 值,这就是它无法通过的原因条件 - 列表未出现。

    选中codepen,打开控制台并将框悬停。第一个日志将是 undefined 值。

    如果您将框悬停在 次,将出现列表,因为 window.k 已在 mouseleave() 函数中设置 - 它不会从以下位置返回 undefined (false)现在开始。


    工作解决方案:

    $(document).ready(function() {
      $('#kDropdown, .hidden-dropdown').mouseleave(function(e) {
        window.k = setTimeout(function() {
          $('.hidden-dropdown').addClass("hide_k");
        }, 250);
      }).mouseenter(function(e) {
        console.log("test")
        clearTimeout(window.k)
        $(".hidden-dropdown").removeClass("hide_k");
      });
    })
    .hide_k {
      display: none;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id='kDropdown' style="background-color: black; height: 100px; width: 100px;"></div>
    
    <div class="hide_k hidden-dropdown">
      <ul>
        <li>LIST</li>
        <li>THAT</li>
        <li>IS</li>
        <li>HIDDEN</li>
      </ul>
    </div>

    【讨论】:

      【解决方案2】:

      您确定需要这条线吗?

      if(window.k) {
      

      第一次输入时,未分配该变量,因此不会触发事件。 如果您删除该行,效果会按预期工作。

      【讨论】:

        【解决方案3】:

        它不是第一次触发,因为还没有window.k

        一旦mouseleave 被分配。所以从第二次开始工作。

        要完成这项工作,请将$(".hidden-dropdown").removeClass("hide_k"); 移到if(window.k) 条件之外。

        这是一个有效的Code Pen

        $(document).ready(function() {
          $('#kDropdown, .hidden-dropdown').mouseleave(function(e) {
            window.k = setTimeout(function() {
              $('.hidden-dropdown').addClass("hide_k");
            }, 250)
          }).mouseenter(function(e) {
            if (window.k) {
              clearTimeout(window.k)
            }
            $(".hidden-dropdown").removeClass("hide_k");
          });
        })
        .hide_k { display: none; }
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <div id='kDropdown' style="background-color: black; height: 100px; width: 100px;"></div>
        
        <div class="hide_k hidden-dropdown">
          <ul>
            <li>LIST</li>
            <li>THAT</li>
            <li>IS</li>
            <li>HIDDEN</li>
          </ul>
        </div>

        【讨论】:

          【解决方案4】:

          第一次不工作的原因是你还没有设置window.k。改变这个:

          $('#kDropdown, .hidden-dropdown' ).mouseleave(function(e) {
              window.k = setTimeout(function(){
          

          到这里:

          window.k=true;
          $('#kDropdown, .hidden-dropdown' ).mouseleave(function(e) {
                  window.k = setTimeout(function(){
          

          正在发生的事情是您正在检查 mouseenter 上的 if(window.k){},当第一次“进入”发生时,还没有发生 mouseleave 来设置 window.k。因此,您的 if(window.k) 签入 mouseenter 第一次返回 false。但是然后你离开盒子,window.k 被设置,然后它从那里开始工作,因为你的 if(window.k) 语句然后返回 true(因为第一个 mouseleave 事件最终设置它)。希望这是有道理的!基本上这是一个时间问题,你只需要在你做任何其他事情之前设置 window.k = true 。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-05-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多