Download Demo

Single page layouts are taking off in a big way. It seems as if every product page nowadays is single paged, so I thought I’d have a little spin at it with this jQuery plugin. This allows you to create single paged layouts with a few optional custom UI elements such as fold up menus. Check out the demo and enjoy!

I’ve tested this on most major platforms and browsers and it seems to work fine on all of them. The idea is simple, it lets you make a quick single page layout and gives you the option of some UI effects, such as disappearing pieces of image to reveal menus. I’ve also added some options to disable all that if it’s not for you. How does it work? Well let’s have a look.

Single Paged Layouts

The initial idea was to make a plugin that allowed you to add cool little UI transitions on an image that had been sized to fill the screen. When I finished that bit though, I realised I kind of wanted to make this into a full single paged layout creating website, so I got to it.

Devices

The issues I ran into were sometimes totally crazy, and making it work on mobile as well as desktop was not a walk in the park. I found many mobile browsers behaved totally differently and weird behaviour like Android firing everything fine, except one timeout which Android added a 300ms delay onto.

Some other issues included how the DOM was loaded, and affected the sizing of the pages, not to mention mobiles and desktops interpreting hidden overflow differently. The majority of these issues were fixable.

How it Works

First off, we need to set up the HTML. FullPaged searches for divs with the id [keyword]-page. So for example, by default the home page has an ID of home-page. In the demo I’ve created 3 pages, the other two pages having the IDs demo-page and world-page.

If you navigate to, for example, index.php#demo then the demo-page will come up. Similarly navigating to index.php#world, the world page will come up. If the user clicked on a link to these pages then they will be scrolled to with a little animation.

Finally there is a div with the class hidden-content. This is where the menu goes. It’s called hidden content because it is initially hidden, and then it will enter the scene when the user clicks a button such as ‘learn more’, which is (by default) identified by the class show-menu. So our HTML looks like this:

<div id="container">

	<div id="home-page">
		<div class="slide-content">
			<div class="content">
				<p>A little information about the product or whatever. Click Learn More and select 'Demos' for more demos.</p>
			</div>
			<div class="show-menu">
				Learn More
			</div>
		</div>
	</div>
	
	<div id="demo-page">
		<div class="slide-content">
				
			<!-- Content goes here -->
				
		</div>
	</div>
	
	<div id="world-page">
		<div class="slide-content">
			<!-- Content goes here -->
		</div>
	</div>
	
	<div class="hidden-content">		
		<div class="content">
			<ul class='menu'>
				<li>
					<a href="#home">
						<span>⌂</span>
						<span>HOME</span>
					</a>
				</li>
				<li>
					<a href="#demo">
						<span></span>
						<span>DEMOS</span>
					</a>
				</li>
				<li>
					<a href="#world">
						<span>🌎</span>
						<span>WORLD</span>
					</a>
				</li>
				<li>
					<a href="">
						<span>✎</span>
						<span>PREV</span>
					</a>
				</li>
				<li>
					<a href="">
						<span>↩</span>
						<span>ARTICLE</span>
					</a>
				</li>
			</ul>
		</div>
	</div>
</div>

Next we need to include the Javascript and run the plugin. To do that we include jQuery, the plugin file, and then call the plugin file. It has a few options which you can change, which are as follows:

  • image – This is the URL to the image you wish to use for the background image on the first page (the home page). I’ve put it here so that it’s easier to manipulate. The default is background.jpg
  • direction – The menu element can be positioned on any edge of the screen. This setting can be set to top, bottom, left or right. The default is bottom.
  • homeFixed – This can be true or false, and it determines whether the background image on the first page is fixed (i.e. it doesn’t scroll when the user scrolls).
  • mobileDirection – Mobiles behave differently than desktops so this setting means you can change the position of the menu element if the user is on a mobile screen. This might be due to space constraints or just aesthetics. It can be set to top, bottom, left or right. The default is bottom.
  • size – This is the size of the menu. This can refer to the height if the menu is located on the bottom or top of the screen, or the width if it’s on the left or right. The default is 140, as in 140px.
  • mobileAdj – This is the reduction in size you wish to apply when the user is using a mobile device. The default is 40, as in 40px. This means the menu element will be 40px smaller in height or width if the user is on a smaller screened device.
  • blur – Should the main background image on the first page blur when the user clicks to show the menu? This is a pretty neat effect but it can cause some performance issues on devices, and only works in webkit browsers. Use with caution. The default is false, but it can be set to true too.
  • animation – The animation you wish to use. There are 4 keywords you can use here:
    • fold – The menu will fold out, like paper.
    • fade – The menu will fade into existence.
    • slide – The menu will slide out.
    • show – The menu will be shown by default. No animation or clicking necessary.
  • scrollTime – The time you want it to take for the page to scroll to the next page when the user clicks a link. The default is 1, as in 1 second.

