2016-12-04 2 views
1

Mit diesem Code wird ein Audioclip wiedergegeben, wenn Sie den Mauszeiger über die article Elemente bewegen. Das Problem ist, dass es stoppt, wenn die Maus auf untergeordnete Elemente schwebt. Wie kann ich die Stopsound-Funktion nicht ausführen, wenn die Maus über die allgemeinen article Elemente und auf die untergeordneten Elemente bewegt wird?Onmouseout nicht ausgeführt, wenn die Maus auf bestimmte Elemente bewegt wird?

BEARBEITEN: Grundsätzlich möchte ich keine der Funktionen ausführen, wenn Sie abwechselnd das untergeordnete Element wechseln, über das Sie den Mauszeiger halten.

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>

Antwort

1

der Tat das mouseout Ereignis auslöst, wenn die Maus bewegt sich über ein anderes Element, auch wenn dieses Element ein Kind des Zielelements des Ereignisses ist.

Aber das mouseover Ereignis auslösen auch, wenn Sie innerhalb der Grenzen des übergeordneten Elements bleiben, wenn Sie also dieses Ereignis erkennen konnten, bevor das mouseout Ereignis zu behandeln, können Sie zwischen diesem Fall und dem wahren Weggang von der unterscheiden Elternelement

Dies Sie durch Verzögerung der Behandlung mit setTimeout tun können, und Aufhebung dieser Aktion, wenn Sie ein mouseover Ereignis haben folgende sofort:

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 
} 
+0

Brilliant! Die einfachste Lösung ist immer die beste. – student42

+0

Das ist zwar kein großer Deal, aber wenn Sie das Sub-Element ändern, auf dem Sie den Mauszeiger halten, nachdem der Clip abgespielt wurde, beginnt er neu. Kennen Sie eine ähnlich einfache Lösung? Wenn du nichts auf deinem Kopf hast, mach dir keine Sorgen damit. – student42

1

Mit .hover Funktion des JQuery löst dieses Problem als here erläutert.

HINWEIS: Es gibt ein paar Sekunden Verzögerung in meiner Beispieldatei, bevor das Audio startet, also wenn Sie den Mauszeiger über die article halten, warten Sie ein oder zwei Sekunden, bis die Musik startet.

Auch Ihre a und div Tags wurden falsch verschachtelt.

Zuletzt habe ich Ihre Ereignisbindung aus dem HTML entfernt und diese in das JavaScript verschoben, was sehr empfohlen wird, da inline HTML-Ereignisbindung "Spaghetti-Code" verursacht, schwieriger debug/scale, anonyme globale Ereignisbehandlungs-Wrapperfunktionen verursacht (das ändern „dieses“ binidng) erstellt und Ereignis HTML verbindlich folgt nicht der viel moderner und robuster W3C DOM Event Standard

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>

+0

Wenn Sie Kind divs innerhalb des Artikels Tag youd gemacht, dass, wenn Sie ändern die Untergeordnete Elemente, über die Sie schweben, der Audioclip wird neu gestartet. – student42

+0

Das Verschieben der Attribute in den übergeordneten Artikel hat den gerade erwähnten Effekt. Ich habe das OP so bearbeitet, dass sich die Attribute im Artikel-Tag befinden. – student42

+0

@ student42 Bitte sehen Sie meine aktualisierte Antwort für die Lösung. –

Verwandte Themen