Javascript - mouseover

Treverer

Grand Admiral Special
Mitglied seit
23.07.2001
Beiträge
3.211
Renomée
107
Standort
Trier
  • SIMAP Race
  • QMC Race
boah, bei javascript bekomme ich echt immer den brass.
also, es geht um folgendes:

ich habe mehrere boxen per div definiert, welche alle mit mouseover, onclick & mouseout ereignissen verbunden sind. bei mouseover erscheint um die box herum eine gestrickelte linie.

das problem: die boxen können (und sollen) in beliebiger folge ineinander verschachtelt sein. dies hat aber offensichtlich zur folge, daß ein mouseover ereignis für eine "verschachtelte" box auch für deren übergeordneten rahmen (der parent sozusagen) gilt. an diesem bild wird es schön deutlich:

mouseover.png


wäre ich mit der maus über der weißen box, wäre auch nur diese markiert, da sie keine box über sich hat. die textbox und die rote box wiederum sind verschachtelt. bewege ich mich nur über die dunkelblaue box, dann ist eben diese & die türkise box markiert - die hellgrüne dagegen nicht (child), was auch gut ist.

mir war vorher nicht klar, daß dies so läuft :] okay, läßt sich wohl auch kaum ändern und kann ja auch sinn machen. ABER! das gleiche gilt auch für onclick. klicke ich also auf die grüne, oberste box löst dies tatsächlich drei onclick ereignisse aus (für grün, dunkelblau & türkis). ich muß/will aber tatsächlich nur die box selektieren, welche sich tatsächlich unter der maus befindet. shit 8-(

hat jemand eine idee?

p.s.: die hierachie aufzulösen ist keine feine idee, weil ich ja die boxen gerade innerhalb der parent-box positionieren will.
 
event.stopPropagation() in W3C-Browsern
oder
window.event.cancelBubble = true;
im IE.

Dein Problem ist das "Event Bubbling", also ein Event wird in der Hierarchie nach oben hin weitergereicht.
Unterbinden tun das diese Aurufe bzw. zuweisungen in der eventhandler-funktion
Beispiel

box.click = function(ev) { //ev = eventobjekt
// mach hier irgendwas
ev.stopPropagation();
}
 
event.stopPropagation() in W3C-Browsern
oder
window.event.cancelBubble = true;
im IE.

Dein Problem ist das "Event Bubbling", also ein Event wird in der Hierarchie nach oben hin weitergereicht.
Unterbinden tun das diese Aurufe bzw. zuweisungen in der eventhandler-funktion
Beispiel

box.click = function(ev) { //ev = eventobjekt
// mach hier irgendwas
ev.stopPropagation();
}

hi!

vielen dank. wieder was gelernt, nämlich daß man diese sachen unterbinden kann. :-*

dumm nur, daß ich mittlerweile alles auf document.event auswertung "umgestellt" habe und "einfach" schaue, welches drecks-element d'runter liegt. ich muß so sprechen, weil es echt der letzte dreck ist mit javascript: jeder backt seine eigenen brötchen.

'jetzt' zum beispiel quäle ich mir einen ab wegen der positionierung der elemente relativ zum parent. aber 'style.left" ist einfach nur müll, da es zum einen keine prozente in pixel umrechnet und zum anderen durch css definition (anscheinend?) nicht wirklich gesetzt wird. ich erinnere mich dunkel daran, dieses problem schon einmal gehabt zu haben. und dabei konzentriere ich mich derzeit nur auf firefox - was soll's erst werden mit ie, safari, opera etc.pp. *buck*

na ja, immerhin läuft die auswahl des jeweiligen element jetzt richtig. wie gesagt, ich habe alle mouseover, onclick, mouseout & mousedown & mouseup ersetzt mit event routinen, welche für das gesamte dokument laufen. wird mir später auch das einbinden von strg, alt, shift erleichtern. 8) war insofern ganz gut, bereits in das beschriebene problem rein zu rennen...aber eigentlich hasse ich es, das ganze javascript gedöns *nein*
 