So now all you gotta do is call the plugin. Your code might look a little like this:

 
<script src="jquery.js"></script>
<script src="fullPaged.js"></script>

<script>
$(document).ready(function() {
	
	$('#container').fullPaged({
		'direction' : 'bottom',
		'size' : 140
	});
	
});
</script>

Of course you can alter the options to the ones I’ve listed above as you wish.

A little on how it works

So how does this all work? Well the animation effects are done through some clipping and appending which would take too long to show you the exact semantics. Suffice to say it takes the option you’ve chosen and appends some elements to create the illusion of the animation.

The pages are resized based on the height and width of the screen, and this is run every time the user does anything (such as resizing the window or changing orientation).

var $height, $width;
		
// The height and width of the window. Add 1 for mobile compatibility (i.e. so users on iPhones can still access URL bar
// By double tapping on the top of the screen). 
$height = $(window).outerHeight() + 1;
$width = $(window).width();
		
// Resize everything so it fits
(resize = function() {
				
	// The height and width of the window
	$height = height = window.innerHeight ? window.innerHeight : $(window).height();
	$width = $(window).outerWidth();
				
	$t.$element.css({
		'width' : $width+'px',
		'height' : $height+'px'
	});
				
})();

$(window).resize(resize).scroll(resize).on('orientationchange', resize);

// Put in a timeout to allow the page to load and get the proper dimensions for the window. Ensures no problems
// are encountered
setTimeout(function() {
	// Run resize function
	resize();
	// Overflow hidden, so the user cannot scroll.
	$('body').css({'overflow' : 'hidden'});
			
}, 100);

We also have to run this function a few more times to ensure the DOM is loaded and that the script receives the correct screen size. Notice above we’ve set overflow to hidden. That’s so the user can’t scroll. On mobile devices this doesn’t work, so the best work around is to make touchmove not work like so:


// Prevents scrolling on touch devices.
$('body').on('touchmove', function(e) {
	e.preventDefault();
});

Now that we’ve disabled scrolling and full-sized our pages we need to track the window for hash changes. If the hash changes we want the user to be scrolled to the #[hash]-page. To do that we add an event listener (via jQuery) and just track down the position of the page we want to scroll to using scrollTop. We’re using jQuery animations here which is the easiest method for scrolling:

$(window).on('hashchange', function(e) {
				
	// Getting the name of the page
	var pagename = window.location.hash.substr(1),
		divname = '#'+pagename+'-page';
				
	if($(divname).length !== 0) {
					
		$t.pageName = divname;
					
		$t.$element.find('.hidden-content').css({'z-index' : '99999999'});
					
		if($t.isScroll === false) {
				
			// Scrolling is now true
			$t.isScroll = true;
						
			// Animate the scroll position. 
			$('html, body').animate({
						
				scrollTop : $(divname).offset().top 
						
			}, ($t.options.scrollTime*1000));
					
			// Separate timeout set as a callback in order to ensure the smoothness
			// of the scroll. Resets variables.
			setTimeout(function() {
													
				$t.isScroll = false;
				
				$t.$element.find('.hidden-content').css({'z-index' : '999'});
						
			}, ($t.options.scrollTime*1000));
				
			return false;
						
		} else {
					
			e.preventDefault();
					
		}
					
	}

});

That’s the basic principle of it, but obviously in the plugin what with animations and stuff like that it can get a little bit more complicated.

The plugin is available to download via the download link at the top, or you can check out the demo. I hope you’ve enjoyed or find use in the plugin! Have a good day.