2016-10-02 5 views
1

ich eine Gruppe haben, die einige Elemente in sich enthält: Ein Pfad (der schwarze) und 2 Rects (die rosa und blau)SVG Schnapp schweben über gruppierten Elemente

enter image description here

Sie alle gehören zu derselben Gruppe.

Im Grunde, was ich tun möchte, ist ich mag eine Funktion auszuführen, wenn die Gruppe schwebt über so ich tun:

group.hover(function(e){ //set up hovering 
      console.log("hover bubble"); 
     }, function(e) { 
      console.log("unhover bubble"); 
    }); 

Aber die Art und Weise Gruppen arbeiten wird jedes Element innerhalb der Gruppe wird, dass die Hover-Funktion ... wenn ich also über den schwarzen Pfad schwebe und mich dann zum rosa Rechteck beginne, wird es denken, dass es ein Unhover vom schwarzen Pfad ist und dann ein Schwebeflug über die rosa Rekta. Das ist nicht was ich will.

Ich möchte den Mauszeiger über den gesamten gruppierten Bereich bewegen und die Funktion ausführen lassen, sobald der gesamte gruppierte Bereich verschoben ist, und die Funktion zum Entfernen, wenn der gesamte gruppierte Bereich nicht mehr sichtbar ist.

Art wie wenn alle diese Elemente in einem div waren, und ich über die div schwebte ..

+0

Sicher erstellen Sie eine Gruppe und nicht ein Set? – Ian

Antwort

1

kann ich sehen, dass Sie snap.svg und raphael als Tags, aber hier ist eine Lösung reine JS verwenden.

Ich machte eine einfache SVG mit einer Gruppe, die eine schwarze rect (Ihren Pfad), eine rosa rect und eine blaue rect. Wenn Sie über die Gruppe schweben, sie „schweben Blase“ in der Konsole anmeldet, wenn Sie es schweben ausloggt „unhover Blase“:

var group = document.querySelector("g"); 
 

 
function isInside(node, target) { 
 
    for (; node != null; node = node.parentNode) 
 
     if (node == target) return true; 
 
} 
 

 
group.addEventListener("mouseover", function(event) { 
 
    if (!isInside(event.relatedTarget, group)) 
 
     console.log("hover bubble"); 
 
}); 
 

 
group.addEventListener("mouseout", function(event) { 
 
    if (!isInside(event.relatedTarget, group)) 
 
     console.log("unhover bubble"); 
 
});
svg { 
 
    background-color: tan; 
 
}
<svg width="300" height="300"> 
 
\t <g> 
 
\t \t <rect x="40", y="40", width="220", height="220", fill="black"></rect> 
 
\t \t <rect x="60", y="60", width="80", height="80", fill="pink"></rect> 
 
\t \t <rect x="160", y="60", width="80", height="80", fill="blue"></rect> 
 
\t </g> 
 
</svg>

Dies ist die Ursache des Problems:

Immer wenn der Mauszeiger einen Knoten betritt oder verlässt, wird ein "Mouseover" - oder "Mouseout" -Ereignis ausgelöst [...] Leider ist das Erstellen eines solchen Effekts nicht so einfach wie das Starten des Effekts auf "mouseover" und endend es auf "mouseout". Wenn die Maus von einem Knoten zu einem ihrer untergeordneten Elemente bewegt wird, wird "mouseout" auf dem übergeordneten Knoten ausgelöst, obwohl die Maus den Knotenbereich nicht wirklich verlassen hat. Um die Dinge noch schlimmer zu machen, propagieren diese Ereignisse genauso wie andere Ereignisse, und Sie erhalten daher auch "mouseout" -Ereignisse, wenn die Maus einen der Kindknoten des Knotens verlässt, auf dem der Handler registriert ist.

Quelle des Codes und des Angebots: Eloquent JavaScript, von Marijn Haverbeke.

+0

Danke dafür, können Sie Ihren Code ein wenig erklären? – unconditionalcoder

+0

Aus dem Buch: * "Die isInside-Funktion folgt den übergeordneten Links des angegebenen Knotens, bis sie entweder den Anfang des Dokuments erreicht (wenn der Knoten null wird) oder das übergeordnete Element, nach dem wir suchen" *. Diese Funktion gibt also "true" zurück, wenn Sie von einem Kind zu einem anderen Kind wechseln, gibt aber "undefined" zurück, wenn Sie das Elternelement betreten oder verlassen. Das Negieren von undefined (mit '!') Ergibt "true", und der Code nach "if" wird nur dann ausgeführt, wenn Sie das übergeordnete Element eingeben oder verlassen. –