XHTMLforum

XHTMLforum (http://xhtmlforum.de/index.php)
-   Javascript & Ajax (http://xhtmlforum.de/forumdisplay.php?f=83)
-   -   Events vererben/überladen? (http://xhtmlforum.de/showthread.php?t=45740)

Dirk1 06.05.2007 12:37

Event order /propagation
 
Hallo erst einmal,

in diesem Forum lese ich schon eine ganze Weile mit.
Dies ist mein erster Beitrag. Meine Frage ist vielleicht etwas ungewöhnlich,
aber für einen JS-Profi vielleicht doch nicht unlösbar.

Ich arbeite mit einem Content-management-system, dass mir an einer Stelle die Suppe versucht zu versalzen.

Im Header-bereich steht u.A. etwas in der Art:

Code:

        document.onmousemove=T3_onmousemoveWrapper;
        document.onload=T3_onloadWrapper;

Da im restlichen Code das onmousemove-event nirgendwo abgefragt wird, gehe ich mal davon aus, dass dies implizit für alle Objekte gilt.

Ich würde dies gerne für einzelne Objekte deaktivieren.
Ich habe dazu bereits mit
Code:

<div onload="return true">...
experimentiert.

Das scheint aber keine Wirkung zu haben.

Weiss jemand eine Lösung für das Problem?
Freue mich über jede Antwort.

Gruß
Dirk

Dirk1 07.05.2007 11:33

Stop bubbling
 
So, ich habe den Titel des Beitrags noch einmal geändert, weil mir mittlerweile klar ist, worum es im Kern geht.

Wenn zwei ineinander verschachtelte Elemente das gleiche Ereignis abfragen (einen event-handler dazu besitzen), wird erst der eine und dann der andere ausgeführt. Bei MS-IE normalerweise zuerst das innen liegende Element.

Die Lösung wäre jetzt gegeben, wenn man an der Stelle das Weiterreichen des events (propagation) abbrechen könnte.

Wer ist so tief drin in Javascript, darüber Bescheid zu wissen?

duessu 07.05.2007 12:02

Salü
Vielleicht geht es wenn du die Events anders einbindest (Javascript :: Event Handler bzw. DOM:element.addEventListener - MDC) --> useCapture verändern (ist aber nur eine Vermutung)

Ich persönlich würde das event genau nur auf den objekten einschalten auf dem du es brauchst, also nicht global auf dem document sonder auf dem jeweiligen tag.

Dirk1 07.05.2007 17:46

cancelBubble=true;
 
So, ich habs.
Es muß auf der inneren Ebene ein zusätzlicher event-handler eingerichtet werden. Dort kann über CancelBubble=true das weiterreichen zur nächsthöheren Ebene unterbunden werden, oder weitere Operationen durchgeführt werden.

Für alle dies interessiert hier ein kleines Testprogramm:

Code:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>stop bubbling</title>

<script language="JavaScript">

function onclickA(e)

{
        if (!e) var e = window.event //MSIE
        alert("Click innen");
        e.cancelBubble=true;
        e.stopPropagation();
        return true;
}

function onclickB(e)
{
        alert("Click aussen");
        return true;
}

function onloadH()
{
        ela = document.getElementById("a")
        elb = document.getElementById("b")
        if (ela.addEventListener) {
                ela.addEventListener("click", onclickA, false);
                elb.addEventListener("click", onclickB, false);
        }
        else if (ela.attachEvent){
                ela.attachEvent("onclick", onclickA);
                elb.attachEvent("onclick", onclickB);
        }
        return true;
}
</script>


</head>
<body onload="onloadH()">
        <div id="b" style="width:200px; height:200px; background:red">
                <div id="a" style="width:100px; height:100px; background:blue"></div>
        </div>


</body>
</html>

Noch ein paar Anmerkungen dazu.
Es muß unterschieden werden zwischen MSIE und dem Rest der Welt.
Bei MS heisst wird das event nicht über "e", sondern über "window.event" referenziert.
Deshalb die erste Zeile in den Funktionen, die das event abarbeiten sollen.

Weiterhin heisst es bei MS "attachEvent" statt "addEventListener".
Bei letzterem gibt es einen zusätzlichen dritten Parameter, mit dem bestimmt werden kann, ob Ereignisse von aussen oder von innen abgearbeitet werden soll.
Der hier vorgestellten Intention nach soll es von innen nach aussen gehen. Deshalb der dritte Parameter auf "false".

Bei Microsoft hingegen geht es immer von innen nach aussen.

Dirk

Schmeily 23.12.2011 09:22

Lösung gesucht
 
Fast hätte ich gedacht mit dem vorherigem Post eine Lösung für mein Problem gefunden zu haben. Dem ist leider nicht so.
Vielleicht hab ich ein Brett vorm Kopf und einer von Euch sieht die Lösung sofort.

Also hier das Problem:
Mouseover auf dem äußerem DIV (rot) löst ein Event aus und Mouseout auch.
Bei hover über blau und grün soll nichts passieren. In CSS klappt das alles. Da das Ganze aber noch etwas chicker werden soll (Fading) kommt Javascript in Spiel. So werden bei Mouseover und Mouseout auf blau und grün ungewollter Weise fadein und fadeout ausgelöst. Wie kann man das abstellen?
Hat jemand eine Idee??? Wäre prima!
So, und nun wünsche ich Euch ein frohes Fest und einen guten Rutsch ins neue Jahr!

Hier kurz der Quellcode:

HTML-Code:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>stop bubbling</title>

<script language="JavaScript">
var EvtCount = 0;


function onclickB(e) {
        if (!e) var e = window.event //MSIE
                EvtCount++;
        alert("rot rein - Eventnr.: " + EvtCount);
        e.cancelBubble=true;
        e.stopPropagation();
        return true;
}

function onclickBO(e) {
        if (!e) var e = window.event //MSIE
                EvtCount++;
        alert("rot raus - Eventnr.: " + EvtCount);
        e.cancelBubble=true;
        e.stopPropagation();
        return true;
}

function onloadH() {
        elb = document.getElementById("b")
        if (elb.addEventListener) {
                elb.addEventListener("mouseover", onclickB, false);
                elb.addEventListener("mouseout", onclickBO, false);
        }
        else if (elb.attachEvent){
                elb.attachEvent("mouseover", onclicB);
                elb.attachEvent("mouseout", onclickBO);
        }
        return true;
}
</script>


</head>
<body onload="onloadH()">
        <div id="b" style="width:200px; height:200px; background:red">
                <div id="a" style="width:100px; height:50px; background:blue;color:#ffffff;margin:10px 0 0 10px;top:50px">mache nichts</div>
                <div id="c" style="width:100px; height:50px; background:green;color:#ffffff;margin: 0 0 0 10px">mache nichts</div>
        </div>


</body>
</html>


Dirk1 23.12.2011 20:16

Hallo Schmeily,

interessant, dass nach so langer Zeit jemand auf diesen thread stösst.

Zwei Probleme sehe ich bei dir.

1. Du fängst die Ereignisse der inneren Elemente nicht ab. Deshalb meldet sich immer nur der rote Kasten.

2. Wenn du z.B. auf blau hoverst, wird offensichtlich "mouseout" auf rot ausgelöst. Da dies aber nur rot betrifft, kannst du es durch blau nicht abfangen.


Was genau hast du vor?
Vielleicht solltest du heutzutage mal einen Blick auf jquery werfen?

Grüße
Dirk

moontan 04.01.2012 12:25

Hi Schmeily,

ich weiss nicht ob Dir das hilft - aber wenn Du die inneren Divs bei denen nichts passieren soll aus der Struktur nimmst - also nicht in das rote Div schreibst sondern ausserhalb definierst und das als positioniertes Elment über Deinen roten Divs schiebst sollte das so funktionieren wie Du möchtest.

Ob sich Deine Projekt so umsetzen lässt weiß ich natürlich nicht - aber durch die Verschachtelung die Du hast ist das Event mouseover div id=b immer true - auch wenn man mit der Maus über die inneren blauen und grünen Divs geht.
Da hilft dann auch kein cancelBubble - es ist ja im Prinzip auch keine Bubble.

LG
Uli

Schmeily 29.01.2012 16:54

Danke Euch nochmal
 
Ja, Du hast Recht. Mit jquery ist das kein Problem und damit ist es ja (hab ich auch) ohne Probleme machbar.
Mir ging es einfach um das Verständnis.


Alle Zeitangaben in WEZ +2. Es ist jetzt 10:33 Uhr.

Powered by vBulletin® Version 3.8.11 (Deutsch)
Copyright ©2000 - 2024, vBulletin Solutions, Inc.

© Dirk H. 2003 - 2023