JQuery oder JavaScript: Inhaltsverzeichnis erstellen

Linus_for_you

Grünschnabel
Für eine HTML-Softwaredokumentation, die nur offline verwendet wird,
brauche ich eure Hilfe.

Und zwar will ich ein Inhaltsverzeichnis erstellen, dass alle Überschriften dynamisch erfasst und daraus ein sinnvoll durchnummeriertes Inhaltsverzeichnis erstellt.

Ich hab aber keine Ahnung wo ich da genau anfangen soll, da ich noch ein Anfänger im Hinblick auf JavaScript bin.

die Struktur der Überschriften ist immer gleich. Es gibt ein DIV mit einer Klasse die immer mit "gsc" anfängt und danach eine <h1>
also z.B. so
Code:
<div class="gscTitel">
    <h1>Ich bin die Überschrift</h1>
         <div class="gscSubTitel">
              <h1>Ich bin die 2. Überschrift</h1>
         </div>
</div>

diese Struktur kann leider nicht verändert werden (also z.b. mit h2, h3, h4 etc erweitert werden)

das erste Resultat sollte sein:
1 Ich bin die Überschrift
1.1 Ich bin die 2. Überschrift

nach Möglichkeit sollen die Überschriften 2. Ordnung eingerückt sein.
Im absoluten Idealfall soll vor den Überschriften 2. Ordnung und niedriger ein "+" stehen (Icon), über dass man die Überschrift und alle Überschriften darunter zusammenklappen (ausblenden) kann.

Ich hoffe ihr könnt mir helfen. Ich freue mich über alle hilfreichen Tipps und Codebeispiele.
 
Man kann so was innerhalb von Minuten runter hacken (dank jQuery). Hast du denn schon was versucht?

Erstmal würde ich alle Überschriften der ersten Ebene Selektieren. Dann über diese iterieren und mir alle Unterpunkte holen. Und das für alle Ebenen. Da springt einem quasi Rekursion sofort ins Auge.

Wird das irgendwie kommerziell verwendet oder ist das für dich privat?
 
Es ist für die Softwaredokumentation hier an der Hochschule.
Ich weiß jetzt nicht ob das für dich als kommerziell zählt,
aber privat ist es nicht.

Ja ich hab schon vermutet, das jQuery das Mittel der Wahl ist. JQuery is echt toll! :D

Erstmal würde ich alle Überschriften der ersten Ebene Selektieren.
Tja und da fängt es schon an. Ich hab in der JQuery Doku schon sehr intesiv gesucht aber nichts passendes gefunden.

Wenn es dir nicht zu viele Umstände macht, könntest du mir dann vielleicht etwas konkreter beschreiben wie du vorgehen würdest? Also vielleicht kleine Codebeispiele geben damit ich lernen kann wie das genau funktioniert?
 
Die jQuery Doku ist zwar hervorragend, aber zum Selektieren benutzt man CSS-Selektoren. Die findest du dort nicht ;).

Kannst du bitte etwas mehr HTML zeigen? Aus den zwei Ebenen an Überschriften lässt sich nicht erkennen, wie z.B. zwei Überschriften auf der gleichen Ebene aussehen oder die dritte Ebene.

EDIT:
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
	
	<title>TOC</title>
</head>

<body>
	<div>
		<h1>Ich bin die Überschrift</h1>
		
		<div>
			<h1>Ich bin die 2. Überschrift</h1>
			
			<div>
				<h1>Ich bin die 3. Überschrift</h1>
			</div>
			
			<div>
				<h1>foobar Ich bin die 3. Überschrift</h1>
				
				<div>
					<h1>Bacon</h1>
				</div>
			</div>
		</div>
	</div>
	<div>
		<h1>Foo Ich bin die Überschrift</h1>
		
		<div>
			<h1>Foo Ich bin die 2. Überschrift</h1>
			
			<div>
				<h1>Foo Ich bin die 3. Überschrift</h1>
			</div>
		</div>
	</div>
	<div>
		<h1>Bar Ich bin die Überschrift</h1>
		
		<div>
			<h1>Bar Ich bin die 2. Überschrift</h1>
			
			<div>
				<h1>Bar Ich bin die 3. Überschrift</h1>
			</div>
		</div>
	</div>
	
	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
	<script type="text/javascript">
	/* <![CDATA[ */
	function walk( toc , $elem ) {
		if( ! $elem.size() ) {
			return;
		}
		
		var $kids = $elem.find( '> div' );
		
		$kids.each(function() {
			var $heading = $(this).find( '> h1' );
			
			if( $heading.size() ) {
				return walk( toc[ $heading.text() ] = {}, $(this) );
			}
		});
	}
	
	$(function() {
		var toc = {};
		
		walk( toc , $('body') );
		
		alert( JSON.stringify( toc ) );
	});
	/* ]]> */
	</script>
