Ecommerce Developer
 
 

Code

Sliding and Gliding Page Content with JavaScript

 

Repositioning page content is, perhaps, one of the most common challenges a front-end web developer faces. JavaScript—in conjunction with HTML and CSS—offers a number of possible solutions.

In this article, I will describe one of the ways to slide and glide page content using JavaScript. This coding example can be applied to create effects similar to the ones seen on Roxy, HobbyTown USA; or Family Christian Stores, to name a few examples.

HTML Markup and CSS

For this tutorial, I have created a basic HTML page, which features a paragraph of text about a Ducati motorcycle, three images of that motorcycle, and a YouTube video about how Ducati designed the bike. I have also used a CSS file to hide all of the content except the paragraph about the motorcycle.

Shows initial markup with style

The script I am going to write is dependent on two sections of HTML markup: a control section and a section for the content that I will be sliding around the page.

<!doctype html>
<html lang="en">
<head>
	<title>Slide and Glide Content</title>
	<link type="text/css" rel="stylesheet" href="style2.css">
	<link rel="icon" type="image/png" href="favicon.png">
</head>
<body>
	<div id="wrapper">	
	<h1>Slide and Glide Content, Example One</h1>
	<div class="control-panel">
		<ul class="control-list">
		<li id="1">1</li>
		<li id="2">2</li>
		<li id="3">3</li>
		<li id="4">4</li>
		<li id="5">5</li>
		</ul>
	
	</div><!--end control panel-->
	<div class="gliding">
		<span class="gliding-content"><h2>The Ducati Multistrada 1200</h2><p>Adrenaline and excitement alternate with comfort and relaxation. The components mounted on the Multistrada 1200, including DTC and R-b-W as standard equipment and optional ABS, use state-of the-art technology, performance and design to deliver a stunning and accessible motorcycle.</p></span>
		<span class="gliding-content"><img src="1-ducati.png" alt="my next bike" /></span>
		<span class="gliding-content"><img src="2-ducati.png" alt="the ducati for two" /></span>
		<span class="gliding-content"><img src="3-ducati.png" alt="got to love this bike" /></span>
		<span class="gliding-content"><object width="640" height="385"><param name="movie" value="http://www.youtube.com/v/Agc9NInB158&hl=en_US&fs=1&"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/Agc9NInB158&hl=en_US&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"></embed></object></span>
			
	</div><!--end gliding-content-->
	</div><!--end wrapper-->
	<script src="js.js"></script>
</body>
</html>

First, take note of the control section, which is a div with the class name of "control-panel." It contains an unordered list with a class name of "control-list," and several list items that each has a unique id. To save time in this tutorial, I added the id values in the markup, but I could, of course, have added them via JavaScript.

The content section is also a div, this time with the class name "gliding." It contains a series of span tags each with the class name "gliding content."

For the most part, I used these various class names for style, but I will need a way to identify both the "control-list" and "gliding" in JavaScript.

Here is the style sheet.

#wrapper {margin: 150px auto; width: 820px; overflow: hidden;}

/*control panel*/