Och eigentlich ists garnicht so wild, das event-objekt ist einer der schwachpunkte, zugegeben aber das W3C-DOM-Objektmodell bilden die ganzen Browser eigentlich recht gut ab... und um sich derartige Arbeit zu erleichtern gibts Hilfsbibliotheken alla jQuery.
Left mit % werten habe ich noch nie versucht, kann mir aber auch nicht vorstellen wie er das interpretieren sollte!? - da du in js bist kannst du die % ja selber mit der breite / höhe des elternelements verrechnen und das dann in pixel setzen.

style.left wird schon umgesetzt, allerdings nehmen Elemente einen Left-Wert nicht unter allem Umständen an.
Meistens nur bei position:relative;
oder position:absolute; oder auch position:fixed;
Der default position:static, den jedes element von hause aus hat, positioniert es einfach im "fluss"... um ein element in seinem parent einzurücken o.ä. braucht man aber auch kein left, da reicht eine margin zu definieren (oder ein padding auf dem parent)

da position:absolute und position:relative sich immer auf das nächsthöhere element beziehen das ebenfalls eine dieser Positioniereungen (alternativ auf den body) trägt, muss man dafürmanchmal etwas tricksen.
Angenommen man will ein kleines div am boden eines größeren divs ausrichten, dann gibt man dem großen "position:relative;left:0;top:0;" damit es an seiner angestammten position verbleibt, aber als "besonder positioniertes element" gilt. und dem kleinen div da drin kann man dann "position:absolute; bottom:0;" geben was bedeutet, positioniere es absolut gemessen am nächsten Parent der nicht position:staiuc hat, und setze es mit 0px abstand zum boden hin.

Grüßchen
ich
 
Och eigentlich ists garnicht so wild, das event-objekt ist einer der schwachpunkte, zugegeben aber das W3C-DOM-Objektmodell bilden die ganzen Browser eigentlich recht gut ab... und um sich derartige Arbeit zu erleichtern gibts Hilfsbibliotheken alla jQuery.
Left mit % werten habe ich noch nie versucht, kann mir aber auch nicht vorstellen wie er das interpretieren sollte!? - da du in js bist kannst du die % ja selber mit der breite / höhe des elternelements verrechnen und das dann in pixel setzen.

style.left wird schon umgesetzt, allerdings nehmen Elemente einen Left-Wert nicht unter allem Umständen an.
Meistens nur bei position:relative;
oder position:absolute; oder auch position:fixed;
Der default position:static, den jedes element von hause aus hat, positioniert es einfach im "fluss"... um ein element in seinem parent einzurücken o.ä. braucht man aber auch kein left, da reicht eine margin zu definieren (oder ein padding auf dem parent)

da position:absolute und position:relative sich immer auf das nächsthöhere element beziehen das ebenfalls eine dieser Positioniereungen (alternativ auf den body) trägt, muss man dafürmanchmal etwas tricksen.
Angenommen man will ein kleines div am boden eines größeren divs ausrichten, dann gibt man dem großen "position:relative;left:0;top:0;" damit es an seiner angestammten position verbleibt, aber als "besonder positioniertes element" gilt. und dem kleinen div da drin kann man dann "position:absolute; bottom:0;" geben was bedeutet, positioniere es absolut gemessen am nächsten Parent der nicht position:staiuc hat, und setze es mit 0px abstand zum boden hin.

Grüßchen
ich

ich denke, an der grafik kann man erkennen, daß ich eh mit position:absolute arbeite.
das entscheidende problem bei style.left ist, daß der wert durch javascript ausdrücklich gesetzt werden muß. ein setzen durch css reicht definitiv nicht. :P
ich hatte aber die obige anordnung erst in laufzeit generiert, mit "myStyle.insertRule" also als css. jetzt habe ich zumindest die positionierung ersetzt durch ein "document.getElementById(object_id).style.top=attribut_value;" - und schon funktioniert auch das korrekte auslesen.

