Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Javascript

Display Advertising Filmstrip

5.00/5 (3 votes)
25 Mar 2013CPOL6 min read 25.7K   258  
Basically a slideshow script, but more simple in design and easier to deploy.

Introduction

I'm basically in the marketing business, and Display Advertising is key to marketing success. What's even better is being able to squeeze in 5 to 10 display ads or marketing messages in the same amount of space and change them every 5 seconds or so, and replay it over and over, or just run it in a loop until the user says no more.

So if you are a programmer and you are trying to make a slideshow or something to show several items of content in the same place, then you are participating in some form of marketing.

Background 

I took over a website project for a customer and spent days fixing all the errors. I ran across this jQuery script for a slideshow in the project, but it had issues with timing and looping. I guess the previous vendor just copied and pasted the code  from a Wordpress plug-in into the project without knowing how it operated.

After spending a couple of hours trying to fix it, I thought maybe I would just look for something already written just to get by with, but really found nothing that was easy to setup and deploy. So I started from scratch and wrote my own.

The biggest issue is being easy to setup, controlling the timing of animations, and how to detect when the animation was really finished, to start again. I did some research on the jQuery website on the .animation() call, and ended up running various tests for about an hour to test the complete callback function. Other slideshow scripts used a loop counter to track each slide, but when JavaScript runs, it goes full bore until complete, making the counter completely useless because it finished before all the delay times completed.

So the question is, how do we determine when all the animations are complete? Do we use elapsed time? No, because the script would stop running before the elapsed time was complete. We can't use the counter in the loop because that would complete as well before the animations are finished running. So we'll use the length of the total amount of elements in the container then. When we reach the calculated length of the combined total of element widths, that's the end, so reverse or loop. Do something. This value will always be available because it's written to the DOM. One way to look at it is that JavaScript alters the DOM but the DOM holds the values until its changed again by JavaScript.

The code takes all the div elements in the master film container and reorganizes them in the DOM, creating a long filmstrip of cells, just like film. It then programs all the CSS needed, so no CSS file is required, and trashes the code on the webpage and inserts the new code. Then the loop function just runs the film left to right, 1 frame at a time, and rewinds the film and starts again.

This is the horizontal version, I suppose I could make it go vertical as well, but let's see how this works first.

Using the code  

Make a reference to jQuery, I used version 1.8.2 but I think earlier versions should work fine. Then make a new file, register it on your webpage in the header element, and copy the code below to the file. The HTML code block below is just a simple div container, with five more div elements inside it.

You can create new HTML content now, or just use my content and replace the image files with something in your project, to make sure it works first. Then you can go back and edit the child elements. The example content below is a container that is 980px by 250px, with images that are the same size.

This is an explanation of the vars in the run script. 

// Some Preset Values,

This is the width, height of the filmstrip. The other two are the ease time and view time.