</body>

</html>

Liefert folgendes JSON als Inhaltsverzeichnis. Daraus jetzt Listen zu generieren ist nochmal eine völlig andere Baustelle.

Javascript:
{
    "Ich bin die Überschrift": {
        "Ich bin die 2. Überschrift": {
            "Ich bin die 3. Überschrift": {},
            "foobar Ich bin die 3. Überschrift": {
                "Bacon": {}
            }
        }
    },
    "Foo Ich bin die Überschrift": {
        "Foo Ich bin die 2. Überschrift": {
            "Foo Ich bin die 3. Überschrift": {}
        }
    },
    "Bar Ich bin die Überschrift": {
        "Bar Ich bin die 2. Überschrift": {
            "Bar Ich bin die 3. Überschrift": {}
        }
    }
}
 
Zuletzt bearbeitet:
Hier mal ein kleiner Abschnitt aus dem Quelltext.
Du siehst hier quasi Kapitel 5 und 6.
Es gibt schon ein kleines JavaScript-File, dass über die Datei läuft und die Kapitel richtig nummeriert. (Kommt nicht von mir, sondern hab ich irgendwo im Netz gefunden)
"Übersicht" kriegt dann die 5, "Programm" die 5.1, "Foo bar" die 5.1.1 etc.
Und diese Nummerierung muss ich ja auch irgendwie in das Inhaltsverzeichnis kriegen.
HTML:
<div class="gscOverview">
<h1>&Uuml;bersicht</h1>
    <div class="gscProgramm">
    	<h1>Programm</h1>
        <div class="gscFoobar" widget="foobar">
            <h1>Foo bar</h1>

            <div class="gscContentBlock">
				<div class="gscFooVisual"><img src="images/content/foobar.png"></div>
				<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.  </p>  
                         
            </div>
        </div>
    </div>
    <div class="gscgsceddableFoo">
    	<h1>Foo widgets</h1>

        <div class="gscBar" widget="Bar">
            <h1>Bar Foo</h1>
            <div class="gscContentBlock">
            	<div class="gscWidgetBar"><img src="images/content/barfoo.png"></div>
				<p>Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. </p>
                      
            </div>
        </div>
    </div>  

</div>    

<div class="gscWidgets">
	<h1>Widgets Description</h1>
    <div class="gscContentBlock">
        <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
        
    </div>        

	<div class="gscWidgetSpecification" widget="Barfoobar">
    	<h1>Widget Bar Foo Bar</h1>
    	<div class="gscWidgetDescription">

        	<p>Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
            
        </div>
        <div class="gscLorem">
            <h1>Lorem</h1>
            <div class="gscConsetetur">
            	<h1>Consetetur Sadipscing</h1>
                 <div class="gscBlock">

                    <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>

					<img src="images/content/widgetbarfoo.png">          

                    <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
      			 
                 </div>
            </div>
            <div class="gscDolores">
                <h1>Dolores</h1>

                <div class="gscContentBlock">
                    <img src="images/content/dolores.png">
                    <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p>
                    <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>    
                                                        
                </div>
            </div>   
            
        </div>

