I just launched a new course on ES6! Use the code WESBOS for $10 off.

Strengthen your core JavaScript skills and master all that ES6 has to offer. Start Now →

Link within a jQuery Cycle slideshow with the hashchange event

Two of my favorite jQuery plugins are Mike Alsup’s Cycle and Ben Alman’s Hashchange. Cycle allows you to create really flexible sliders /slideshows and Hashchange allows you to create an event that triggers on hash change. When you’re using jQuery cycle for a large slideshow, its a good idea to let users link within that slideshow to a specific slide so that they can share and bookmark them.

A great example of this is for a photographer that may have 50 pictures in their portfolio, they often do not let you share the link to that specific picture but rather just the page with the slideshow embedded in it. Additionally, the user can now use the browsers back/forward buttons to navigate through your slideshow

Not to fear! We can set a hash on the url every time we change the slide and then check for a hash when the page loads, sending them to that specific slide.

The code isn’t too complex, so if you’re comfortable with cycle, head on over to view the demo or download it at the github repo.

First we start off with some basic markup

	<a href="#" id="prev">Prev</a>
	<a href="#" id="next">Next</a>

	<div class="slideshow">
		<img src="http://farm5.static.flickr.com/4029/4646753786_4a219fbbe3_z.jpg" alt="" />
		<img src="http://farm4.static.flickr.com/3472/3817281628_d5933948db_z.jpg" alt="" />
		<img src="http://farm1.static.flickr.com/199/476514422_0c1424fb06_z.jpg?zz=1" alt="" />
		<img src="http://farm2.static.flickr.com/1311/909213290_161035cf47.jpg" alt="" />
		<img src="http://farm4.static.flickr.com/3088/2688916488_1a125cd0e7_z.jpg" alt="" />
		<img src="http://farm1.static.flickr.com/215/520495246_22da7d843b.jpg" alt="" />
		<img src="http://farm4.static.flickr.com/3537/3492378275_fceca7bf0e_z.jpg?zz=1" alt="" />
	</div>

Then be sure to include jQuery, jQuery Cycle and Hashchange.

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript" src="plugins.js"></script>

Finally, we write a little JavaScript

This can be broken down into three parts:

