Wer kennt es nicht: Mehrere Datentabellen oder -abschnitte auf einer Seite und der Benutzer verliert schnell den Überblick. Die Lösung: Ein wenig JavaScript, mit ein wenig CSS und ein paar DIVs garniert, das ganze kräftig durchkneten und fertig ist der Tabbed-Content für jeden Einsatzzweck. Weiterlesen…
prototype
Parallax Scrolling Effekt mit Prototype/Scriptaculous JavaScript
Wer sich an Spiele wie “Shadow of the Beast” erinnert, der muss sich auch zwangsweise an diesen netten Pseudo-3D Effekt erinnern, mit dem diese Spiele ihren coolen Look erhielten. Parallax Scrolling nennt man diese Technik übrigens, bei der verschiedene Layer aus Grafiken übereinander gelegt und unterschiedlich schnell horizontal oder auch vertikal bewegt werden.
Weil mir gestern Abend langweilig war, habe ich mich damit beschäftigt den Parallax Effekt versuchsweise in JavaScript umzusetzen. Als Bibliotheken verwende ich dabei PrototypeJS und Scriptaculous. Nachdem ich mit einem Grafikprogramm meine 3 Layer gezeichnet und PNGs mit Transparenz exportiert hatte, ging es an die Umsetzung. Schnell wurde mir klar, wie simpel es im Grunde ist mit ein wenig CSS und JavaScript diesen Effekt zu erzeugen. Weiterlesen…
AJAX loading Grafik neben dem Mauszeiger anzeigen
Um dem Benutzer zu visualisieren, dass gerade ein asynchroner HTTP Request ausgeführt wird, hat die AJAX Welt das ajax-loading.gif erfunden. Diese kleine animierte Grafik gibt es in vielen Varianten und bittet den Benutzer optisch darum zu warten, bis der Inhalt geladen wurde. Sinnvolle Sache, sonst klickt er sich nämlich doof und dusselig, falls es doch mal ein wenig länger dauert. Kurzerhand habe ich das auch mal hier in Form des springenden Punktes im Blog eingebaut.
Zuerst habe ich meinen Body-Tag mit einer ID versehen, damit ich mit Prototype einfach auf das Body-Element zugreifen kann.
<body id="body">
Dann habe ich ein kleines DIV samt Bild mit den CSS Eigenschaften “position:absolute” und “display:none” hinzugefügt. Das DIV kann mit Prototype so nämlich frei positioniert werden, wird aber vorerst nicht angezeigt.
<!-- Create hidden bouncing ball layer (ajax-loading.gif or similar) --> <div id="bouncer" style="position:absolute;display:none"><img src="/images/ball.gif" alt=""/></div>
Als nächstes wird ein Event-Handler an den Event “onmousemove” des Body-Tags geklebt. Der Handler ermittelt die aktuellen Maus-Koordinaten und platziert das (noch immer versteckte) DIV versetzt neben der Maus.
// Move the bouncing ball next to mouse cursor position
$('body').onmousemove = function( e ) {
mouseX = Event.pointerX( e );
mouseY = Event.pointerY( e );
$('bouncer').setStyle( { left: (mouseX+15) + 'px', top: (mouseY+15) + 'px' } );
return true;
}
Danach habe ich meine AJAX-Load Funktion noch so abgeändert, dass mit Beginn des Requests das DIV mit der Grafik angezeigt wird und bei Erfolg oder Fehler wieder versteckt wird. Anbei eine kleine Beispiel-Funktion.
// Example function to use the bouncer
function ajax_load( uri )
{
$('bouncer').show();
new Ajax.Request( uri, {
onSuccess: function( r ) {
$('bouncer').hide();
},
onFailure: function( r ) {
$('bouncer').hide();
}
});
}
Wirklich einfach, aber ein toller und ausnahmsweise auch mal sinnvoller Effekt. ;-)
WordPress dazu bringen Seiten per AJAX zu laden
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.
