Deus Figendi: Bubbling vermeiden

Hi,
ich habe ein Problem, welches dem von Tine nicht ganz unähnlich ist ^^

Folgendes: Ich bekomme von PHP ein JSON-Objekt. Bitte nicht schimpfen, ich werde es anständig parsen für den Test verwende ich eval().
Hier das JSON-Objekt:

var php_output = eval( [                                              //  
 {"categorie":true,"id":0,"name":'1', "children":[                    //  
  {"categorie":true,"id":1,"name":'1.1', "children":[                 //  
   {"categorie":false,"id":2,"name":'1.1.1',"dicetag":'[aaa]'} ,      //  
   {"categorie":false,"id":3,"name":'1.1.2',"dicetag":'[bbb]'} ,      //  
   {"categorie":false,"id":4,"name":'1.1.3',"dicetag":'[ccc]'} ,      //  
   {"categorie":false,"id":5,"name":'1.1.4',"dicetag":'[ddd]'}        //  
  ]} ,                                                                //  
  {"categorie":false,"id":6,"name":'1.2',"dicetag":'[eee]'}           //  
 ]} ,                                                                 //  
 {"categorie":true,"id":7,"name":'2', "children":[                    //  
  {"categorie":true,"id":8,"name":'2.1', "children":[                 //  
   {"categorie":false,"id":9,"name":'2.1.1',"dicetag":'[fff]'} ,      //  
   {"categorie":false,"id":9,"name":'2.1.2',"dicetag":'[ggg]'} ,      //  
   {"categorie":false,"id":9,"name":'2.1.3',"dicetag":'[hhh]'} ,      //  
   {"categorie":false,"id":9,"name":'2.1.4',"dicetag":'[iii]'}        //  
  ]} ,                                                                //  
  {"categorie":false,"id":10,"name":'2.2',"dicetag":'[jjj]'}          //  
 ]}  ,                                                                //  
 {"categorie":true,"id":11,"name":'3', "children":[                    //  
  {"categorie":true,"id":12,"name":'3.1', "children":[                 //  
   {"categorie":false,"id":13,"name":'3.1.1',"dicetag":'[kkk]'} ,      //  
   {"categorie":false,"id":14,"name":'3.1.2',"dicetag":'[lll]'}       //  
  ]} ,                                                                //  
  {"categorie":false,"id":17,"name":'3.2',"dicetag":'[mmm]'}          //  
 ]}                                                                   //  
]);

Es ist also ein Array von Objekten die so aufgebaut sind:
categorie:Bool
id:int
name:string
children (wenn categorie):array von gleichartigen Objekten
dicetag (wenn categorie nicht):string
(ich hab mir das nicht ausgedacht!)
Manch einer ahnt sicher schon wohin das führt, dieses Objekt-Array überführe ich in verschachtelte Listen:

function make_ul(my_object,my_depth) {  
 var this_ul = document.createElement('ul');  
 for (var i = 0; i < my_object.length; i++) {  
  var this_li = make_li(my_object[i],my_depth);  
  this_ul.appendChild(this_li);  
 }  
 if (my_depth > 0) {  
  this_ul.style.display = "none";  
 }  
 return this_ul;  
}  
  
function make_li(my_object,my_depth) {  
 var this_li = document.createElement('li');  
 var this_text = document.createTextNode(my_object.name);  
 this_li.appendChild(this_text);  
 if (my_object.categorie) {  
  var this_ul = make_ul(my_object.children,my_depth+1);  
  this_li.appendChild(this_ul);  
  this_li.addEventListener( 'click', function() { toggle_visibility(this); }, false );  
 } else {  
  //Anderes onClick-Event  
 }  
 return this_li;  
}  
  
var whole_ul = make_ul(php_output,0);

Klappt soweit auch. Wenn ich this_ul.style.display = "none"; weg lasse sehe ich den ganzen Baum so wie er sein soll.
Nun will ich die Äste aber natürlich auf- und zuklappen können, daher gibt es eine toggle-Funktion (die oben auch registriert wird):

  
  
function toggle_visibility(li_element) {  
 var ul_element = li_element.firstChild;  
 if (ul_element.nodeType != 1) {  
  var ul_element = ul_element.nextSibling;  
 }  
 if (ul_element.style.display == "block") {  
  ul_element.style.display = "none";  
 } else {  
  ul_element.style.display = "block";  
 }  
}

Es ist zu erwarten, dass "firstChild" ein Textknoten ist, daher "blätter" ich weiter, denn es könnte ja auch der gesuchte sein :)
getElementsByTagName verwende ich hier nicht, falls künftig irgendwann da mal keine ul drin steht.

So, toggle funktioniert im Prinzip auch, aber... es bubblet. Will sagen: Wenn ich den ersten Knoten öffne ist alles gut, ich kann ihn auf und zu klappen wie ich möchte. Wenn ich dann aber einen Ast eine Ebene tiefer öffne (z.B. 1.1) dann klappt das im Grunde auch aber gleichzeitig wird die höhere Ebene geschlossen, weil ich natürlich auch auf jenes Element klicke.

Ist auch alles total logisch, aber ich steh halt auf dem Schlauch wie ich das verhindern könnte.

--
sh:( fo:| ch:? rl:( br:& n4:& ie:{ mo:} va:) de:µ_de:] zu:) fl:( ss:| ls:[ js:(
  1. Hi,

    so viel Gelaber, für so wenig Problem ...?

    Dass du JSON benutzt, dass von einem PHP-Script erzeugen lässt (, und den Webserver vom Taschengeld, dass dir Omi gibt, gemietet hast, und dass dieser Webserver in einem Rechenzentrum in XY steht, und dass die Hardware von Firma Foo in Bar gebaut wurde, ...) - das ist doch alles vollkommen uninteressant für das eigentliche Problem.

    So, toggle funktioniert im Prinzip auch, aber... es bubblet. Will sagen: Wenn ich den ersten Knoten öffne ist alles gut, ich kann ihn auf und zu klappen wie ich möchte. Wenn ich dann aber einen Ast eine Ebene tiefer öffne (z.B. 1.1) dann klappt das im Grunde auch aber gleichzeitig wird die höhere Ebene geschlossen, weil ich natürlich auch auf jenes Element klicke.

    http://www.quirksmode.org/js/introevents.html

    MfG ChrisB

    --
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
  2. Hallo,

    So, toggle funktioniert im Prinzip auch, aber... es bubblet. Will sagen: Wenn ich den ersten Knoten öffne ist alles gut, ich kann ihn auf und zu klappen wie ich möchte. Wenn ich dann aber einen Ast eine Ebene tiefer öffne (z.B. 1.1) dann klappt das im Grunde auch aber gleichzeitig wird die höhere Ebene geschlossen, weil ich natürlich auch auf jenes Element klicke.

    hilft Dir molilys Archivbeitrag weiter.

    Freundliche Grüße

    Vinzenz

  3. Hi,

    So, toggle funktioniert im Prinzip auch, aber... es bubblet.

    möglicherweise hilft das:
        function cancleBubble(event) {
            try {
                e =  event? event : window.event;
                if (e.stopPropagation) {
                    e.stopPropagation();
                } else {
                    e.cancelBubble = true;
                }
            } catch (err) { }
        }

    hierdurch wird das bubbeln gestoppt.

    Gruesse, Joachim

    --
    Am Ende wird alles gut.