WordPress, PHP, JavaScript, Web 2.0, Gaming, Motorräder, Fotografie, Piratenpartei, Privates

javascript

WordPress dazu bringen Seiten per AJAX zu laden

Fr 23 Okt. 09 # Permalink

Wer im Browser sein Javascript aktiviert hat, der wird sicherlich sehen, dass beim Klicken eines Links der Content hier dynamisch geladen wird. Um das in meinem WordPress Theme zu realisieren, habe ich zwei einfache JavaScript Funktionen geschrieben. Als JS Bibliotheken nutze ich dafür Prototype und Scriptaculous, es ginge aber auch sicherlich mit JQuery.

Vorteil der Lösung: Wenn ein Fehler auftritt, oder im Browser kein JavaScript aktiviert ist, dann funktioniert die Seite ganz normal, was nebenbei auch sehr Suchmaschinen freundlich ist.

Die erste Funktion “fixLinks” die ich nutze, hat den Zweck an alle Links, die nicht bestimmten Kriterien entsprechen – z.B. Links auf Bilder, externe Links oder aber Links in WordPress Backend – eine “onclick” Aktion anzufügen. Die neue “onclick” Aktion des Links ruft dann die zweite Funktion “get_page” auf, welche die Seite läd und mit einem netten Effekt dann anzeigt.

function fixLinks()
{
	var myLinks = document.links;
	var myBrowserType = (window.attachEvent ? 1 : (window.addEventListener ? 2 : 0));
	var myDomain = 'thegeek.de';
	for( var i = 0; i < myLinks.length; i++ )
	{
		// Get the href
		myHref = myLinks[i].href.toString();
		// Get the onclick action
		myOnClick = myLinks[i].onclick ? myLinks[i].onclick : '';
		// Only attack onclick action, if not jscript links, images, wp-admin features and internal link
		if( 	myOnClick == ''
			&& myHref.indexOf( "#" ) != (myHref.length - 1)
			&& myHref.indexOf( "javascript:" ) == -1
			&& myHref.indexOf( "wp-admin" ) == -1
			&& myHref.indexOf( "#respond" ) == -1
			&& myHref.indexOf( "/trackback" ) == -1
			&& myHref.indexOf( "/feed" ) == -1
			&& myHref.indexOf( "/wp-login" ) == -1
			&& myHref.indexOf( ".jpg" ) == -1
			&& myHref.indexOf( ".gif" ) == -1
			&& myHref.indexOf( ".png" ) == -1
			&& myHref.indexOf( myDomain) != -1
		)
		{
			switch( myBrowserType )
			{
				case 1:
					Event.observe( myLinks[i], 'click', function( e ) { if( !get_page( this.href ) ) e.stop(); } );
					break;
				case 2:
					myLinks[i].setAttribute( "onclick", "return get_page( this.href );" );
					break;
				default:
					// Do nothing
			}
		}
	}
}
// body onload="fixLinks()" und die Sache läuft. :-)

Die zweite Funktion bewegt zuerst den Inhalt an die beim Init ermittelt Position außerhalb des Bildschirms und läd dann per asynchronem HTTP Request die neue Seite. Der Inhalt der Seite ist im Theme mit einem HTML Kommentar gekennzeichnet und wird mittels Regular Expression ermittelt, dann in den Layer eingefügt, um die Seite danach wieder an die ursprüngliche Position zu bewegen. Keine Ahnung, ob's im IE klappt, ist mir allerdings auch ziemlich egal. :-)

Sollte etwas schief gehen, dann gibt die Funktion "true" zurück, womit der Klick auf den Link ganz normal ausgewertet wird. Hat alles geklappt, liefert die Funktion "false" zurück und der Browser folgt dem angeklicktem Link dann nicht. So ist auf jeden Fall gewährleistet, dass die neue Seite angezeigt wird - auf die synchrone oder asynchrone Art.

	var	c_w = $('content').getWidth();
	var	c_x = $('content').viewportOffset()[0];
	var	c_leave = (c_x + c_w) * -1;
	var	c_come = c_leave * -1;
	var	c_search = /()((?:.|[\r\n])*?)()/mgi;
	var	get_page_return_code = false;
	var	effect_running = false;
	function get_page( uri )
	{
		get_page_return_code = false;
		if( effect_running == false )
		{
			effect_running = true;
			new Effect.Move( 'content', { x: c_leave, y: 0, mode: 'relative', duration:0.5,
				afterFinish:function() {
					new Ajax.Request(	uri, {
									method:'get',
									onSuccess: function( r ) {
											$('content').update( '' );
											SearchResult = c_search.exec( r.responseText );
											while( SearchResult != null )
											{
												if( SearchResult[ 2 ] )
													$('content').update( SearchResult[ 2 ] );
												SearchResult = c_search.exec( r.responseText );
											}
											new Effect.Move( 'content', { x: c_come, y: 0, mode: 'relative', duration:0.5, afterFinish:function () {effect_running = false;} } );
											fixLinks();
									},
									onFailure: function( r ) {
										get_page_return_code = true;
										effect_running = false;
									}
					});
				}
			});
		}
		return get_page_return_code;
	}

Klar handelt es sich hier um ziemliches sinnfreies Eyecandy. Ich mag Eyecandy.