ich werde mir jquery mal genauer anschauen. wäre nicht unwahrscheinlich, daß ich es grundsätzlich gebrauchen kann. was mir aber wirklich noch fehlt, ist eine grafikbibliothek (bei jquery habe ich nichts gefunden dazu), mit der ich linien zwischen den objekten zeichnen kann. vor wochen hatte ich da schon mal was gefunden, aber wieder vergessen, was es war...

update:
gerade gefunden: http://raphaeljs.com/
genau, was ich brauche, denke ich ...ach was: viel besser, zu gut :-)
 
Zuletzt bearbeitet:
Wenn das SVG benutzt, schießt dur dir aber bei älteren IEs ins Knie, das sollte klar sein.

Ob dus glaubst oder nicht, ich hab erst kürzlich eien "Bug Meldung" von einer meiner Pages bekommen wo sich auf Nachfrage herausgestellt hat dass IE 6 benutzt wurde... solche fossivlien gibts also noch...

.insertRule benutze ich eher selten, wenn ich irgendwelche mouseover-effekte mache geht das meistens indem ich die class des Objektes auf eine andere switche, die dann per CSS gepflegt ist.
Daher kanns gut sein dass das "Nebenwirkungen" hat.

Beachten sollte man noch den häufig beobachteten Fehler, dass man immer eine einheit mitgeben muss, unter umständen wird .stye.left = 15 also ignoriert, weil es .style.left = "15px" heißen müsste.
FF mag das auch ohne schlucken, andere Browser unter Umständen nicht.

Manchmal mag auch die Reihenfolge eine Rolle spielen... also wenn er das style.left per CSS nciht akzeptiert ist womöglich zum Zeitpunkt wo er das auswertet das position:absolut noch garnicht "angekommen"..!?
Es gibt manchmal die Komischsten seiteneffekte bei CSS und JS im zusammenspiel.
Deswegen versuche ich so wenig styles in JS hardzucoden wie möglich, genieriere ne Latte CSS-Klassen und benutze JS dann bestenfalls zum switchen der klassen.

Das was du da per JS onmouseover mit der gestrichelten Linie gebaut hast ließe sich auch per CSS ausdrücken...
z.B.
#diveleemntname:hover {
border: 1px dotted red;
}
Die Firefüchse verstehen :hover aund noch einige pseudoklassen nämlich nicht nur auf Links sondern auch auf einer Reihe anderer Elemente.

Grüßchen
ich

P.S. jQuery ist keine grafikbibliothek, besitzt aber eine Reihe sehr netter funktionen, ist einfach anzuwenden und normalisiert die eventobjekte, wenn man die Handler per jQuery verknüpft. Dann kann man in den Handlerfunktionen das Eventobjekt nach w3C Standard nutzen, also mit .stopPropagation() und .which um den tastencode zu bekommen usw. und braucht nicht mehr auf das IE-Event-Objektmodell extra abzuprüfen.
Um z.b. allen divs mit Css-klasse "container" einen eventhandler zu verpassen, schreibt man in jQuery einfach:
$("div.container").bind("mouseover",function(ev) {
//mach hier irgendfwas nützliches
ev.stopPropagation(); // bubbeln unterbinden
});

und fertig ist der Gag.
Auch so geschichten wie "finde von element x aus den nächstgelegenen parent der eine td ist" usw. geht mit der .closest("td") - funktion kinderleicht, ohne große schleifen etc.
und um an alle Lindknoten von x zu kommen schreibt man .children(). optional kann gefiltert werden auf alle Kindknoten eines bestimmten Typs, z.B. wenn man nur IMGs haben will .children("img")
und so weiter... ich würde im Alltag kirre werden ohne jQuery ;)
http://jquery.com/
 
Zuletzt bearbeitet:
... ich würde im Alltag kirre werden ohne jQuery ;)
http://jquery.com/


hallo Ge0rgy,

so, ich werde auch langsam kirre. bin einfach nicht mehr fit genug zum programmieren :P

zum stand der dinge (war ja lange pause):

