Bugfix #1 zu "Der erste Code"

Wie schön es doch war, endlich den ersten Code online gestellt zu haben – endlich
war die Welt wieder um eine Problemlösung reicher. Oder doch nicht?
Einen „kleinen“ Fehler hat der vorherige JavaScript Code: sobald man den Blog
etwas besser gestalten will, mit den „Jump Breaks“, geht da irgend etwas schief…

Das Problem:
Blogger ersetzt nicht nur den Ausdruck für den JumpBreak mit entsprechendem
HTML Code, dadurch wird auch das aktuelle Element der HTML-Seite geschlossen,
und mehr wird auch nicht angezeigt. Demnach wird, wenn man im deutschen DIV
einen JumpBreak einsetzt, alles darunter liegende einfach weg geschnitten. Somit
kann man die englische Version nicht anzeigen.

Der Plan:
Der Ausdruck für den JumpBreak muss in den Post, das ist klar: Nur so kommt
man an die korrekte URL für den kompletten Post. Da der JumpBreak alles
„wegschneidet“ was dahinter liegt, muss er einfach als letztes in den Post. Der Post
wird in 2 Hälften unterteilt (Vor JumpBreak und nach JumpBreak), sowie 2 Versionen
eingefügt (eine deutsche und eine englische). Dann nehmen wir uns zur Hilfe ein
weiteres DIV-Element, in welchem wir den anzuzeigenden Inhalt zusammenbasteln.
Ist man auf der Hauptseite des Blogs und sieht sich einen Post mit JumpBreak an,
soll zunächst der erste Teil der deutschen Version angezeigt werden, mit der Option,
zum ersten Teil der englischen Version zu wechseln. Wird der Post komplett angezeigt,
soll die komplette deutsche Version angezeigt werden (+language-switcher).
Hier werden wir gleich noch auf ein „dezentes Problem“ stoßen…

Die Lösung:
Ich unterteile die Lösung in Part1 und Part2:
Part 1 ist die Unterteilung des Posts in 2 Hälften pro Version und dessen Anzeige.
Part 2 wird behandeln, wie wir standardmäßig Teil1 der deutschen Version anzeigen.

