limu: Links mit bestimmter Klasse suchen und Linktexte ausgeben

Hiho ich möchte den Quelltext nach Links durchsuchen welche die Klasse isActive haben und dann die Linktexte der gefundenen Ergebnisse ausgeben um eine Breadcrumbnavigation aufzubauen.

Da ich mich aber erst seit kurzem ausführlicher mit JS beschäftige brauch ich eure Hilfe. :)

Hier erstmal der zusammengemurkste Code von mir^^

  
<script type="text/javascript">  
var bodyTag = document.getElementsByTagName("body");  
 function breadcrumbfunction() {  
	for (var i = 0; i < bodyTag.length; ++i) {  
	document.write('> ' + document.getElementsByClassName('isActive').text);				  
			};  
		}  
</script>  
  

Diese Funktion setze ich dann per append in das dafür vorgesehene Div ein. Leider habe ich da irgendwo nen kleinen oder größeren Fehler drin. :/
Wenn ich die Funktion mit alert() ausgeben lasse bekomme ich das Ergebnis "> undefined".

Wäre echt supi wenn Du/Ihr mir da weiterhelfen könntet da ich jetzt schon den halben Tag nur an dieser kleinen Funktion sitze. :(

lg LiMu

  1. @@limu:

    nuqneH

    var bodyTag = document.getElementsByTagName("body");
    function breadcrumbfunction() {
    for (var i = 0; i < bodyTag.length; ++i) {

    Es darf nur ein body-Element im DOM sein. Dieses ist in JS per document.body ansprechbar. document.getElementsByTagName("body") und die „Schleife“ über das eine gefundene Element machen keinen Sinn.

    document.write('> ' + document.getElementsByClassName('isActive').text);

    document.getElementsByClassName('isActive') liefert alle Elemente der betreffenden Klasse (in modernen Browsern, die das unterstützen). Hier wäre eine Schleife über die gefundenen Elemente angebracht.

    Und eine Abfrage, ob die Methode existiert, damit ältere Browser nicht mit einem Fehler aussteigen:

    var breadcrumbElements = document.getElementsByClassName ? document.getElementsByClassName('isActive') : [];

    Es gibt keine Eigenschaft 'text' für Elementobjekte. Aber '[link:https://developer.mozilla.org/de/docs/DOM/Node.textContent@title=textContent]'.

    Und document.write() ist so gut wie nie eine gute Idee. Besser textContent bzw. innerHTML verwenden (oder DOM-Methoden).

    Die Klassenbezeichnung "active" ist auch unglücklich gewählt, da sie an die CSS-Preudoklasse ':active' erinnert, die etwas ganz anderes tut. Besser wäre meist "selected" oder "current" oder hier meinetwegen "breadcrumb-path".

    Jetzt solltest du weiterkommen.

    Qapla'

    --
    „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
    1. Danke euch für die Hilfe, werde mir eure Hinweise morgen mal zu Gemüte führen. Für heute mach ich erstmal Schluss. :)

      lg limu

      1. So ich habe es jetzt mal anders gemacht und hinbekommen. Danke euch nochmals für die Hilfe und die Richtungsangaben. :)

        lg LiMu

        		function breadcrumbfunction() {  
        			for (var i = 0; i < document.getElementsByTagName("a").length; i++) {  
        				if (document.getElementsByTagName("a")[i].className == "isActive") {	  
        					$("#BreadcrumbNavi").append("> " + document.getElementsByTagName("a")[i].innerHTML);  
        				}  
        			}
        
        1. Hallo,

          ich bin zwar kein Javascript oder jQuery Experte, aber ich wage jetzt trotzdem mal einen Vorschlag.

          So ich habe es jetzt mal anders gemacht und hinbekommen.

          Da du offensichtlich jQuery verwendest, ist deine Umsetzung imho viel zu "umständlich". ;-)

          	function breadcrumbfunction() {  
          
            	for (var i = 0; i < document.getElementsByTagName("a").length; i++) {  
            		if (document.getElementsByTagName("a")[i].className == "isActive") {	  
            			$("#BreadcrumbNavi").append("> " + document.getElementsByTagName("a")[i].innerHTML);  
            		}  
            	}
          
            
          ~~~javascript
            
          function breadcrumbfunction() {  
          	$('a.isActive').each(function() {  
          		$("#BreadcrumbNavi").append(" > " + $(this).html());  
          	});  
          }  
          
          

          Wenn sich die betreffenden 'A' Elemente alle in einem gemeinsamen Elternelement befinden, kann man es zusätzlich noch darauf eingrenzen (falls die Seite noch andere 'A' Elemente beinhaltet).

          Gruß Gunther

          1. Hiho,

            danke schön da schaut der code gleich viel übersichtlicher aus. :)
            Hab der Navi jetzt auch noch eine Verlinkung verpasst.

            function breadcrumbfunction() {  
            	$('a.isActive').each(function () {  
            		$("#BreadcrumbNavi").append(" > <a href='" + $(this).attr('href') + "'>" + $(this).html() + "</a>");  
            	});  
            }
            

            Gestern noch innerlich geflucht wie so ein Spatz und heute freu ich mich dank euch.

            lg LiMu

        2. @@limu:

          nuqneH

          	function breadcrumbfunction() {  
          
            	for (var i = 0; i < document.getElementsByTagName("a").length; i++) {  
            		if (document.getElementsByTagName("a")[i].className == "isActive") {	  
            			$("#BreadcrumbNavi").append("> " + document.getElementsByTagName("a")[i].innerHTML);  
            		}  
            	}
          
            
          Dazu noch ein paar Anmerkungen:  
            
          Es ist nicht gut Elemente oder Elementkollenktionen mehrfach aus dem DOM rauszusuchen, schon gar nicht innerhalb einer Schleife. Man sollte das nur einmal und das Ergebnis in einer Variablen ablegen.  
            
          In JavaScript ohne jQuery sähe das dann so aus:  
            
          ~~~javascript
          function breadcrumbfunction()  
          {  
            var aElements = document.getElementsByTagName("a"),  
                breadcrumbNavi = document.getElementById("BreadcrumbNavi");  
            
            for (var i = 0; i < aElements.length; i++)  
            {  
              if (aElements[i].className == "isActive")  
              {	  
                breadcrumbNavi.innerHTML += "> " + aElements[i].innerHTML;  
              }  
            }  
          }
          

          Aber wie Felix schon sagte, gibt es die Kollektion der Links schon in document.links.

          Die Abfrage, ob der Klassenname "isActive" ist, ist auch problematisch. Was, wenn so’n Link mehreren Klassen angehört: "foo isActive bar"?

          In modernen Browsern gibt es das [link:https://developer.mozilla.org/en-US/docs/Web/API/element.classList@title=classList]-Objekt mit der contains-Methode:

          function breadcrumbfunction()  
          {  
            var breadcrumbNavi = document.getElementById("BreadcrumbNavi");  
            
            for (var i = 0; i < document.links.length; i++)  
            {  
              if (document.links[i].classList.contains("isActive"))  
              {	  
                breadcrumbNavi.innerHTML += "> " + document.links[i].innerHTML;  
              }  
            }  
          }
          

          Qapla'

          --
          „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
          1. Hallo,

            function breadcrumbfunction()

            {
              var breadcrumbNavi = document.getElementById("BreadcrumbNavi");

            for (var i = 0; i < document.links.length; i++)
              {
                if (document.links[i].classList.contains("isActive"))
                {
                  breadcrumbNavi.innerHTML += "> " + document.links[i].innerHTML;
                }
              }
            }

              
            Wenn man einen Link in der Schleife erzeugt, wie limu es vor hat, dann hat man ggf. eine Endlosschleife. Sowohl document.getElementsByTagName als auch document.links sind Live-Knotenlisten, die immer das DOM wiederspiegeln. Das Einfügen eines Links sorgt dafür, dass sich die Liste während der Iteration vergrößert. Hier ist jQuery vorteilhaft, weil es feste Knotenlisten zurückgibt.  
              
            Man kann die Live-Knotenliste in einen einfachen, abgekoppelten Array mit Elementknoten umwandeln:  
              
            `var links = Array.prototype.slice.call(document.links);`{:.language-javascript}  
              
            @limu: Ich verstehe allerdings nicht, wieso eine Seite auf sich selbst verlinken soll. Oder handelt es sich um die jeweilige Oberkategorie?  
              
            Noch ein Punkt, wo jQuery vorteilhaft ist:  
              
            `breadcrumbNavi.innerHTML += '…';`{:.language-javascript}  
              
            Das serialisiert den Elementinhalt zu einem String, ergänzt diesen und parst ihn wieder in einen DOM-Baum. Das spielt bei ein bisschen HTML keine Rolle, bei größeren Elementen leidet die Performance merklich. Und sämtliche Event-Handler und sonstige nicht serialisierbaren Daten im DOM gehen verloren.  
              
            Wenn man hier einfaches JavaScript schreiben will, so wäre [insertAdjacentHTML](https://developer.mozilla.org/en-US/docs/Web/API/element.insertAdjacentHTML) eine bessere Wahl:  
              
            `breadcrumbNavi.insertAdjacentHTML('beforeend', '…');`{:.language-javascript}  
              
            Diese Methode ist ziemlich unbekannt, aber äußerst nützlich. Sie wird auch von jQuery intern verwendet.  
              
            In ferner Zukunft wird es [append](http://dom.spec.whatwg.org/#parentnode) geben (DOM4):  
              
            `breadcrumbNavi.append('…');`{:.language-javascript}  
              
            Bis dato hilft einem jQuery, viele Fallstricke zu vermeiden, die reines JavaScript so mit sich bringt.  
              
            Mathias
            
            -- 
            [Chaplin.js – JavaScript application architecture using Backbone.js.](http://chaplinjs.org/)
            
    2. [latex]Mae  govannen![/latex]

      Und eine Abfrage, ob die Methode existiert, damit ältere Browser nicht mit einem Fehler aussteigen:

      var breadcrumbElements = document.getElementsByClassName ? document.getElementsByClassName('isActive') : [];

      Damit schließt man unnötigerweise IE8 aus.
      Wo ist der „nicht hilfreich“-Link (SCNR)

      var breadcrumbElements = (document.querySelectorAll) ? document.querySelectorAll('.isActive') : [];

      oder wenns beliebt

      var breadcrumbElements;  
      if (document.getElementsByClassName) {  
          breadcrumbElements = document.getElementsByClassName('isActive');  
      }  
      else if (document.querySelectorAll) {  
          breadcrumbElements = document.querySelectorAll('.isActive');  
      }  
      else {  
          breadcrumbElements = [];  
      }
      

      (wobei man den konkreten Fall als Grundlage nehemn muß; doc.qSA ist in IE8 wegen einiger Einschränkungen nicht generell nutzbar)

      Stur lächeln und winken, Männer!

      Kai

      --
      Array(16).join("x" - 1) + " Batman!"
      Wir sind die Schlumpf. Widerschlumpf ist schlumpflos. Wir werden Sie einschlumpfen.
      SelfHTML-Forum-Stylesheet
  2. Liebe(r) limu,

    möchte den Quelltext nach Links durchsuchen

    nicht den Quelltext, sondern die <a>-Elemente im DOM, also dem aus dem Quelltext erstellten Objektmodell des Dokuments. Dafür hat man document.links erfunden. Das ist eine Art Array (eine "live node list" um genau zu sein), über dessen Elemente Du iterieren (in einer Schleife abarbeiten) kannst.

    Zum Rest hat Dir Gunnar schon fachlich hilfreiches geschrieben.

    Liebe Grüße,

    Felix Riesterer.

    --
    ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
  3. હેલો

    Hiho ich möchte den Quelltext nach Links durchsuchen welche die Klasse isActive haben und dann die Linktexte der gefundenen Ergebnisse ausgeben um eine Breadcrumbnavigation aufzubauen.

    Mach doch 'ne richtige, dann haben auch Suchmaschinen was davon.

    બાય

    --
     .
    ..: