Week 10: Back to editing
En we zijn er weer met een nieuwe blogpost. Week 10 is officieel verleden tijd. Anders als de voorbije paar weekjes had deze week voor mij wel een aantal stevige uitdagingen in petto.
3e keer, goeie keer
Gert gaf mij deze week de opdracht om een wel bijzondere image slideshow te schrijven in jQuery. De bedoeling was om in een webpagina de achtergrondafbeelding om de zoveel tijd te doen veranderen met een leuk effectje. De achtergrondafbeeldingen moesten in willekeurige volgorde afgespeeld worden en om het nog extra uitdagend te maken mocht een achtergrondafbeelding zich geen 2x achter elkaar herhalen. Bovendien moest de code werken in elke browser, inclusief Internet Explorer 6. Deze uitdaging heb ik uiteindelijk 3 keer over moeten doen. Ik leg even mijn aanpak uit. Voor wie zich niet zo interesseert in het technische raad ik aan om dit eventjes te skippen :)
Mijn eerste plan was om de achtergrondafbeelding herhalend te laten in laden in een <div></div> met een negatieve z-index en absolute positionering zodat deze altijd op de achtergrond bleef. Eerst stelde ik een array op met daarin alle paden naar de images. Vervolgens maakte ik een afspeellijst waar de afbeeldingen willekeurig in werden geplaatst. Op het moment dat de pagina werd geladen, ging het script van start en werd de afspeellijst overlopen. Wanneer deze was afgelopen werd de afspeellijst weer opgesteld in een andere volgorde (om herhalingen te voorkomen). Iedere keer een afbeelding geladen is, wordt de volgende eronder geplaatst en vervaagt de eerste. Deze werkwijze werkte zeer goed in alle browsers behalve in IE6. Van zodra de eerste afbeelding zijn overgang deed naar de tweede stopte het script om één of andere reden.
Mijn tweede aanpak had ongeveer hetzelfde basisidee. In plaats van met 1 achtergrond div te werken maakte ik deze keer gebruik van 2 divs samen met een 3e div om te cachen. Met dezelfde stappen als voordien schreef ik mijn array weg in een afspeellijst. De eerste afbeelding van die afspeellijst werd in de eerste div gestoken, de tweede afbeelding in de tweede div en de derde afbeelding in de cacher. Enkel de 1e afbeelding werd met jQuery getoond. Na een bepaald aantal seconden werd de 2e div over de 1e div geplaatst met een fade-effect waardoor de 1e niet meer zichtbaar was. Op dat moment verplaatste de afbeelding die zich in de cacher bevond naar de 1e div en werd een nieuwe afbeelding in de cacher gestoken. Na weer een aantal seconden werd dan de 1e div weer zichtbaar en verdween de 2e div die op zijn beurt ook een nieuwe afbeelding kreeg. Dit script werkte in alle browsers. Het probleem echter was dat van zodra alle images in Internet Explorer in het geheugen zaten en de bezoeker nadien terug zou keren naar de webpagina, het script niet meer wou starten. Dit omdat Internet Explorer een apart systeem gebruikt om webpagina’s te laden.
Mijn derde en laatste aanpak was het rechtstreeks plaatsen van alle images in een achtergrond div. Er wordt weer een afspeellijst gecreëerd en aan de hand van die afspeellijst wordt een afbeelding gekozen die zichtbaar wordt gemaakt. Deze afbeelding krijgt een klasse toegewezen, alle andere afbeeldingen zonder die klasse worden uit het zicht gehaald terwijl de gekozen afbeelding in het zicht blijft. Deze methode is wellicht niet de meest snelheids vriendelijke methode maar het is wel een methode die door alle browsers, inclusief IE6, kan worden uitgevoerd zonder problemen.
Voor de rest van de week heb ik een aantal wireframes een grondige update gegeven. Ik krijg vaak de kans om mee te denken over mogelijke oplossingen bij problemen en leer dagelijks nog steeds nieuwe dingen bij. (zoals Ext JS 4).
Voor volgende week heb ik nog een aantal subpagina’s die ik moet ontwerpen, nog een wireframe dat aangepast moet worden en een promotiepagina voor last minute vakanties.. ( wat mij soms toch doet wegdromen naar de zomer). Enfin, het weekend is van start gegaan. Zoals altijd, tot de volgende..
Hieronder mijn uiteindelijke jQuery code:
var speed = 3000;
// Variable to store the images we need to set as background
var photos = [ 'assets/images/fadebox/1.jpg',
'assets/images/fadebox/2.jpg',
'assets/images/fadebox/3.jpg',
'assets/images/fadebox/4.jpg',
'assets/images/fadebox/5.jpg',
'assets/images/fadebox/6.jpg'];
$(document).ready(function() {
var shuffle = function(o){
for( var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
}
var seq = new Array();
for( var i = 1 ; i <= photos.length ; i++ ){
seq[i-1] = i;
}
s = shuffle(seq);
// Creating a background div
var background = $('#fancy_background');
if( background.length == 0 )
{
background = $('<div id="fancy_background"></div>');
background.insertBefore( $('body').children().first() );
}
// Make new image
var img = $('<img />');
// Place all the images
var i = 0;
$(photos).each(function(){
$('#fancy_background').append('<img />');
$('#fancy_background img:last-child').attr( {'src': photos[i], 'style': 'display: none; z-index: -1;', 'class': 'inactive'});
i = i + 1 ;
});
var current=0;
var slideshow = function(){
setInterval( function(){
current = ( current + 1 ) % seq.length;
if( current == 0 ){
s = shuffle( seq );
}
$(photos).each(function(){
$('#fancy_background img').attr('class','inactive');
$('#fancy_background img:nth-child('+s[current]+')').attr('class','active');
});
$('#fancy_background img.active').fadeIn('slow');
$('#fancy_background img.inactive').fadeOut('slow');
}, speed);
}
// Set first active image
var rand = Math.floor( Math.random() * photos.length ) + 1;
$('#fancy_background img:nth-child('+rand+')').fadeIn('slow');
// Start slideshow
slideshow();
});