【问题标题】:Onmouseout not to run when moving mouse over to certain elements?将鼠标移到某些元素时不运行 Onmouseout?
【发布时间】:2016-12-05 04:45:20
【问题描述】:

因此,当您将鼠标悬停在 article 元素上时,此代码会播放音频剪辑。问题是当鼠标悬停在子元素上时它会停止。当鼠标悬停在通用 article 元素上并悬停在子元素上时,如何使 Stopsound 功能不运行?

编辑:基本上,当您交替悬停在哪个子元素上时,我不希望这两个函数运行。

   function PlaySound(soundobj) {
     var thissound = document.getElementById(soundobj);
     thissound.play();
   }

   function StopSound(soundobj) {
     var thissound = document.getElementById(soundobj);
     thissound.pause();
     thissound.currentTime = 0;
   }
* {
  margin: 0;
  padding: 0;
}
article24 {
  width: 50px;
  height: 100px;
  background-color: green;
}
#box24 {
  width: 50px;
  height: 50px;
  background-color: blue;
}
#present24 {
  width: 50px;
  height: 50px;
  background-color: red;
}
#bauble24 {
  width: 10px;
  height: 10px;
}
<audio id='mySound' src="http://www.freesound.org/data/previews/278/278903_3546642-lq.mp3"></audio>
<article id="article24" onmouseover="PlaySound('mySound')" onmouseout="StopSound('mySound')">
  <div id="box24">
    <h2></h2>
  </div>
  <div id="present24">
    <a href="">
      <div id="bauble24">
        <p id="belle24">""</p>
      </div>
    </a>
  </div>
</article>

【问题讨论】:

    标签: javascript html


    【解决方案1】:

    确实,只要鼠标悬停在另一个元素上,mouseout 事件就会触发,即使该元素是事件目标元素的子元素。

    但是,当您停留在父元素的范围内时,mouseover 事件也会触发 ,因此如果您可以在处理 mouseout 事件之前检测到该事件,您可以区分这种情况和父元素的真正离开。

    您可以通过使用setTimeout 延迟处理,并在您立即收到mouseover 事件时取消该操作来做到这一点:

    var timer = -1; // ID of a timer we will use
    
    function PlaySound(soundobj) {
        clearTimeout(timer); // cancel any pending StopSound action
        var thissound=document.getElementById(soundobj);
        thissound.play();
    }
    
    function StopSound(soundobj) {
        timer = setTimeout(function () { // defer the action
            var thissound=document.getElementById(soundobj);
            thissound.pause();
            thissound.currentTime = 0;
       }, 0); // 0 is enough, as the `mouseover` event is already posted in the message queue
    }
    

    【讨论】:

    • 太棒了!最简单的解决方案总是最好的。
    • 这没什么大不了的,但是如果您在剪辑完成播放后更改悬停在哪个子元素上,它会重新开始。你知道一个同样简单的解决方法吗?如果您的头上没有任何东西,请不要为之烦恼。
    【解决方案2】:

    使用 JQuery 的 .hover 函数可以解决这个问题,如 here 所述。

    注意:在音频开始之前,我的示例文件有几秒钟的延迟,因此当您将鼠标悬停在 article 上时,请等待一两分钟让音乐开始播放。

    另外,您的 adiv 标记嵌套不正确。

    最后,我已从 HTML 中删除了您的事件绑定并将其移至 JavaScript,强烈建议这样做,因为内联 HTML 事件绑定会导致“意大利面条代码”,更难调试/缩放,导致匿名全局事件处理包装函数(更改要创建的“this”binidng)并且 HTML 事件绑定不遵循更现代和更强大的 W3C DOM Event 标准

    var playing = false;
    
    var audio = document.getElementById("mySound");
    var art = document.getElementById("article24");
    
    // We don't really need two functions for start vs. stop
    // One function that simply toggles the sound based on 
    // a flag will do it. JQuery's .hover method takes two
    // arguments (a mouseover callback and a mouseleave callback)
    $(art).hover(playStop, playStop);
    
    function playStop(e) {
      // Check to see if we are playing or not and toggle based on that:
      if(!playing){
        audio.play();
        playing = true;
      } else {
        audio.pause();
        audio.currentTime = 0;      
        playing = false;     
      }
    }
    /* The following is not necessary and is only included to
       be able to visually discern the various child elements */
    article { border:10px solid black; padding:10px;} 
    div { border:5px solid red;}
    div * {border-color: blue;}
    div h2 {background:green; }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <audio id='mySound' src="http://www.stephaniequinn.com/Music/Mozart%20-%20Presto.mp3"></audio>
    
    <article id="article24">
            
      <div class="box" id="box24">
        <h2>I am in child div #1</h2>
      </div>
            
      <div id="present24">I am child div #2
        <a href="">
          <div id="bauble24">  
            <p id="belle24">I am in child div #2, but am child div #3</p>
          </div>
        </a>
      </div> 
      
    </article>

    【讨论】:

    • 如果您在文章标签中创建了子 div,您会看到,一旦您更改了悬停在哪些子元素上,音频剪辑就会重新启动。
    • 将属性移到父文章中就有我刚才提到的效果。我编辑了 OP,使属性位于文章标签中。
    • @student42 请参阅我更新的解决方案答案。
    • 我看到你删除了这个问题,所以我也删除了。
    猜你喜欢
    • 2013-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-04
    • 2012-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多