【问题标题】:Using .animate and .mouseover to let an element appear/disappear使用 .animate 和 .mouseover 让元素出现/消失
【发布时间】:2018-12-17 01:52:42
【问题描述】:

我正在学习 JavaScript 和 jQuery,在进行以下练习时遇到了问题。 我在页面右侧有一个 div,其中包含另一个较小的 div,其中包含一个带有一些 imgs 的无序列表,我只想在鼠标指针进入第一个 div 时出现。

问题是当鼠标指针进入第一个div时,较小的那个开始不受控制地上下移动。

我尝试在更大的 div 上使用 .is(:hover) 方法,正如另一个关于 SO 的问题所建议的那样,但它没有帮助。

这是我的代码:

stato = "out";

$("#control").mouseover(

  function() {

    if (stato == "out")
      $("#socialBox").animate({
        top: 300
      });
    //$("#socialBox").show();
    stato = "in";



  }

);


$("#control").mouseleave(

  function() {
    $("#socialBox").animate({
      top: -500
    });
    //$("#socialBox").hide();
    stato = "out";

  }

);
body {
  background: lightblue;
}

img {
  height: 50px;
  width: 50px;
}

ul {
  list-style-type: none;
}

#control {
  position: fixed;
  right: 0px;
  top: 0px;
  height: 100%;
  width: 100px;
  background: yellow;
}

#socialBox {
  position: fixed;
  top: -500px;
  right: 0px;
  width: 75px;
  background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="control"></div>
<div id="socialBox">
  <ul>
    <li><img id="cane" src="img/cane.jpg" /></li>
    <li><img id="gatto" src="img/gatto.jpg" /></li>
    <li><img id="koala" src="img/koala.jpg" /></li>
    <li><img id="mucca" src="img/mucca.jpg" /></li>
    <li><img id="panda" src="img/panda.jpg" /></li>
    <li id="nascondi"> X </li>
  </ul>
</div>

我也尝试过使用其他鼠标事件,例如 mouseenter 和 mouseout,但我遇到了同样的问题。

提前致谢。

【问题讨论】:

  • @Alex 感谢您的编辑:您能告诉我您对我的代码应用了哪些更改吗?我什么都看不到.. :-S 谢谢。

标签: javascript jquery jquery-animate mouseover mouseleave


【解决方案1】:

TL;DR:将您的 socuialBox div 移动到 content div 中。

完整说明: 问题都是因为事件冒泡。

首先,您的 html 需要更改,因为 socialBox div 在 control div 之外,即使在使用 mouseentermouseleave 时,事件也会反复触发。所以socialBox 被移动到control div 并使用mouseentermouseleave 事件。

第二,事件冒泡。由于事件冒泡,问题仍然出现在第一步之后。

mouseover - 当鼠标指针移入元素时触发。在子元素上移动时,子元素的事件被触发,并且导致父元素的mouseover 被触发的事件冒泡。

mouseout - 与mouseover 相同,但在离开元素时触发。

mouseenter - 仅当鼠标指针进入事件绑定的元素时触发。活动不会冒泡。

mouseleave - 与 mouseenter 相同,但在离开事件绑定的元素时触发。

要更清楚地理解,请参阅这些文档。 jQuery mouseover, jQuery mouseout.

@gilly3 有一个很好的工作小提琴来演示his answer 中的事件

stato = "out";

$("#control").mouseenter(function() {
    $("#socialBox").animate({
      top: 100
    });
    stato = "in";
});


$("#control").mouseleave(function() {
    $("#socialBox").animate({
      top: -500
    });
    stato = "out";
});
body {
  background: lightblue;
}

img {
  height: 50px;
  width: 50px;
}

ul {
  list-style-type: none;
}

#control {
  position: fixed;
  right: 0px;
  top: 0px;
  height: 100%;
  width: 100px;
  background: yellow;
}

#socialBox {
  position: fixed;
  top: -500px;
  right: 0px;
  width: 75px;
  background: red;
  pointer:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="control">
    <div id="socialBox">
      <ul>
        <li><img id="cane" src="img/cane.jpg" /></li>
        <li><img id="gatto" src="img/gatto.jpg" /></li>
        <li><img id="koala" src="img/koala.jpg" /></li>
        <li><img id="mucca" src="img/mucca.jpg" /></li>
        <li><img id="panda" src="img/panda.jpg" /></li>
        <li id="nascondi"> X </li>
      </ul>
    </div>