ich habe nun das generieren der grafik (ehedem div-boxen) in Raphaël—JavaScript Library ausgeführt. hat manche vorteile - aber eben auch nachteile.

z.b. funktioniert das gemeinsame verschieben der verschachtelten div-boxen nicht mehr, was mir ehedem so wichtig war *buck*. muß ich wohl eine eigene routine bauen. auch gibt es keine durch werte setzbare z-ebene mehr (nur noch tofront, toback befehle) - muß ich also auch eine eigene liste führen. ändert aber alles nicht daran, daß der jetzige weg der bessere ist (wegen der zukunft ;) ).

doch nun zur frage, von der ich hoffe jemand hat eine lösung:

rechtecke besitzen die eigenschaft "x" und "y", ellipsen dagegen "cx" und "cy". also muß ich bei einer verschiebe-funktion für die verschiedenen objekte verschiedene wege gehen. dumm nur, daß ich bisher keinen weg finde, die objekte auf ihren typ zu prüfen.

vielleicht bin ich zu doof zum suchen - aber bin schon echt stunden dran...
 
Ähm, ich kenne die JS-Lib nur vom Namen her, nie damit gearbeitet...
Aber ein Objekt abzuprüfen ist in Javasctipt entweder mit typeof möglich, geht aber AFAIK nur bei eingebauten Typen, also
var x = "abc";
alert(typeof(x))
Sollte sowas wie "String" ausgeben.

Andernfalls Prüft man einfach eigenschaften ab.
Also wenn ein rechteck keine property cx besitzt, eine ellipse aber schon, sollte ein
if (meinobjekt.cx) {
alert("ich bin eine ellipse");
} else {
alert("nichts da...");
}
Dir schon deutlich genug zeigen womit du es zu tun hast...!?

Zu den verschachtelungen kann ich nichts sagen, da ich nicht weiß wie Raphael die Objekte anlegt, wenn die sich im DOM befinden, solltest du über .parentNode ... navigieren können, wenn die dinger nur JS-Objekte sind, wirds etwas komplizierter herauszukriegen welche davon übereinander liegen....

Da bin ich aber mangels Erfahrung mit Raphael letztlich überfragt, sorry...

Gruß,
ich
 
Ähm, ich kenne die JS-Lib nur vom Namen her, nie damit gearbeitet...
Aber ein Objekt abzuprüfen ist in Javasctipt entweder mit typeof möglich, geht aber AFAIK nur bei eingebauten Typen, also
var x = "abc";
alert(typeof(x))
Sollte sowas wie "String" ausgeben.

Andernfalls Prüft man einfach eigenschaften ab.
Also wenn ein rechteck keine property cx besitzt, eine ellipse aber schon, sollte ein

Dir schon deutlich genug zeigen womit du es zu tun hast...!?

Zu den verschachtelungen kann ich nichts sagen, da ich nicht weiß wie Raphael die Objekte anlegt, wenn die sich im DOM befinden, solltest du über .parentNode ... navigieren können, wenn die dinger nur JS-Objekte sind, wirds etwas komplizierter herauszukriegen welche davon übereinander liegen....

Da bin ich aber mangels Erfahrung mit Raphael letztlich überfragt, sorry...

Gruß,
ich

na, brauchst dich doch nicht zu entschuldigen. ich bedanke mich ja vielmehr für die schnelle antwort. an den weg, einfach nach dem proberty zu testen, dachte ich auch schon - ist aber unschön.

als info zur graphics-library: die befehle beruhen auf Scalable Vector Graphics (SVG) und ich kann auf die objekte auch zugreifen ohne die bibliotheks-funktionen zu nutzen. aber das ist alles noch neuland *suspect*

update:

oh man, folgendes geht doch:

type=event.target;
if (type=="[object SVGRectElement]")

ich dachte es ginge nicht, da es mit einer switch/case anweisung nicht funktioniert. warum auch immer, vermutlich fehlt die umwandlung in string...genau deswegen "liebe" ich javascript...:P
 
Zuletzt bearbeitet:
Zurück
Oben Unten