1. Setup your document
We write a small function that will determin the current slide, so if a user visits http://wesbos.com/demos/jquery-cycle-link-within/index.html#photo-3 we know they want to see photo 3.

	// get current slide's number
	function currentSlide() {
		var hash = window.location.hash || '#photo-1';
		return parseInt(hash.replace(/[A-Za-z#\-\/!]/g, '') - 1);
	}
	// global vars
	var	cycleSelector = $('.slideshow'),
			startSlide = currentSlide(),
			hasSlid = 0;

2. Build our jQuery Cycle slideshow
Here we are doing two important things. First we set the browsers hash to the current slide that was either clicked on the thumbnails or using the next/prev buttons. Next we set the variable hasSlid to 1. This is our way of telling the hashchange event not to fire the slide change since we have already done it here. More on this below.

// append some markup for the controls
	cycleSelector.before('

')
	// start jQuery Cycle
	.cycle({
		 startingSlide: startSlide,
		 // when using the next/prev links
   	 onPrevNextEvent: function(isNext, idx, slide) {
   	 	hasSlid = 1;
   	 	window.location.hash = "photo-"+ (parseInt(idx) + 1) + "";
   	 	return false;
   	 },
   	 // when using the pager thumbnails
   	 onPagerEvent: function(idx, slide) {
   	 	hasSlid = 1;
   	 	window.location.hash = "photo-"+ (parseInt(idx) + 1) + ""; 

   	 	return false;
   	 },
   	 timeout: 0,
   	 pager:  '#nav ul',
   	 next: '#next',
   	 prev: '#prev',
   	 speed: 500,
   	 // build the thumbnails
   	 pagerAnchorBuilder: function(idx, slide) {
       return '
	
  • '; } });

    3. Bind to hashchange
    Finally, we need to listen for the hashchange event. This means that the code within this event will execute whenever the hash in the url is changed. So, for example, if a user changes the url from #photo-2 to #photo-4, this event will be fired and change the current slide to slide 4.

    Again, we only want to change the slide if our variable hasSlid is set to 0, if its set to 1 we know that either the prev/next controls or the thumbnails have taken care of this. If a user visits the url from a link or is using their browsers back/next buttons, then we use this to change the slide.

    	// bind to the hashchange event
    	$(window).bind('hashchange', function () {
    			var slideNo = currentSlide();
    			// we only want to fire the slide change if the next button or the pager hasn't done it for us
    			if (hasSlid === 0) { cycleSelector.cycle(slideNo); }
    			// return it back to zero
    			hasSlid = 0;
    	}); 
    
    	// when the page loads, we need to trigger a hashchange
    	$(window).trigger( "hashchange" );

    And thats it. You’re now able to link within a jQuery Cycle slideshow, bookmark and share certain slides, and use your browsers back/forward button. Let me know if you have any questions or improvements. Please fork the github repo and send me a pull request.
    Want more like this? Be sure to Follow me on twitter for the latest 🙂

    This entry was posted in JavaScript, jQuery and tagged , , , , . Bookmark the permalink.

    18 Responses to Link within a jQuery Cycle slideshow with the hashchange event

    1. ericB says:

      Hi, thanks for the tutorial

      I want to wrap an anchor tag around the image. When I do that the thumbnails do not show up and I get a broken image url icon instead. How can I add an anchor tag and get it to work?

      thanks

    2. Katy says:

      Hey,
      Great bit of code, just wondering if you can help me with 2 things:

      1. How to scroll right instead of fade
      2. How to use text terms as the pagination instead of thumbnails – I changed the code from
      pagerAnchorBuilder: function(idx, slide) {
      return ‘‘;
      }
      to

      pagerAnchorBuilder: function(idx, slide) {
      return ‘#photo-‘+ (idx+1) +”;
      }

      So it’s now printing #photo-1, #photo-2 etc. Is there anyway to get these to be custom terms? e.g. Faces, Buildings etc. There are 4 fixed words I would like to use and I would also like for these to appear in the URL e.g. site.com/#faces etc.

      Very grateful for any help….

      Thanks a lot

      • wesbos says:

        See this updated example: http://wesbos.com/demos/jquery-cycle-link-within/index-slug.html#dogs

        Basically just set the alt tag on your images. I’ve updated currentSlide() onPrevNextEvent() and onPagerEvent()

        For the sliding, see the cycle documentation, should just be adding fx : slideHorz to the main cycle() function.

        • Katy says:

          Getting there! I’ve got it scrolling, that was just being being careless and missing the quotes on: fx: ‘scrollHorz’. I’ve also now got a list of items, but unfortunately they all say ‘undefined’ as does the hashtag. I REALLY appreciate your help with this, and it’s so nearly there…. any bright ideas or if it’s not too cheeky, I could send you my code?

    3. aedwards says:

      Is anyone having issues with this in IE9?

    4. paul says:

      This is great, thanks for posting! All other solutions I’ve come across break the browser’s back button in one browser or another.

      I’m interested in using your second version (alt tag as slug), but I’m trying to use it without the thumbnails. I’ve tried deleting those portions of the code, but I’m new to JS and I think I’m removing too much / too little, because I keep breaking it in ie8.

      Any help would be appreciated. 🙂

      Thanks!

    5. paul says:

      I figured it out. Thanks again for the great tutorial. It’s exactly what I was looking for.

    6. kathy says:

      like the hashchange! the ability to share a specific slide is handy. you mention having a gallery of 50 images, what do you do w/ the thumbnail pager with that many items?

    7. Mark says:

      Hi there.

      Did anyone ever figure out how to get the names of the links in the pager nav instead of the thumbnails?

      Thanks,
      Mark

    8. Lorenzo says:

      It’s possible to implement this method if there is already an hashchange navigation on the website?
      For example if I have Url like this:

      http://mywebsite.com/#/slideshow

      How can I append hash relative to the slide?

      Thanks

    9. Sara says:

      how can I share slideShow in real time ??

    10. Stephen says:

      Looks great….however, I’m cycling divs in a slideshow. I can’t figure out how to get this to work in that context. Any help would be greatly appreciated! Thanks.

    11. Pingback: Jquery Hashchange / Deep Linking on Codrops Draggable Image Grid Framework

    12. Ronny says:

      hashchange I can implement this example?
      http://www.hostcreat.com/aplicacion-2/index.html
      Any help is welcome, Thanks.

    13. Richard says:

      Can I implement this when using slide navigation that sits outside of the slider?

      For example I have a series of that are used to hold the slide content. Each slide has an ID, so from my navigation I’ll include the hash for each div and when selected I want cycle to slide to whichever div has that hash?

    14. felix says:

      Just wanted to say a huge thanks for this, exactly what I needed to do. Lifesaver!

    Leave a Reply

    Your email address will not be published. Required fields are marked *