JavaScript
function run_DisplayAdvertising_Horizontal(obj, cW, vW, cC, vT, eT) { 

Don't mess or modify the code above unless your really good at jQuery. They are abbreviated for a reason, but the values are as follows:

  • obj - Filmstrip container
  • cW - filmstrip total length
  • vW - cell or frame width
  • cC - total amount of frames
  • vT - view time 
  • eT - ease time 
  • fsRewind - is a calculation that auto sets the rewind time, to product a smooth result.
JavaScript
///////////////////////////////////////////////////////////////////////////////
//  jquery.displayadvertising.js
//
//  writen by Jim Kirker on December 18, 2012
//  Copyright by redCopper, Inc. 2013
//
//  jQuery and dynamic javascript to build a filmstrip out of current elements,
//  destroy the current elements and run the new filmstrip instead in the container;
//  then run the filmstrip in a loop, and rewind, then run again until a stop command is issued.
//
///////////////////////////////////////////////////////////////////////////////

$(document).ready(function () {
    
    load_DisplayAdvertising_Horizontal();
});
 
///////////////////////////////////////////////////////////////////////////////
//  load_DisplayAdvertising_Horizontal
//  Create a dynamic filmstrip in the DOM from current webform elements of text
//  We will run the filmstrip in another function below
///////////////////////////////////////////////////////////////////////////////
function load_DisplayAdvertising_Horizontal() {
 
    // Some fixed preset values
    var view_Width = 980;   // width of each filmstrip cell
    var view_Height = 250;  // height of each filmstrip cell
    var view_Time = 4000;   // amount of time to view the filmstrip cell
    var ease_Time = 1400;   // amount of time to pan the filmstrip cell left
    
    // Count how many Display Ads that we have in the slide container
    var child_Count = parseInt($('[id*="_slide_container"]').children().length);
 
    // We should build a dynamic message if no child objects exist

 
    //Prepare the slide_container as a fixed object with the correct css
    $('[id*="_slide_container"]').css({
        "position": "relative",
        "width": view_Width + "px",
        "height": view_Height + "px",
        "overflow": "hidden"        
    });
 
    // Alright, Setup all the the Child Panels 
    // within the Parent Container as a long film strip of panels
    var fsWidth = 0;
    var fsHeight = 0;
 
    // Loop through the Display Ads and reprogram the CSS
    $('[id*="_slide_container"]').find("._slide_child").css({
        //Program each child container to display and othe specs
        "display": "inline",
        "position": "relative",
        "float": "left",
        "top": "0px",
        "left": "0px"                        
    }).each(function (index) {
        // Measure the total width and max height of all child containers
        // to make a long horizontal filmstrip that just pans left to right
        fsWidth = fsWidth + parseInt($(this).css("width"));
        if (fsHeight > parseInt($(this).css("height"))) {
            fsHeight = parseInt($(this).css("height"));
        }
    })
 
    // Create a dynamic long FilmStrip container 
    // to put all the child panels in like movie film
    var div_filmStrip = document.createElement("div");
    div_filmStrip.style.textAlign = "left";
    div_filmStrip.style.width = fsWidth + "px";
    div_filmStrip.style.height = fsHeight + "px";
    div_filmStrip.style.position = "relative";
    div_filmStrip.style.left = "0px";
    div_filmStrip.style.top = "0px";
    
    // Copy the html from each child container to reinsert into the Dom
    var temp_InnerHTML = $('[id*="_slide_container"]').html();
    div_filmStrip.innerHTML = temp_InnerHTML;
 
    // Replace the old container content with this new filmstrip and copied content
    $('[id*="_slide_container"]').empty();
    $('[id*="_slide_container"]').append(div_filmStrip);
 
    // Run the Display Advertising in a seperate function for play and rewinding
    // The function should be just below this function
    run_DisplayAdvertising_Horizontal(
        div_filmStrip,
        fsWidth,
        view_Width,
        child_Count,
        view_Time,
        ease_Time
    ); 
}
 
///////////////////////////////////////////////////////////////////////////////
//  run_DisplayAdvertising_Horizontal
//  External run function that plays and rewinds over and over
///////////////////////////////////////////////////////////////////////////////
function run_DisplayAdvertising_Horizontal(obj, cW, vW, cC, vT, eT) {
    if (cC > 0)
    {
        var fsWidth = parseInt(cW - vW);
        var fsRewind = parseInt(vT / cC);
        for (var i = 0; i < cC-1; i++)
        {
            $(obj).delay(vT).animate({
                left: '-=' + vW
            }, eT, "linear", function () {
                //Animate Complete             
                var fsPosition = parseInt($(obj).css("left"));
                if (fsPosition == -fsWidth) {
                    $(obj).delay(vT).animate({
                        left: '0px'
                    }, fsRewind, "linear", function () {
                        // rewind complete, run the Display Ad again
                        run_DisplayAdvertising_Horizontal(obj, cW, vW, cC, vT, eT);
 
                    });
                }
            });            
        }       
    }
}
 
///////////////////////////////////////////////////////////////////////////////
//  displayAdvertising_Collapse()
//  External jQuery that will collapse and expand the filmstrip
//  wired directly to the image button onClientClick
///////////////////////////////////////////////////////////////////////////////
function displayAdvertising_Collapse() {
    var slideState = $('[id*="_slide_container"]').css("display");
    if (slideState == "block")
    {
        $('[id*="_slide_container"]').slideUp('fast');
        $('[id*="_lbl_SS_Collapse"]').text("show display advertising");
    }
    else 
    {
        $('[id*="_slide_container"]').slideDown('fast');
        $('[id*="_lbl_SS_Collapse"]').text("hide display advertising");
    }
}

This is the HTML part of the program. The master container has an ID of _slide_container which is needed so the script can detect the container. The child container has a class called _slide_child. This is needed so the child elements can be picked up and modified by the script. Other than that, you can place anything you want in the child container.

You can create a stylesheet and a class called _slide_child if your prefer to style over there instead of direct styling on the web form. Right now I just have an image file in the film cell "_slide_child". You can write more complex HTML and place in the film cell. The images should show up for testing to make sure it works, before you modify the contents with your messages.

ASP.NET
<div id="_slide_container" 
         style="width: 980px; height: 254px; text-align: center; margin: 0px auto; display: block;">
        
    <div id="slideChild_0" class="_slide_child" style="width: 980px; height: 250px; display: block;">
        <asp:Image ID="img_slideshow_child_0" runat="server" 
            ImageUrl="http://www.redcopper.net/EN-US/images/SlideShows/SS_StrategyPlanning_980x250.png" />       
    </div>

    <div id="slideChild_1" class="_slide_child" style="width: 980px; height: 250px; display: none;">
        <asp:Image ID="img_slideshow_child_1" runat="server" 
            ImageUrl="http://www.redcopper.net/EN-US/images/SlideShows/SS_WebDesign_980x250.png" />       
    </div>

    <div id="slideChild_2" class="_slide_child" style="width: 980px; height: 250px; display: none;">
        <asp:Image ID="img_slideshow_child_2" runat="server" 
            ImageUrl="http://www.redcopper.net/EN-US/images/SlideShows/SS_WebDevelopment_980x250.png" />       
    </div>
    
    <div id="slideChild_3" class="_slide_child" style="width: 980px; height: 250px; display: none;">
        <asp:Image ID="img_slideshow_child_3" runat="server" 
            ImageUrl="http://www.redcopper.net/EN-US/images/SlideShows/SS_HKB_Project_2_980x250.png" />       
    </div>
    
    <div id="slideChild_4" class="_slide_child" style="width: 980px; height: 250px; display: none;">
        <asp:Image ID="img_slideshow_child_4" runat="server" 
            ImageUrl="http://www.redcopper.net/EN-US/images/SlideShows/SS_InternetCommerceEngine-5_980x250.png" />       
    </div>

</div> 

Points of Interest 

There is no fixed relationship between the variable your declare in JavaScript for tracking versus the total amount of time that animations are set to ease or animate. The only real way to measure or check animations results are to go back to the DOM and check the updated value. So if you are depending on a loop counter to determine when the animation is complete, the loop counter will finish in about 1 second, while the animation can take up to 30 seconds. That's why you have to take a measurement to something in the DOM, and compare it to your calculated end result from your JavaScript.

I'm curious about adding the jQuery.UI to the script to do some real fancy easing or transitions, in between Display Ads. 

History 

This is the first time I've written one of these from scratch. I wrote something similar in ActionScript 3 for Flash. I like the rewind feature that moves the strip back to 0 really fast, instead of just looping clean from the start.

Download the Zip Example

I have added a zipped asp.net project for you to download, and quickly run to see how it works. You should be able to quickly see how simplistic it is, and how easy it is to implement in your project. 

Remember, you not limited to images, technically, you should be able to put any HTML you want in the containers, just remember to keep the height and width consistent. 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)