function MXMSlider (slider) { var $this = this, sumwidth = 0, slider = $(slider), sliderlist = slider.children("ul.sliderlist"), itemImgs = sliderlist.find("img"), items = sliderlist.find('li'), nextBtn = $('', {className:'next leftright',text:'next',click:clickNextPrev}).data('dir','next'), prevBtn = $('', {className:'prev leftright',text:'prev',click:clickNextPrev}).data('dir','prev'), sliderwidth = 0, itemwidths = [], currentitem = 0, margin = 25, countImgs = 0, highlighter = $('
', {className:'highlighter'}); // add buttons outside of slider div slider.append(nextBtn,prevBtn); // Image loading callback (we can't test the width of the images until they've loaded) itemImgs.one("load",function(){ if (++countImgs == itemImgs.length) buildNav(); }).each(function(){ if(this.complete || (jQuery.browser.msie && parseInt(jQuery.browser.version) == 6)) $(this).trigger("load"); }); function buildNav () { var slidernav = $('
', {className:'slidernav'}), slidernavlist = sliderlist.clone(), scale = 30; // need to do this once we're sure all the images have loaded. TODO: just have one loop on images itemImgs.each(function(){ var width = this.offsetWidth + margin; sliderwidth += width; itemwidths.push([width,sumwidth]); sumwidth -= width; }); sliderlist.width(sliderwidth) slider.after(slidernav); highlighter.appendTo(slidernav); $this.slidernavlistitems = slidernavlist.children('li'); $this.slidernavlistitems.each(function (i){ this.innerHTML = ''; this.style.width = parseInt(itemwidths[i][0]/scale) + 'px' }); //set up click events for slider list slidernavlist.appendTo(slidernav).delegate("li","click",function(e){ currentitem = $this.slidernavlistitems.index(e.target); animateList(itemwidths[currentitem][1],e.target.offsetLeft); return false; }); highlighter.width((slider.width() - (margin * 2)) / scale).height('21px').css({opacity:'0.3', left:$this.slidernavlistitems.first().position().left}); hideNextPrev(); } function animateList (sliderleft,highlighterleft) { sliderlist.animate({left: sliderleft},400,hideNextPrev); highlighter.animate({left: highlighterleft},400); } function clickNextPrev (e) { if (!sliderlist.is(':animated')) { // next or previous (forwards or backwards)? ($(e.target).data('dir') == 'prev') ? currentitem -= 1 : currentitem += 1; // animate in the right direction animateList(itemwidths[currentitem][1],$this.slidernavlistitems.eq(currentitem).position().left); } return false; } function hideNextPrev () { // If scrollist is right of left terminus hide prev button if (sliderlist.position().left >= 0) { prevBtn.addClass('sliderdisabled').unbind('click'); if (!nextBtn.data('events')) nextBtn.removeClass('sliderdisabled').bind('click',clickNextPrev); // Else if scrollist is left of right terminus hide next button } else if (sliderlist.position().left <= (slider.width() - sliderlist.width())) { nextBtn.addClass('sliderdisabled').unbind('click'); if (!prevBtn.data('events')) prevBtn.removeClass('sliderdisabled').bind('click',clickNextPrev); } else if (!nextBtn.data('events')) { // Else show next buttons nextBtn.removeClass('sliderdisabled').bind('click',clickNextPrev); } else if (!prevBtn.data('events')) { // Else show prev buttons prevBtn.removeClass('sliderdisabled').bind('click',clickNextPrev); } return false; } }; new MXMSlider("#slider1")