2

layout

Here's a somewhat complex puzzle, I'd love some feedback on how others would approach this.

This site is basically a free regional news blog. The image at the bottom demonstrates the layout (ignore the date overlap glitch). It's coded in PHP, jQuery and xajax.

My question has to do with dynamic content loading. As is, on page-load, I assign the arrows to the URL of the prev/next articles. No prob. The URLs are friendly, the page reloads to the next article, and I can cycle through them all day long.

But ... I'd like to turn the arrows into a slider (not an href) with the following behavior:

Clicking the right arrow will ...

  1. Begin loading the new content offscreen via xajax,
  2. Cause the old content to slide left (from onscreen to offscreen) flush with the new content also sliding left (from offscreen to onscreen).

Why? Sliders are awesome, and I think it would look pro. And this is basic slider stuff (like this jQuery scrollLeft slider) except with content being dynamically loaded on click of the arrow, which raises some questions:

  • What's the best approach for this?
  • Do I use PHP to pre-populate ALL empty hidden article DIVs?
  • Do I use jQuery to append/prepend/remove article DIVs with each arrow click?
  • What would the jQuery "scrollLeft" offset look like? The content DIV is static width, but would I be better off with jQuery scrollTo?

I hope my question is clear ... Any suggestions would be most appreciated!

designosis
  • 5,182
  • 1
  • 38
  • 57
  • p.s. I recognize that this breaks bookmarking, but I plan on implementing HTML5's History APIs (or perhaps history.js ... https://github.com/balupton/history.js) – designosis Aug 23 '11 at 06:00

2 Answers2

4

Here's the solution I came up with.

http://jsfiddle.net/tXUwZ/

If anyone has ideas on how to clean it up or make it tighter, please let me know!

Many thanks to @Jamie for the push in the right direction!

designosis
  • 5,182
  • 1
  • 38
  • 57
1

You have two options in my opinion:

  1. Populate each slider on page load so that a jQuery click function animates the content
  2. Populating the data on a per slide basis using an AJAX call

If it's only a few items/slides, then I'd populate on page load. If you're looking at lots of slides (which you might expect with a daily news blog) or if each slide will contain a lot of data (such as high-res images, etc.) I'd go with the second option.

The second option is easy to do. All you'd need is three divs (one for the onscreen slide and two for the flanking offscreen slides that will 'replace' the onscreen one when either arrow is clicked). I'd use something like this:

<div class="container">
    <div class="inner-container">
       <div class="back"></div>
        <div class="content off_screen_left" id="1"></div>
        <div class="content on_screen" id="2"></div>
        <div class="content off_screen_right" id="3"></div>
       <div class="next"></div>
    </div>
</div>

And the required CSS:

.container{width:200px;height:150px;overflow:hidden}
.inner-container{width:600px;height:150px;margin-left:-200px}
.content{float:left;width:200px;height:150px}

And as for jQuery:

$(".next").live('click', function(){
  var current_id=$(this).prev(".on_screen").attr("id"); // get current page ID
  $(".content").css("float","right"); // float all elements to the right
  $(".off_screen_right").animate({display:none;}); // make the furthest right disappear gradually
  $(".on_screen").attr("class","off_screen_right"); // make on_screen the new off_screen_right and add the correct ID attribute
  $(".off_screen_left").attr("class","content on_screen"); // make off_screen_left the new on_screen
  $(".container").prepend('<div class="content off_screen_left" id="'+current_id-1+'"></div>'); // add the new off_screen_left element and add the correct ID attribute
  $(".off_screen_left").load("load-content.php?page_id="+current_id-1);  // populate the new off_screen_left element
});
$(".back").live('click', function(){
  var current_id=$(this).next(".on_screen").attr("id"); // get current page ID
  $(".content").css("float","left"); // float all elements to the left
  $(".off_screen_left").animate({display:none;}); // make the furthest left disappear gradually
  $(".on_screen").attr("class","off_screen_left"); // make on_screen the new off_screen_left and add the correct ID attribute
  $(".off_screen_right").attr("class","content on_screen"); // make off_screen_right the new on_screen
  $(".container").append('<div class="content off_screen_right" id="'+current_id+1+'"></div>'); // add the new off_screen_left element and add the correct ID attribute
  $(".off_screen_right").load("load-content.php?page_id="+current_id+1);  // populate the new off_screen_left element
});

But that's just one option. You can use a slider out of the box but I prefer to custom code things so that I know exactly what I'm doing.

hohner
  • 11,498
  • 8
  • 49
  • 84
  • I REALLY like where you're going with this. For the animation, won't the current content fade, and then suddenly be replaced with the next content? Would it be possible to make this a smooth panning transition? – designosis Aug 23 '11 at 07:04
  • 1
    Nope. Because you've floated all the content divs to either the left or right (see the second line in each click function) they're all leaning on one another. If the element moves, the element to its right moves and vice versa. What we can do instead of animating it to "display:none" is animating it to "width:0" so that it appears to slide smoothly. You'd need to use: `$(".off_screen_right").animate({width:0px;}).remove();` so that it would first be reduced to 0px and then be removed from the markup – hohner Aug 23 '11 at 07:11
  • Love it. Building a demo, I'll post it in a moment :) – designosis Aug 23 '11 at 07:16
  • What would you do for CSS? Things don't seem to slide if "container" has a fixed width, even with overflow:hidden ... – designosis Aug 23 '11 at 08:12