</div>

【讨论】:

    【解决方案2】:

    问题是您的动画#socialBox 没有嵌套在#control 中。无论您使用哪个鼠标事件,只要动画框位于光标下方,光标就会“离开”#control,从而触发隐藏动画。

    如果您想保持标记不变,可以使用计时器延迟动画。在我下面的解决方案中,如果#control mouseleave#socialBox mouseenter(反之亦然)几乎同时触发,计时器将确保不会执行动画。

    我还在动画之前调用了.stop(),以避免由于过快移动鼠标而导致多个动画排队。

    var shown = false;
    var timer;
    
    function triggerAnimation(show) {
        clearTimeout(timer);
        timer = setTimeout(function() {
            // If we're already on the same state, no need to animate
            if (show === shown) return;
    
            // Animate socialBox
            $("#socialBox").stop().animate({ top: show ? 300 : -500 });
    
            // Toggle state
            shown = !shown;
        }, 10);
    }
    
    $("#control, #socialBox")
        .mouseenter(function() { triggerAnimation(true); })
        .mouseleave(function() { triggerAnimation(false); });
    body { background: lightblue; }
    img { height: 50px; width: 50px; }
    ul { list-style-type: none; }
    #control { position: fixed; right: 0px; top: 0px; height: 100%; width: 100px; background: yellow; }
    #socialBox { position: fixed;  top: -500px; right: 0px; width: 75px; background:red; }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="control"></div>
    <div id="socialBox">
        <ul>
            <li><img id="cane" src="img/cane.jpg"/></li>
            <li><img id="gatto" src="img/gatto.jpg"/></li>
            <li><img id="koala" src="img/koala.jpg"/></li>
            <li><img id="mucca" src="img/mucca.jpg"/></li>
            <li><img id="panda" src="img/panda.jpg"/></li>
            <li id="nascondi"> X </li>
        </ul>
    </div>

    【讨论】:

      【解决方案3】:

      正如Thieri 提到的,您需要将socialBox 包装在control div 中。

      socialBox 未绑定到父 div。


      stato = "out";
      
      $("#control").mouseover(
        function() {
          if (stato == "out")
            $("#socialBox").animate({
              top: 0
            });
          //$("#socialBox").show();
          stato = "in";
        }
      );
      
      
      $("#control").mouseleave(
        function() {
          $("#socialBox").animate({
            top: -500
          });
          //$("#socialBox").hide();
          stato = "out";
        }
      );
      body {
        background: lightblue;
      }
      
      img {
        height: 50px;
        width: 50px;
      }
      
      ul {
        list-style-type: none;
      }
      
      #control {
        position: fixed;
        right: 0px;
        top: 0px;
        height: 100%;
        width: 100px;
        background: yellow;
      }
      
      #socialBox {
        position: fixed;
        top: -500px;
        right: 0px;
        width: 75px;
        background: red;
      }
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <div id="control">
        <div id="socialBox">
          <ul>
            <li><img id="cane" src="img/cane.jpg" /></li>
            <li><img id="gatto" src="img/gatto.jpg" /></li>
            <li><img id="koala" src="img/koala.jpg" /></li>
            <li><img id="mucca" src="img/mucca.jpg" /></li>
            <li><img id="panda" src="img/panda.jpg" /></li>
            <li id="nascondi"> X </li>
          </ul>
        </div>
      </div>

      【讨论】:

        【解决方案4】:

        触发行为是因为“#socialBox”进入视图,然后阻塞了mousepointer和“#control”之间的“路径”,因此脚本触发了mouseleave-event。

        首先,去掉mousemove...使用mouseenter,就可以删除stato变量了。

        接下来将“#control” div 包裹在“#socialbox”周围,如下所示:

        <div id="control">
          <div id="socialBox">
            <ul>
              <li><img id="cane" src="img/cane.jpg" /></li>
              <li><img id="gatto" src="img/gatto.jpg" /></li>
              <li><img id="koala" src="img/koala.jpg" /></li>
              <li><img id="mucca" src="img/mucca.jpg" /></li>
              <li><img id="panda" src="img/panda.jpg" /></li>
              <li id="nascondi"> X </li>
            </ul>
          </div>
        </div>
        

        【讨论】:

          猜你喜欢
          • 2020-07-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-01-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多