hab mir dein kleines Script eben angeschaut bin aber nicht sehr schlau daraus geworden... :(
 
Wie sieht denn das Skript aus dem Internet aus? Vielleicht lässt die die Inhaltsverzeichnis-Funktionalität einfach dort integrieren. Ich kann mich im Moment nicht konzentrieren, hatte heute morgen Klausur.
 
So, hier das Script
Code:
var counter = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
function updateHeadlines(root, level) {
	var childs = root.childNodes;
	for (var i=0; i<childs.length; i++) {
		if(childs[i].nodeName=="H1") {
		  if(level>0) counter[level-1]++;
		  if(level<7) childs[i].innerHTML = getNumbering(level) + " " + childs[i].innerHTML;
		  childs[i].style.fontSize = "" + (28 - level*2) + "px";
		}
		if(childs[i].nodeName=="DIV" && childs[i].className!="gscTitel") {	  
		  updateHeadlines(childs[i], (level+1));
		}
	}
	counter[level] = 0;
	
}

function getNumbering(level) {
	var str = "";
	for(var i=0;i<level;i++) str += (str!=""? "." + counter[i] : counter[i]);
	return str;
}

Wie war denn die Klausur? Gut gelaufen?
 
Wie war denn die Klausur? Gut gelaufen?

Ja, war ok. Ich bin nur irgendwie im Moment nicht in Höchsform. Es ging in der Klausur um AJAX, PHP, XSLT und XSD (Am Computer).

Ich hab meinen Code von weiter oben etwas erweitert. Ich muss jetzt leider wieder weg. Die restlichen Punkte bekommen wir auch noch hin.

HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
	
	<title>TOC</title>
</head>

<body>
	<div class="gscOverview">
	<h1>&Uuml;bersicht</h1>
		<div class="gscProgramm">
			<h1>Programm</h1>
		    <div class="gscFoobar" widget="foobar">
		        <h1>Foo bar</h1>

		        <div class="gscContentBlock">
					<div class="gscFooVisual"><img src="images/content/foobar.png"></div>
					<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.  </p>  
		                     
		        </div>
		    </div>
		</div>
		<div class="gscgsceddableFoo">
			<h1>Foo widgets</h1>

		    <div class="gscBar" widget="Bar">
		        <h1>Bar Foo</h1>
		        <div class="gscContentBlock">
		        	<div class="gscWidgetBar"><img src="images/content/barfoo.png"></div>
					<p>Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. </p>
		                  
		        </div>
		    </div>
		</div>  

	</div>    

	<div class="gscWidgets">
		<h1>Widgets Description</h1>
		<div class="gscContentBlock">
		    <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
		    
		</div>        

		<div class="gscWidgetSpecification" widget="Barfoobar">
			<h1>Widget Bar Foo Bar</h1>
			<div class="gscWidgetDescription">

		    	<p>Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
		        
		    </div>
		    <div class="gscLorem">
		        <h1>Lorem</h1>
		        <div class="gscConsetetur">
		        	<h1>Consetetur Sadipscing</h1>
		             <div class="gscBlock">

		                <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>

						<img src="images/content/widgetbarfoo.png">          

		                <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>
		  			 
		             </div>
		        </div>
		        <div class="gscDolores">
		            <h1>Dolores</h1>

		            <div class="gscContentBlock">
		                <img src="images/content/dolores.png">
		                <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p>
		                <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>    
		                                                    
		            </div>
		        </div>   
		        
		    </div>
	
	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
	<script type="text/javascript">
	/* <![CDATA[ */
	function walk( toc , $elem ) {
		if( ! $elem.size() ) {
			return;
		}
		
		var $kids = $elem.find( '> div' );
		
		$kids.each(function() {
			var $heading = $(this).find( '> h1' );
			
			if( $heading.size() ) {
				return walk( toc[ $heading.text() ] = {}, $(this) );
			}
		});
	}
	
	function output( toc , numbering ) {
		var list = '';
		var counter = 1;
		
		for(var k in toc) {
			if(toc.hasOwnProperty(k)) {
				list += '<li>' + getNumbering(numbering, counter) + ' ' + k + '</li>'
				
				list += output( toc[k] , getNumbering(numbering, counter) );
				
				counter++;
			}
		}
		
		if(list.length) {
			return '<ol style="list-style-type:none;">' + list + '</ol>';
		} else {
			return '';
		}
	}
	
	function getNumbering( numbering , counter ) {
		if(numbering === '') {
			return counter;
		}
		
		return numbering + '.' + counter
	}
	
	$(function() {
		var toc = {};
		
		walk( toc , $('body') );
		
		var lists = output( toc , '' );
		
		$('body').prepend(lists);
	});
	/* ]]> */
	</script>
</body>

</html>
 
ok super.. also das läuft schon mal soweit.
das nächste Problem ist nun, wie ich die Anker-Links im Dokument selbst setze (manuell oder evt sogar automatisch)? Und wie ich dann in der Inhaltsliste die passenden Überschriften mit den entsprechenden Anker verlinke...
 
Müssen es Anker sein?

Javascript:
//Hier könntest du noch sinnvollere Selektoren nehmen, weil es kommen bestimmt neben dem Inhaltsverzeichnis noch andere Listen vor

var items = $('li');
var heading = $('h1');

items.click(function() {
	var i = items.index( this );
	var h = heading.eq( i );
	
	$(window).scrollTop( h.offset().top );
});
 

Neue Beiträge

Zurück