{"id":1717,"date":"2010-12-15T13:19:44","date_gmt":"2010-12-15T12:19:44","guid":{"rendered":"http:\/\/www.simonbattersby.com\/blog\/"},"modified":"2014-03-16T10:38:19","modified_gmt":"2014-03-16T10:38:19","slug":"jquery-endless-slider","status":"publish","type":"page","link":"https:\/\/www.simonbattersby.com\/blog\/jquery-endless-slider\/","title":{"rendered":"jQuery endless looped slider"},"content":{"rendered":"<p>Here&#8217;s another variation on a jQuery slider, this time with the images in an endless loop. Tested in IE6\/7\/8, Firefox 3, Chrome, Opera 9\/10, Safari 4, all on Windows XP.<\/p>\r\n\r\n<h3>The demo<\/h3>\r\n\r\n<div id=\"endless_slider\" class=\"shadow roundbox\">\r\n<div id=\"slider_box\">\r\n<div id=\"endless_slider_arrows\">\r\n<img loading=\"lazy\" decoding=\"async\" id=\"endless_slider_left\" src=\"\/images\/misc\/left_arrow.gif\" alt=\"Scroll left\" title=\"Scroll left\" width=\"56\" height=\"56\"\/>\r\n<img loading=\"lazy\" decoding=\"async\" id=\"endless_slider_right\" src=\"\/images\/misc\/right_arrow.gif\" alt=\"Scroll right\" title=\"Scroll right\" width=\"56\" height=\"56\"\/>\r\n<\/div>\r\n<div id=\"slider_images\">\r\n<img loading=\"lazy\" decoding=\"async\" class=\"active\" src=\"\/images\/photography\/insects\/Gallery1.jpg\" alt=\"Hoverfly on a green leaf\" title=\"Hoverfly on a green leaf\" width=\"506\" height=\"337\" \/>\r\n<img loading=\"lazy\" decoding=\"async\" src=\"\/images\/photography\/insects\/Gallery11.jpg\" alt=\"Fly on a pink flower\" title=\"Fly on a pink flower\" width=\"506\" height=\"337\"  \/>\r\n<img loading=\"lazy\" decoding=\"async\" src=\"\/images\/photography\/insects\/Gallery10.jpg\" alt=\"Insect on a leaf\" title=\"Platycheirus granditarsus (I think) on a leaf\" width=\"506\" height=\"337\"  \/>\r\n<img loading=\"lazy\" decoding=\"async\" src=\"\/images\/photography\/insects\/Gallery12.jpg\" alt=\"Fly\" title=\"Blue bottle fly on a green leaf\" width=\"506\" height=\"337\"  \/>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n<h3>The code<\/h3>\r\n<p>Here&#8217;s my example html:<\/p>\r\n<pre>&lt;div id=\"slider_box\"&gt;\r\n   &lt;div id=\"endless_slider_arrows\"&gt;\r\n      &lt;img id=\"endless_slider_left\" src=\"\/images\/misc\/left_arrow.gif\" alt=\"Scroll left\" title=\"Scroll left\" width=\"56\" height=\"56\"\/&gt;\r\n      &lt;img id=\"endless_slider_right\" src=\"\/images\/misc\/right_arrow.gif\" alt=\"Scroll right\" title=\"Scroll right\" width=\"56\" height=\"56\"\/&gt;\r\n   &lt;\/div&gt;\r\n   &lt;div id=\"slider_images\"&gt;\r\n      &lt;img class=\"active\" src=\"\/path\/to\/image1.jpg\"\/&gt;\r\n      &lt;img src=\"\/path\/to\/image2.jpg\"\/&gt;\r\n    &lt;\/div&gt;\r\n&lt;\/div&gt;\r\n<\/pre>\r\n\r\n<p>Here&#8217;s the necessary css &#8211; just to show the important bits &#8211; you&#8217;ll need to add some more to position and style  as required:<\/p>\r\n<pre>\r\n#slider_box{border:1px solid #303030;position:relative;height:337px;width:506px;overflow:hidden}\r\n#slider_images{position:absolute;left:0;top:0}\r\n#slider_box img{float:left}\r\n<\/pre>\r\n\r\n<p>And here&#8217;s the javascript:<\/p>\r\n\r\n<pre>$(document).ready(function(){\r\n\r\n   var $imgWidth = $('#slider_images img').first().outerWidth();<span class=\"code_comment\">\/\/read the image width\r\n<\/span>   var $imgCount = $('#slider_images img').length;<span class=\"code_comment\">\/\/count the images\r\n<\/span>   $('#slider_images').width($imgWidth*($imgCount+2));<span class=\"code_comment\">\/\/set the width of the container to the number of images - plus 2 to account for the cloned images\r\n<\/span>   $('#slider_images img').first().addClass('endless_slider_first');<span class=\"code_comment\">\/\/identify the first and last images\r\n<\/span>   $('#slider_images img').last().addClass('endless_slider_last');\r\n   $('.endless_slider_first').clone().appendTo('#slider_images');<span class=\"code_comment\">\/\/clone the first image and put it at the end\r\n<\/span>   $('.endless_slider_last').clone().prependTo('#slider_images');<span class=\"code_comment\">\/\/clone the last image and put it at the front\r\n<\/span>   $('#slider_images').css({'left':-1*$imgWidth+'px'});<span class=\"code_comment\">\/\/reset the slider so the first image is still visible\r\n<\/span>   \r\n   $('#endless_slider_right').click(function(){\r\n      $('#slider_images').stop(true,true); <span class=\"code_comment\">\/\/complete any animation still running - in case anyone's a bit click happy... \r\n<\/span>      var $newLeft = $('#slider_images').position().left-(1*$imgWidth);<span class=\"code_comment\">\/\/calculate the new position which is the current position minus the width of one image\r\n<\/span>      $('#slider_images').animate({'left':$newLeft+'px'},function(){<span class=\"code_comment\">\/\/slide to the new position...\r\n<\/span>         if (Math.abs($newLeft) == (($imgCount+1)*$imgWidth)) <span class=\"code_comment\">\/\/...and if the slider is displaying the last image, which is the clone of the first image...\r\n<\/span>            {\r\n            $('#slider_images').css({'left':-1*$imgWidth+'px'});<span class=\"code_comment\">\/\/...reset the slider back to the first image without animating \r\n<\/span>            }\r\n         });\r\n      return false;\r\n   });\r\n   \r\n   $('#endless_slider_left').click(function(){\r\n      $('#slider_images').stop(true,true); <span class=\"code_comment\">\/\/complete any animation still running  \r\n<\/span>      var $newLeft = $('#slider_images').position().left+(1*$imgWidth);<span class=\"code_comment\">\/\/calculate the new position which is the current position plus the width of one image\r\n<\/span>      $('#slider_images').animate({'left':$newLeft+'px'},function(){<span class=\"code_comment\">\/\/slide to the new position\r\n<\/span>         if (Math.abs($newLeft) == (0)) <span class=\"code_comment\">\/\/if the slider is displaying the first image, which is the clone of the last image\r\n<\/span>            {\r\n            $('#slider_images').css({'left':-($imgCount)*$imgWidth+'px'});<span class=\"code_comment\">\/\/reset the slider back to the last image without animating \r\n<\/span>            }\r\n\t});\r\n   return false;\r\n   });\r\n\r\n})<\/pre>\r\n\r\n\r\n\r\n<h3>The logic<\/h3>\r\n<p>The slider container, here <code>#slider_box<\/code> has overflow hidden. The images are contained within an absolutely positioned div, <code>#slider_images<\/code> which has its width set to the number of images, plus two, times the image width. I&#8217;m then cloning the first image, and placing it at the end of the images, and cloning the last image and placing it before the first image. <\/p> \r\n\r\n<p>I&#8217;m animating the left and right click events by changing the left position of <code>#slider_images<\/code> by the width of an image. Then, at the completion of each animation, I&#8217;m checking the left position to see if I&#8217;m at the end of the images, displaying a cloned image, and if so swapping back to the original image. So, if I&#8217;m displaying the last image, which is the cloned first image, I change the position again, without animating, back to displaying the orginal non-cloned first image. This swap is invisible to the user and hence we give the appearance of an infinite loop.<\/p>\r\n<h3>Can I use this on my site?<\/h3>\r\n<p>Probably. See my <a href=\"\/blog\/use-of-code-from-this-site\/\">policies on using code from this site<\/a>.<\/p>\r\n<script type=\"text\/javascript\" src=\"\/javascript\/infinite_slider.js\"><\/script>","protected":false},"excerpt":{"rendered":"<p>Here&#8217;s another variation on a jQuery slider, this time with the images in an endless loop. Tested in IE6\/7\/8, Firefox 3, Chrome, Opera 9\/10, Safari 4, all on Windows XP. The demo The code Here&#8217;s my example html: &lt;div id=&#8221;slider_box&#8221;&gt; &lt;div id=&#8221;endless_slider_arrows&#8221;&gt; &lt;img id=&#8221;endless_slider_left&#8221; src=&#8221;\/images\/misc\/left_arrow.gif&#8221; alt=&#8221;Scroll left&#8221; title=&#8221;Scroll left&#8221; width=&#8221;56&#8243; height=&#8221;56&#8243;\/&gt; &lt;img id=&#8221;endless_slider_right&#8221; src=&#8221;\/images\/misc\/right_arrow.gif&#8221; alt=&#8221;Scroll [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1717","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.simonbattersby.com\/blog\/wp-json\/wp\/v2\/pages\/1717","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.simonbattersby.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.simonbattersby.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.simonbattersby.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.simonbattersby.com\/blog\/wp-json\/wp\/v2\/comments?post=1717"}],"version-history":[{"count":4,"href":"https:\/\/www.simonbattersby.com\/blog\/wp-json\/wp\/v2\/pages\/1717\/revisions"}],"predecessor-version":[{"id":2949,"href":"https:\/\/www.simonbattersby.com\/blog\/wp-json\/wp\/v2\/pages\/1717\/revisions\/2949"}],"wp:attachment":[{"href":"https:\/\/www.simonbattersby.com\/blog\/wp-json\/wp\/v2\/media?parent=1717"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}