A Full Page Width Scroller For jQueryUI - wideScroller

Image

I needed a full page width image scroller that supported “infinite scrolling” and could handle being positioned, where the 1st image is aligned to something on the page. Poking around I found most jQuery scrollers made use of scrollTo and would not work when the window was the container. So I coded my own as a jQueryUI widget, this widget can be used with any HTML content.

Requirements

To use wideScroller you need the following:

  1. jquery.ui.dpui.wideScroller.js - the wide scroller widget
  2. jquery-1.5
  3. jquery-ui-1.8.4 - requires widget factory, can include effect if you want fancy easing
  4. jquery.ba-throttle-debounce - used to throttle the window resize event

You must use jquery-1.4.2 because of a bug that was introduced in jQuery 1.4.3 and is not currently resolved. This bug will only affect you if the total width of your scrollable elements is greater than 10000px. Once this bug is resolved you should be able to update to the latest jQuery without changing any code.

Download Code

Grab the source & examples from github.

Vew Demo

This demo shows the basic functionality - take a look before reading further as it will help explain things. Note how the “active” image is aligned with the “locator” div and how things work correctly if you resize the page.

The HTML Template

<!-- foo.html -->
<span class="ws-currentItem"></span> of
<span class="ws-totalItems"></span>

<div>
    <a href="#" class="prev"> < </a>
    <a href="#" class="next"> > </a>
</div>

<div id="scroller">

    <div id="scroller-spinner"></div>

    <div id="scroller-container">

        <div class="dpui-ws-item dpui-ws-active">
            <img src="images/image1.png"  width="940" height="400" />
        </div>

        <div class="dpui-ws-item">
            <img src="images/image2.png"  width="940" height="400" />
        </div>

        <div class="dpui-ws-item">
            <img src="images/tom.jpg"  width="371" height="400" />
        </div>

        <div class="dpui-ws-item">
            <img src="images/image4.png"  width="250" height="400" />
        </div>

        <div class="dpui-ws-item">
            <img src="images/image5.png"  width="250" height="400" />
        </div>

        <div class="dpui-ws-item">
            <img src="images/image6.png"  width="940" height="400" />
        </div>

    </div>
</div>

Each scrollable item requires the class dpui-ws-item and the active item requires the class dpui-ws-active. Most of the other classes can be specified in the options (see below). The HTML and CSS from github is thoroughly commented.

The CSS

The opacity is just for the demo, you can use any styling you like. , For the locator, in this example its a fixed width centered div, this would likely be your top nav or something similar.

body {
    padding:0;
    margin:0;
}

#scroller {
    overflow:hidden;
    position:relative;
    width:100%;
    height:525px;
}

#scroller-container {
    margin:8px 0 35px 0;
    height:480px;
    position:absolute;
    top:0px;
    left:0px;
    width:100000px;
}

.dpui-ws-item {
    position:absolute;
    padding:0 8px 0 0;
    opacity:.5;
}

.dpui-ws-active {
    opacity:1 !important;
}

#locator {
    width:980px;
    margin:0 auto 0 auto;
}

#scroller-spinner {
    position:absolute;
    width:100%;
    height:100%;
    background:#f5f5f5 url(images/spinner.gif) center center no-repeat;
    top:0px;
    left:0px;
    z-index:5;
}

The JavaScript

$(function() {
    $("#scroller").wideScroller();
});

Options

wideScroller provides the following options:

    .blog-table td {
        border:1px solid silver;
        padding:3px;
    }
offsetLocatorID required: yes
default value: #locator
identifies the locator, where the content will be aligned
containerID required: yes
default value: #scroller-container
the container of the scrollable elements, must be different from the element the widget is invoked upon
loaderID required: yes
default value: #scroller-spinner
hides the scrollable items while we re-shuffle them, see examples
nextButtonClass required: yes
default value: .next
the class of the next button/link
prevButtonClass required: yes
default value: .prev
the class of the prev button/link
showItemNumbers required: no
default value: true
set to true if you want to display 1 of XX
currentItemDisplayClass required: no unless showItemNumbers is true
default value: .ws-currentItem
if showItemNumbers is true class of current item display
totalItemDisplayClass required: no unless showItemNumbers is true
default value: .ws-totalItems
if showItemNumbers is true class of total items display
goToItem required: no
default value: null
used if you want to set an image other than the first as the inital image (see specify-start.html example)
easing required: yes
default value: linear
the easing effect for the scroll, can use jqueryUI easing if you are including.
speed required: yes
default value: 300
the speed of the scrolling, because you might be animating a large number of large images, you may need to adjust this to cut down on "tearing"


Events

The following events have callbacks that you can hook into:

startScroll scrolling has started
stopScroll scrolling has stopped
nextButtonClick next button clicked
previousButtonClick previous button clicked
resize window resize, (likely to be invoked numerous times)

You can hook into a callback when the widget is instantiated or after instantiation using the standard jQuery UI Widget Interface:

//During Instantiation
$("#scroller").wideScroller({
    startScroll: function() {
        $(".foo").hide();
    },
    stopScroll: function() {
        $(".foo").show();
    }
});

//After Instantiation Using Jquery UI Widget
("#scroller").wideScroller("option", "startScroll", function(){
    $(".foo").hide();
});

Performance

If you are sliding a large number of images or if the images have very large dimensions you may notice some “tearing” in certain browsers. You can tweak both the easing and speed to find what fits best for your use-case. I have found that a faster speed (smaller in ms) makes the animation look smoother. If you are able to use > jquery.1.4.3 you can also play with jQuery.fx.interval.

How It Works

Some details on how the widget works, not required reading but might be useful if something is not working as expected. Note that in the illustrative images the grey area is the visible browser window.

Default State Before Widget Before the widget loads, the page looks something like this (depending on browser). The “first” image is flush with the browser window and the rest of the images extend to the right. This initial state is not very important as the widget will move everything around.

Image

Widget Is Loaded When the widget loads, it aligns the active image to the location of a user defined ID. It then re-orders the images… when it reaches one that is beyond the right edge of the window it appends those images before the active image in reverse order.

Image

Moving Forward Advancing through the images, all images are scrolled (using animate) the width of the next image… the next image aligns to the same location. Prior to animating we clone the first image image from the left to the right. The image is cloned so the scrolling appears smooth if the image is visible on the left and will be visible on the right during the animation (so image 4 would be visible going off the left edge and appearing to come in from the right edge). The cloned image is kept but the original is removed. Similar steps occur when moving backward.

Image

Final Thoughts

If you have any comments or questions, please feel free to contact me or just use the below comment form.


JQuery

1074 Words

2010-11-21 16:00 -0800