.control-panel ul{margin: 0; padding: 0; display: inline;}
.control-panel li {display: inline; margin: .25em; padding: 3px; color:#fff; background: #89B8E2; border:#3F70BC solid 1px; }

/*the gliding section*/

.gliding {width: 8030px; height: 400px; margin-top: 1em; position: relative; left: 0;  border-top: #D83B8A solid 10px; border-bottom: #D83B8A solid 10px;}
.gliding-content {width: 820px; height: 400px; float: left; padding: 0; margin: 0; }

Notice that the "#wapper" has a set width and is hiding any content outside of that width.

Meanwhile, ".gliding" has a set width much larger than the content it contains. This is important because I need the content—the paragraph, images, and video—to line up horizontally. If the total width of the content spans were greater than the set width of ".gliding," some of the content would be moved to a new line, frustrating my efforts to glide it into view.

The JavaScript

The JavaScript that I am going to use requires four basic components: (1) an event listener to monitor for a click in the control panel; (2) a function to process the click event; (3) a function to identify "gliding" in the document object model (DOM); and (4) a function to modify the content's relative position on the page.

Step No. 1: Add an Event Listener

While there are a few ways to add event listeners to the DOM, I like to do it as follows since I think it works best across all browsers. Effectively, this listener calls the function "contentGlide" when any element, anywhere on the page, is clicked. This has the added benefit of working if I need to run other JavaScript animations or functions on the page, since I can use the event handling function that I will create next to provide any number of responses. In this way, a one click event listener can then initiate one or dozens of different interactions.

document.onclick = contentGlide; //establishes event listener

Step No. 2: Process the Click Event

The function "contentGlide" has two jobs. First, it must capture what page element was clicked. Second, it needs to tell the browser what to do in response to that click.

function contentGlide(e)
{
	if(!e) var e = window.event;
	var target = e.target || e.srcElement;
	if(target.parentNode.className=='control-list')
	{	
		findGliding();
		var glideMultiple = parseInt(target.id);
		var tPos = (-820 * (glideMultiple - 1));
		motionGlide(tPos);
		
		
	}
	

}

Now that you have seen the complete function, let me dissect it a bit.

function contentGlide(e)
{
	if(!e) var e = window.event;
	var target = e.target || e.srcElement;

The "e" in function contentGlide(e) holds the information about the click event that the event listener captured and passed to the function.

The next two lines sort out the differences between how ECMA-compliant (JavaScript's other, and perhaps more accurate name, is ECMAscript) browsers and Microsoft's Internet Explorer (IE) so that the script will work in any modern browser, including Mozilla Firefox, Google Chrome, IE, Apple Safari, or Opera, to name some.

The next section of the function focuses on just the click events I want to capture and effectively tells the browser to ignore everything else.

if(target.parentNode.className=='control-list')
	{	
		findGliding();
		var glideMultiple = parseInt(target.id);
		var tPos = (-820 * (glideMultiple - 1));
		motionGlide(tPos);
		
		
	}

The if statement says that if the element clicked was inside of "control-list," which is the unordered list inside of the "control-panel" div, it should take four actions. If, however, the click was outside of the "control-list," there is nothing for the browser to do.

If the click is inside of the "control-list," the function will call another function named "findGliding." The "findGliding" function, which I will code next, will return a global variable with a value equal to the "gliding" div in my markup.

Next, the function captures an integer value for the id of list item that was clicked. In the case of my example, this will be a number from 1 to 5, since my list items have id values of 1, 2, 3, 4, and 5.

var glideMultiple = parseInt(target.id);

This integer is vital for my JavaScript, since the technique I am going to use involves repositioning the "gliding" div using the "left" style attribute. When a user clicks on the a control, say "3" which will have a integer value of "3," the function runs a short equation that takes the negative of the width of each "gliding-content" span (in this case that number is -820) and multiplies it by the clicked-list-item's integer value, which is 1.

var tPos = (-820 * (glideMultiple - 1));

Specifically, this equation will return one of the five following answers based on which control is clicked.

  • Click "1" and the equation returns 0, since -820 x 0 = 0. Remember that in this case "glideMultiple" is equal to 1, thus (glideMultiple – 1) = 0.
  • Click "2" and the equation returns -820, since -820 x 1 = -820.
  • Click "3" and the equation returns -1640.
  • Click "4" and the equation returns -2460.
  • Click "5" and the equation returns -3280.

Ultimately, the result of the equation represents the value that I want for the left style attribute of the "gliding" div. This is an important point, which can be hard to imagine or visualize. Think about the "wrapper" div as a picture frame and the "gliding" div as a series of five paintings sewn together and held behind the picture frame. If the "gliding" div has a left value of "0," the first picture is visible through the picture frame. If I changed the "gliding" div left value to "-820", our stitched-together paintings would move left the width of one painting so that the second one was visible through the picture frame.

Shows content gliding across the screen

Finally, the function passes the value the equation returned, which is the target position (tPos), to another function called "motionGlide."

Step No. 3: Locate the "gliding" Content

Before I move forward to the "motionGlide" function, I need to take a step back. You will recall the first thing that the "contentGlide" function told the browser to do was call a function named "findGliding," which doesn't exist just yet.

The "findGliding" function has one aim: locate the "gliding" div. If you are accustomed to using JavaScript libraries, you are probably thinking that I didn't need a whole function for this, rather $('gliding') might have done the trick. But I am not using a JavaScript library, and collecting elements that only have a class name is a common challenge for developers learning JavaScript, so I wanted to demonstrate one way to do this.

function findGliding()
{
	var glidingDiv = document.getElementsByTagName('div');
	for(var i =0; i < glidingDiv.length; i++)
	{
		if(glidingDiv[i].className=='gliding')
		{
			gliding = glidingDiv[i];
		}
		
	}
	
}

First, I asked the browser to return an array containing every div element on the page and store the result as "glidingDiv."

var glidingDiv = document.getElementsByTagName('div');

Next, I have the browser loop through the div elements one by one.

for(var i =0; i < glidingDiv.length; i++)
	{

If and when the browser encounters a div with a class name of "gliding", it will store that particular div in a variable named "gliding."

if(glidingDiv[i].className=='gliding')
		{
			gliding = glidingDiv[i];
		}

Step No. 4: Move Stuff

Now, I can write the "motionGlide" function, which must (1) determine if the "gliding" div has a left attribute; (2) assign it a left attribute if it doesn't have one; (3) compare the integer value of its current or starting left attribute to the target position and take one of three possible actions: subtract from the current left attribute, add to the current left attribute, or just stop and do nothing else.

function motionGlide(t)
{
	if(!gliding.style.left)
	{
		gliding.style.left = 0 + 'px';
	}
	var startPos = parseInt(gliding.style.left);
	if(startPos > t)
	{
		gliding.style.left = (startPos - 10) + 'px';
		glideTimer = setTimeout(function(){motionGlide(t)}, 1);
	}
	else if(startPos < t)
	{
		gliding.style.left = (startPos + 10) + 'px';
		glideTimer = setTimeout(function(){motionGlide(t)}, 1);
	}
	else{clearTimeout(glideTimer);
	}
	
}

Although I did specify a left value for the "gliding" div in my style sheet, that value is not found in the HTML markup. So if I just started by changing the left attribute, I would generate an error the first time a user clicked. With this in mind, I start this function by first checking to see if "gliding" has a left attribute (i.e. is this the first click event?) and if it does not, I set the left value to zero.

Notice that in JavaScript a leading "!" negates a statement. Thus this line of code could be read, "if the left attribute does not exist, do the following."

if(!gliding.style.left)
	{
		gliding.style.left = 0 + 'px';
	}

Next, I create a variable to store the "gliding" div left attribute starting or current value. For example, if a user clicked the "3" in the control list earlier and then came back and clicked the "5," the left value after the first click would be -1640. I need to know this position so that I know the difference between the start position (-1640) and the target position (-3280 if when "5" is clicked). At this step, I am also using parseInt() to remove the "px" from the left attribute and get back a simple integer.

var startPos = parseInt(gliding.style.left);

At this point, the browser has three choices.

If the target position value is greater than the starting left value, the function will subtract 10 pixels from the left value, moving the "gliding" div 10 pixels to the left across the page. It will also set a timer to compare the target position and the original starting position again in one millisecond, continuing to subtract 10 pixels from the left value as long as the target position is a greater number than the original starting left value.

if(startPos > t)
	{
		gliding.style.left = (startPos - 10) + 'px';
		glideTimer = setTimeout(function(){motionGlide(t)}, 1);
	}

If the target position value is less than the starting left value (meaning that it is further left in the content), the function will incrementally add 10 pixels to the left attribute.

else if(startPos < t)
	{
		gliding.style.left = (startPos + 10) + 'px';
		glideTimer = setTimeout(function(){motionGlide(t)}, 1);
	}

Finally, if the target position's value and the starting left value are the same, the function makes sure that no timers are still running and basically stops.

else{clearTimeout(glideTimer);}

Summing Up

This tutorial demonstrated one possible way to move content around the page with JavaScript. There are many others, and in fact, don't be surprised if you see other tutorials on Ecommerce Developer that cover how to manipulate an element's position. But the aim was to give you a taste of how this task may be accomplished.

I also want to mention a couple of other points. This example is fairly bare bones and you may want to add another function that changes the user's mouse pointer to a "hand" when the user hovers over the control panel. Furthermore, since different browsers use different JavaScript rendering engines, you may want to adjust the number of pixels added or subtracted, or extend the timer, to compensate for your target browser. Specifically, you may even want to write a function that slowed things down for some versions of IE since older versions of IE cannot process JavaScript as quickly as Firefox, Chrome, Safari, or Opera and may appear sluggish.

Here is a demo of the finished JavaScript.

Related Articles

0 Comments

Rss-sm