Difference between revisions of "Image slider"

From Organic Design wiki
m
(update code and move into subversion)
Line 1: Line 1:
Here's a simple image slider written 100% in [[JavaScript]] and [[jQuery]]. In converts any ''div'' elements of class "image-slider" containing ''img'' elements in a slider like the one below. The code is shown below the example.
+
Here's a simple image slider written 100% in [[JavaScript]] and [[jQuery]]. In converts any ''div'' elements of class "image-slider" containing ''img'' elements in a slider like the one below. The code is in our Subversion repository [http://svn.organicdesign.co.nz/filedetails.php?repname=extensions&path=%2FImageSlider.js here].
  
 
<div class="image-slider">
 
<div class="image-slider">
Line 14: Line 14:
 
<script type="text/javascript">
 
<script type="text/javascript">
 
// <![CDATA[
 
// <![CDATA[
window.sliderdata = [];
 
window.sliderdelay = 5;
 
 
$(document).ready( function() {
 
$(document).ready( function() {
  
$('div.image-slider').each( function() {
+
var delay = 5;
var div = $(this);
 
 
 
// Create entry in common data for this slider
 
window.currentslider = window.sliderdata.length;
 
div.attr('id', window.currentslider);
 
var slider = { image: 0, dir: 0, images:[], div: div };
 
window.sliderdata.push(slider);
 
 
 
// Store the image urls found in this slider in this sliders data and preload them
 
$('img', div).css('display','none').each( function() {
 
var src = $(this).attr('src');
 
var image = $('<img />').attr('src', src);
 
window.sliderdata[currentslider].images.push( src );
 
window.sliderdata[currentslider].w = $(this).attr('width');
 
window.sliderdata[currentslider].h = $(this).attr('height');
 
});
 
 
 
// Restructure the content of this sliders div into a table with prev/next buttons
 
var prev = '<a class="is-prev" href="javascript:window.image_slider(' + window.currentslider + ',-1)">&lt; prev</a>';
 
var next = '<a class="is-next" href="javascript:window.image_slider(' + window.currentslider + ',1)">next &gt;</a>';
 
div.html( '<table><tr><th><table><tr><td>' + prev + next + '</td></tr></table></th></tr></table>' );
 
 
 
// Set the cell size to the image size and other css styles
 
$('table',div).css({ background: 'transparent', width: slider.w, height: slider.h, 'border-collapse': 'collapse' });
 
$('td,th',div).css({ padding: 0, 'vertical-align': 'middle' });
 
$('.is-prev',div).css({ float: 'left' });
 
$('.is-next',div).css({ float: 'right' });
 
 
 
// Initialise the table's images to first image with zero offset
 
window.image_slider( window.currentslider, 0 );
 
 
 
});
 
});
 
 
 
window.image_slider = function( slider, dir ) {
 
 
 
// Set the new image and animate to it (bail if already animating)
 
var data = window.sliderdata[slider];
 
if( data.dir ) return;
 
data.image += dir;
 
data.dir = dir;
 
 
 
// Show next image on regular interval
 
if( 'timer' in data ) clearTimeout(data.timer);
 
data.timer = setTimeout('window.image_slider(' + slider + ',1)', window.sliderdelay * 1000);
 
 
 
// Play an animation from the current image to the next
 
data.div.animate({ t: 1 }, {
 
duration: 1000,
 
step: function(now, fx) {
 
var div = $(fx.elem);
 
var data = window.sliderdata[div.attr('id')];
 
 
 
// Get the URLs for the current and next image
 
var l = data.images.length;
 
var image = data.image;
 
image += l * 1000000;
 
var next = ( image - dir ) % l;
 
image %= l;
 
var offset = -data.dir * fx.pos * data.w;
 
 
 
// Set the URL and position for the current image
 
$('th', div).css('background', 'transparent url("'
 
+ data.images[image]
 
+ '") no-repeat '
 
+ (offset + data.w * dir)
 
+ 'px center'
 
);
 
 
 
// Set the URL and position for the next image
 
$('td', div).css('background', 'transparent url("'
 
+ data.images[next]+'") no-repeat '
 
+ offset
 
+ 'px center'
 
);
 
},
 
complete: function(now, fx) {
 
var data = window.sliderdata[$(this).attr('id')];
 
data.dir = 0; // mark current slider as no longer animating
 
}
 
});
 
};
 
// ]]>
 
</script>
 
</html>
 
 
 
 
 
== The code ==
 
<js>
 
window.sliderdata = [];
 
window.sliderdelay = 5;
 
$(document).ready( function() {
 
  
 
$('div.image-slider').each( function() {
 
$('div.image-slider').each( function() {
 
var div = $(this);
 
var div = $(this);
  
// Create entry in common data for this slider
+
// Create default data for this slider and store it in the element
window.currentslider = window.sliderdata.length;
+
div.data('image', 0);
div.attr('id', window.currentslider);
+
div.data('dir', 0);
var slider = { image: 0, dir: 0, images:[], div: div };
+
div.data('images', []);
window.sliderdata.push(slider);
 
  
// Store the image urls found in this slider in this sliders data and preload them
+
// Store the image urls found in this slider div in its data and preload them
$('img', div).css('display','none').each( function() {
+
$('img', div).css('display','none').each(function() {
 
var src = $(this).attr('src');
 
var src = $(this).attr('src');
 
var image = $('<img />').attr('src', src);
 
var image = $('<img />').attr('src', src);
window.sliderdata[currentslider].images.push( src );
+
div.data('images').push(src);
window.sliderdata[currentslider].w = $(this).attr('width');
+
div.data('w', $(this).attr('width'));
window.sliderdata[currentslider].h = $(this).attr('height');
+
div.data('h', $(this).attr('height'));
 
});
 
});
  
 
// Restructure the content of this sliders div into a table with prev/next buttons
 
// Restructure the content of this sliders div into a table with prev/next buttons
var prev = '<a class="is-prev" href="javascript:window.image_slider(' + window.currentslider + ',-1)">&lt; prev</a>';
+
var prev = '<a class="is-prev" href="#">&lt; prev</a>';
var next = '<a class="is-next" href="javascript:window.image_slider(' + window.currentslider + ',1)">next &gt;</a>';
+
var next = '<a class="is-next" href="#">next &gt;</a>';
 
div.html( '<table><tr><th><table><tr><td>' + prev + next + '</td></tr></table></th></tr></table>' );
 
div.html( '<table><tr><th><table><tr><td>' + prev + next + '</td></tr></table></th></tr></table>' );
 +
$('.is-prev', div).click(function(e,d) { slide($('div').has(this), -1 ); });
 +
$('.is-next', div).click(function(e) { slide($('div').has(this), 1 ); });
  
 
// Set the cell size to the image size and other css styles
 
// Set the cell size to the image size and other css styles
$('table',div).css({ background: 'transparent', width: slider.w, height: slider.h, 'border-collapse': 'collapse' });
+
$('table',div).css({ background: 'transparent', width: div.data('w'), height: div.data('h'), 'border-collapse': 'collapse' });
 
$('td,th',div).css({ padding: 0, 'vertical-align': 'middle' });
 
$('td,th',div).css({ padding: 0, 'vertical-align': 'middle' });
 
$('.is-prev',div).css({ float: 'left' });
 
$('.is-prev',div).css({ float: 'left' });
Line 142: Line 49:
  
 
// Initialise the table's images to first image with zero offset
 
// Initialise the table's images to first image with zero offset
image_slider( window.currentslider, 0 );
+
slide(div, 0);
 
});
 
});
  
function image_slider( slider, dir ) {
+
function slide(div, dir) {
  
 
// Set the new image and animate to it (bail if already animating)
 
// Set the new image and animate to it (bail if already animating)
var data = window.sliderdata[slider];
+
if(div.data('dir')) return;
if( data.dir ) return;
+
div.data('image', div.data('image') + dir);
data.image += dir;
+
div.data('dir', dir);
data.dir = dir;
 
  
 
// Show next image on regular interval
 
// Show next image on regular interval
if( 'timer' in data ) clearTimeout(data.timer);
+
if(div.data('timer')) clearTimeout(div.data('timer'));
data.timer = setTimeout('window.image_slider(' + slider + ',1)', window.sliderdelay * 1000);
+
div.data('timer', setTimeout(function() { slide(div,1); }, delay * 1000));
  
 
// Play an animation from the current image to the next
 
// Play an animation from the current image to the next
data.div.animate({ t: 1 }, {
+
div.animate({ t: 1 }, {
 
duration: 1000,
 
duration: 1000,
 
step: function(now, fx) {
 
step: function(now, fx) {
 
var div = $(fx.elem);
 
var div = $(fx.elem);
var data = window.sliderdata[div.attr('id')];
 
  
 
// Get the URLs for the current and next image
 
// Get the URLs for the current and next image
var l = data.images.length;
+
var l = div.data('images').length;
var image = data.image;
+
var image = div.data('image');
 
image += l * 1000000;
 
image += l * 1000000;
 
var next = ( image - dir ) % l;
 
var next = ( image - dir ) % l;
 
image %= l;
 
image %= l;
var offset = -data.dir * fx.pos * data.w;
+
var offset = -(div.data('dir') * fx.pos * div.data('w'));
  
 
// Set the URL and position for the current image
 
// Set the URL and position for the current image
 
$('th', div).css('background', 'transparent url("'
 
$('th', div).css('background', 'transparent url("'
+ data.images[image]
+
+ div.data('images')[image]
 
+ '") no-repeat '
 
+ '") no-repeat '
+ (offset + data.w * dir)
+
+ (offset + div.data('w') * dir)
 
+ 'px center'
 
+ 'px center'
 
);
 
);
Line 182: Line 87:
 
// Set the URL and position for the next image
 
// Set the URL and position for the next image
 
$('td', div).css('background', 'transparent url("'
 
$('td', div).css('background', 'transparent url("'
+ data.images[next]+'") no-repeat '
+
+ div.data('images')[next] + '") no-repeat '
 
+ offset
 
+ offset
 
+ 'px center'
 
+ 'px center'
Line 188: Line 93:
 
},
 
},
 
complete: function(now, fx) {
 
complete: function(now, fx) {
var data = window.sliderdata[$(this).attr('id')];
+
$(this).data('dir', 0); // mark current slider as no longer animating
data.dir = 0; // mark current slider as no longer animating
 
 
}
 
}
 
});
 
});
 
};
 
};
 
});
 
});
</js>
+
// ]]>
 +
</script>
 +
</html>

Revision as of 22:11, 27 March 2015

Here's a simple image slider written 100% in JavaScript and jQuery. In converts any div elements of class "image-slider" containing img elements in a slider like the one below. The code is in our Subversion repository here.

Butterfly3.jpg YellowButterfly.jpg MonarchOnPinkTree3.jpg Butterfly1.jpg

Butterfly3.jpg YellowButterfly.jpg MonarchOnPinkTree3.jpg Butterfly1.jpg