<script type=&quot;text/javascript&quot;>
function switchlng(id, lang)
{
	var teil1 = lang + '1';
	var teil2 = lang + '2';
	var show;
	var foundmore = false;
	var foundshow = false;
	for(show=0; show<id.parentNode.children.length; show++)
	{
		if(id.parentNode.children&#91;show&#93;.id == 'show')
		{
			foundshow = true;
			break;
		}
	}
	for(var more=0; more<id.parentNode.parentNode.children.length; more++)
	{
		if(id.parentNode.parentNode.children&#91;more&#93;.className == &quot;jump-link&quot;)
		{
			foundmore = true;
			break;
		}
	}
	if(foundshow)
	{
		for(var i=0; i<id.parentNode.children.length; i++)
		{
			if(id.parentNode.children&#91;i&#93;.id == teil1)
			{
				id.parentNode.children&#91;show&#93;.innerHTML = id.parentNode.children&#91;i&#93;.innerHTML;
				if(!foundmore)
				{
					for(var j=0; j<id.parentNode.children.length; j++)
					{
						if(id.parentNode.children&#91;j&#93;.id == teil2)
						{
							id.parentNode.children&#91;show&#93;.innerHTML += id.parentNode.children&#91;j&#93;.innerHTML;
							break;
						}
					}
				}
				else
				break;
			}
		}
	}
}
</script>
<a href=&quot;&quot; onclick=&quot;switchlng(this, 'de'); return false;&quot; style=&quot;color:#CD0000;&quot;>Wechsle zu Deutsch</a> |
<a href=&quot;&quot; onclick=&quot;switchlng(this, 'en'); return false;&quot; style=&quot;color:#CD0000;&quot;>Switch to English</a>
<div id=&quot;de1&quot; name=&quot;de1&quot; style=&quot;display:none;&quot;>
</div>
<div id=&quot;de2&quot; name=&quot;de2&quot; style=&quot;display:none;&quot;>
</div>
<div id=&quot;en1&quot; name=&quot;en1&quot; style=&quot;display:none;&quot;>
</div>
<div id=&quot;en2&quot; name=&quot;en2&quot; style=&quot;display:none;&quot;>
</div>
<div id=&quot;show&quot; name=&quot;show&quot; style=&quot;display:block;&quot;>
</div>

Ok, wir haben also die DIV-Elemente de1, de2, en1 und en2 für die Texte vor und
nach JumpBreaks, in beiden Sprachen.
Der JavaScript Code macht folgendes: Erst überprüfen wir, ob das show-DIV
überhaupt vorhanden ist und speichern, welches Kind-Element vom Post das ist.
Danach wird geprüft, ob ein JumpBreak vorhanden ist.
Dann wird der Post zusammengebaut: Wurde das show-DIV gefunden, schreiben wir
erst mal den ersten Teil der gewünschten Sprache in das show-DIV.
Haben wir einen JumpBreak gefunden, müssen wir nichts weiter tun – Der Jump-
Break Link ist ja schon in der HTML-Seite drin.
Wurde kein JumpBreak gefunden, sieht man sich den ganzen Post an. Also wird nun
noch, nach dem gleichen Prinzip wie vorher, Teil2 der gewünschten Version in das
show-DIV eingefügt.
So weit so gut. Nur reflektieren wir den Code erst einmal: Es muss die switchlng
Funktion aufgerufen werden, damit etwas in das show-DIV geschrieben wird.
Schlecht, da wir auch direkt beim Seitenaufruf, ohne Sprachwechsel, schon Inhalt
präsentieren wollen. Wir brauchen also noch eine Methode, die aufgerufen wird,
sobald die Seite geladen ist, die uns einmal die Sprache auf deutsch wechselt.
Hier kommt ein neues Problem auf: Wir haben die switchlng-Methode bisher immer
aus dem Post aus aufgerufen, damit wir jeden einzelnen Post in deutsch oder englisch
anzeigen lassen können. Die Methode braucht daher ein HTML-Element welches sich
in einem Post befindet, um einen einzelnen Post zu „aktualisieren“.
Führen wir JavaScript im Post sofort, ohne Beschränkung aus, kommt es zu Fehlern,
weil die Seite noch nicht komplett geladen ist, der Code aber schon ausgeführt wird.
Also benutzen wir das onLoad Ereignis vom body Element. Dann müssen wir „nur“
ein Kind-Element für jeden einzelnen Post auf der Seite finden und die switchlng
Methode ein mal damit aufrufen. Und das geht wie folgt:

<head>
<script type=&quot;text/javascript&quot;>
function init()
{
	var element = document.getElementById(&quot;Blog1&quot;);
	var current = new Array(element.parentNode);
	var Path = new Array(&quot;widget Blog&quot;, &quot;blog-posts hfeed&quot;, &quot;date-outer&quot;, &quot;date-posts&quot;, &quot;post-outer&quot;, &quot;post hentry&quot;, &quot;post-body entry-content&quot;);
	for(var i=0; i < Path.length; i++)
	{
		current = getChildren(current, Path&#91;i&#93;);
	}
	for(var i=0; i<current.length; i++)
	{
		var child = current&#91;i&#93;.firstChild;
		switchlng(child, 'de');
	}
}
function getChildren(current, name)
{
	_children = new Array();
	for(var j = 0; j < current.length; j++)
	{
		for(var k = 0; k < current&#91;j&#93;.children.length; k++)
		{
			if(current&#91;j&#93;.children&#91;k&#93;.className == name)
			_children.push(current&#91;j&#93;.children&#91;k&#93;);
		}
	}
	return _children;
}

</script>
</head>

//DAS onLoad EREIGNIS MUSS IM TEMPLATE HINZUGEFÜGT WERDEN!
//THE onLoad EVENT HAS TO BE ADDED IN THE TEMPLATE!
<body class='loading'onLoad=&quot;init();&quot;>

Die Hierarchie der Seite bleibt glücklicherweise immer gleich, so können wir uns zum
„tiefsten“ Element, welches eine ID hat, direkt vorarbeiten, und von dort an können
wir einem festen Pfad folgen. Wir müssen nur beachten, dass verschiedene
Unterelemente vorhanden sein könnten (Posts und Werbung). Wir hangeln uns so weit
vor, bis wir alle Elemente haben, die Posts sind. Dann rufen wir für jedes davon, ein
mal die switchlng-Methode auf (mit irgend einem Unterelement). Und schon haben
wir, was wir wollten.
Nun müssen wir nur noch die Post-Vorlage erneuern, und uns in Zukunft an das neue
Schema (2 Sprachen mit je 2 Teilen, 1 Show-Div, 1 JumpBreak) halten.
Sobald ich noch etwas mehr Zeit habe, werde ich noch eine kurze Sicherheitsanalyse
für diesen Code gestalten, eigenes JavaScript auf einem Blog sollte immer nur sehr
vorsichtig eingesetzt werden. Eine ratsame Tätigkeit wäre es auf jeden Fall, sämtliche
Strings zu escapen, und eventuell auch noch ein paar if-abfragen einzubauen (sind wir
wirklich im richtigen Element?)

Die neue Post-Vorlage befindet sich im ersten Code-Teil. Und nicht vergessen, das
Template zu ändern und das onLoad Ereignis hinzu zu fügen!
Ich wünsche weiterhin viel Spaß beim Lesen.

MfG
NoMad

Dieser Eintrag wurde veröffentlicht in JS
Bookmarken: Permanent-Link Schreibe einen Kommentar oder hinterlasse einen Trackback: Trackback-URL.
Achtung: Wordpress interpretiert bestimmte Zeichenfolgen als Markup und verändert diese. Nutzt für Programmcode lieber Gist oder PasteBin-Services und verlinkt die Code-Schnipsel.

Post a Comment

Ihre E-Mail wird niemals veröffentlicht oder verteilt. Benötigte Felder sind mit * markiert

*
*

Du kannst diese HTML Tags und Attribute verwenden: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>