Today's Question:  What does your personal desk look like?        GIVE A SHOUT

HTML Page Slide Without a Framework

  Terrence Ryan        2012-04-17 06:51:40       3,612        0    

The HTML5 Microzone is presented by DZone and Microsoft to bring you the most interesting and relevant content on emerging web standards.  Experience all that the HTML5 Microzone has to offer on our homepage and check out the cutting edge web development tutorials on Script Junkie, Build My Pinned Site, and the HTML5 DevCenter.

I'm working on a little demo mobile application for an upcoming project, and I wanted to add sliding transitions between pages. Pretty simple, right? You just use jQuery, jQuery Mobile, zepto, or one of a bunch of other frameworks, and they handle this for you. I didn't want to.  Part of my goal with this particular project is to challenge myself to work without a framework so that I can see how this stuff works by hand.  Also I wanted to keep the HTML as slim and uncrufted as possible

Googling found very little to go on - except a micro solution for page transitions by FASW. I like it, but it's still using someone else's work, and I didn't like adding even the little bit of HTML cruft that it needed.

So I rolled my own.

The solution I came up with actually is pretty lightweight and is powered by a little AJAX, some CSS transitions, and CSS transition events. It's also important to note that this only works with WebKit. (My personal use case is for a mobile application with PhoneGap targeting Android and iOS, so I only need WebKit compatibility.)

First thing is to set the CSS of the body to have a transition on it, so when I move it around it's animated.

1.body{
2.position: relative;
3.-webkit-transition: left .2s ease;
4.}

Next thing I do is fire off a function when the page loads to replace all links with a function that will create the effect.  I use some techniques I learned from a great article named From jQuery to JavaScript: A Reference to handle these operations without jQuery.

01.document.addEventListener('DOMContentLoaded', function() {
02.replaceLinks();
03.});
04. 
05.function replaceLinks(){
06.var links = document.querySelectorAll('a');
07. 
08.for (i=0; i<links.length; i++){
09.var link = links[i];
10.link.addEventListener("click",replacePage, false);
11.}
12. 
13.}

Next step is to use AJAX to get the linked page.

1.event.preventDefault();
2.var href= this.href;
3. 
4.var ajax = new XMLHttpRequest();
5.ajax.open("GET",href,true);
6.ajax.send();

Now comes the transitions.  What I need to do to accomplish this page slide is:

  1. Slide the page off the screen to the left.
  2. Instantaneously move the page to the right side off screen
  3. Replace the contents of the body with the new content
  4. Slide the page on to the screen from the right.

I have to do it in that order.  If you replace the contents independent of the animation, you get weird effects like the page changing then the animation happening, which looks jarring. Or you get the opposite, the transition happening, then the contents changing.  Looks ugly.  Trying to time these proved problematic. The best thing to do would be to wait for the transition offscreen to happen, then change the content, then move it back on screen. I was able to do this by using a transition event.

Basically as far as I can tell there is only one transition event "transitionEnd" regardless of browser manufacturer.  I haven't been able to figure that out. Animation events appear similarly limited.  So here's how I did it:

I moved the body to the left side of the screen.

1.body.style.left = "-100%";

There is an event listener that handles making it transparent while I move it to the other side of the screen.

01.body.addEventListener( 'webkitTransitionEnd', moveToRight, false);
02. 
03.function moveToRight(event){
04.var body = document.querySelector('body');
05.body.removeEventListener( 'webkitTransitionEnd', moveToRight, false);
06.body.addEventListener( 'webkitTransitionEnd', returnToCenter, false);
07.body.style.opacity = 0;
08.body.style.left = "100%"
09.}

I then replace the content, make it visible again, adjust the browser history, and move it back to the center.

01.function returnToCenter(event){
02.var body = document.querySelector('body');
03.body.removeEventListener( 'webkitTransitionEnd', returnToCenter, false);
04.body.innerHTML = bodyContent;
05.history.pushState(null, null, href);
06.body.style.opacity = 1;
07.body.style.left = 0;
08.replaceLinks();
09.}

Then to be thorough, I make sure that I reverse the process if the user hits the back button.

01.window.addEventListener("popstate", handleBackButton);
02. 
03.function handleBackButton(e) {
04. 
05.var ajaxBack = new XMLHttpRequest();
06.ajaxBack.open("GET",location.pathname,true);
07.ajaxBack.send();
08. 
09.ajaxBack.onreadystatechange=function(){
10.var bodyBack = document.querySelector('body');
11.var bodyBackContent = grabBody(ajaxBack.responseText, "body");
12.bodyBack.addEventListener( 'webkitTransitionEnd', moveToLeft, false);
13.bodyBack.style.left = "100%";
14. 
15.function backToCenter(event){
16.var body = document.querySelector('body');
17.body.removeEventListener( 'webkitTransitionEnd', backToCenter, false);
18.body.innerHTML = bodyBackContent;
19.body.style.opacity = 1;
20.body.style.left = 0;
21.replaceLinks();
22.}
23. 
24.function moveToLeft(event){
25.var body = document.querySelector('body');
26.body.removeEventListener( 'webkitTransitionEnd', moveToLeft, false);
27.body.addEventListener( 'webkitTransitionEnd', backToCenter, false);
28.body.style.opacity = 0;
29.body.style.left = "-100%"
30.}
31.}
32.}

Is this the best way to do this?  I have no idea.  But it works for me and I couldn't find a comparable solution via Google.

There is a demo here.(WebKit browsers only)

Full source code is available via github.

Source : http://css.dzone.com/articles/html-page-slide-without

JAVASCRIPT  HTML  SLIDE SHOW  NO FRAMEWORK 

Share on Facebook  Share on Twitter  Share on Weibo  Share on Reddit 

  RELATED


  0 COMMENT


No comment for this article.