Showing posts with label browser. Show all posts
Showing posts with label browser. Show all posts

Tuesday, November 18, 2008

Flash on AMD64 Linux

Adobe answered the cries of Linux users by releasing a 64-bit Linux Flash 10 Plugin. Note that as of this posting the plugin is an Alpha plugin, but I've installed it and have it working on both Firefox-3 and Opera-9.62 for Ubuntu 8.10 Linux.

After closing Firfox and Opera, then using Synaptic to remove flashplugin-nonfree from my system and Cleaning up My Ubuntu Box, I followed the installation instructions given by Adobe.

Firefox wanted to update itself as soon as I removed flashplugin-nonfree, but I held off on doing that until I had the new plugin installed. After extracting libflashplayer.so to ~/.mozilla/plugins I allowed Firefox to update via Ubuntus automatic updates, then started Firefox up and the Flash Player worked like a charm.

Opera didn't want to work right at first however. For some reason Opera wasn't aware of my ~/.mozilla/plugins directory as being a plugins directory so I had to add that directory to my plugins path in Opera.

Adding ~/.mozilla/plugins to my plugins path was simple enough.
Tools > Preferences > Advanced > Content > Plugins Options > Change Path


After adding ~/.mozilla/plugins to the list of folders and restarting Opera the Flash Player was working properly.

Saturday, October 11, 2008

Disable Firefox Image Drag

Firefox 3 has a behavior where clicking an image and moving your mouse will start to drag a preview of that image around. The behavior even occurs with the background images for elements.

While this drag and drop behavior for images in Firefox can be really usefull for the visitor, this behavior can be a real problem if you're writing an application that depends on JS to drag around elements that contain images or have background images.

Placing the image or element inside a container and attaching event listeners to that container instead of the image or element with a background seems like an obvious answer, but it will only work for the first click. If the visitor drops the element and tries to drag it again Firefox will start up with the drag and drop behavior.

What does work though is having your mousedown event listener prevent the default action, which seems to be that drag and drop behavior.

Within the event handler you're assigning to your mousedown event, assuming you're argument list includes an event object, as is the case with most jQuery event handlers, your function declaration might look like this.

var callback = function(event){
if(event.preventDefault)
{
event.preventDefault();
}
// Other code...
}


Nice and easy.

Friday, September 5, 2008

Web File Formats 101

These are file extensions or formats you're likely to come across at one point or another if you're going to get into designing web sites. They're split into common groups, include a brief description of where you're likely to see or use them, and clicking the *.EXTENSION link in the titles will take you to a Wikipedia entry with a lot more details on that file format.

This list is a collection of about 45 file formats I've used enough times to remember when presented with a huge list of file formats after roughly five years of experience.




Browser File Formats

Browser file formats are files that instruct web browsers to do something directly. Many technologies may work with browser file formats, but browsers are generally the things that make use of them.

*.AS Adobe/Macromedia Action script file

AS files are generally used as library or optional include files in Flash or Flex applications.

*.CSS Cascading Style Sheet file

CSS files contain CSS rules which web browsers use to decide what web pages should look like.

*.HTM / *.HTML Hyper Text Markup Language

HTML files are web pages. HTML is what files such as PHP, ASP, CFML, and JSP produce when they're executed.

*.ICO Icon file

ICO files are commonly used as Favicons (that little icon in the address bar)

*.JS Javascript file

JS files are used to store Javascript. Javascript is a cornerstone in many of the applications on the web today. Javascript provides a way for web developers to utilize the browsers rendering engine and make changes to the content of a web page without needing to make a trip back to the web server to generate a new page with the updated content. Javascript is becoming more popular for producing animation in web pages since the jQuery, Prototype, and Moo-Tools Javascript libraries were developed.

*.SWF Adobe/Macromedia Shockwave Flash file

SWF files are generally used in Rich Internet Applications and require the Adobe/Macromedia Flash Player to view.

*.VBS Microsoft Visual Basic Script file

VBS files are similar in concept to JS files but they often have control over operation system functionality normally off limits to JS, however VBS files are only supported by Microsoft Internet Explorer versus JS which is available on almost every popular web browser. VBS is generally only found on private Microsoft Windows based Intranet sites, though even there it's being replaced by newer offerings from Microsoft.

Image File Formats

Image file formats are files used to store and transfer photographs, vector art, logos, favicons and things like that. They're also used to store information artists use to modify the images in image manipulation applications such as Photoshop and Fireworks.

*.BMP Bitmap Graphic file

BMP files are an early image format with little or no compression applied. BMP files are sometimes found on websites, but have generally been replaced by formats such as PNG, GIF, and JPG in recent years.

*.GIF Graphic Interchange Format file

GIF files are image files that sometimes include simple frame-based animation and alpha transparency. PNG has gained popularity over GIF in recent years do the the superior color quality of PNG, however transparency problems with Microsofts Internet Explorer 6 have slowed the transition from GIF to PNG.

*.JPG / *.JPEG Joint Photographic Group image file

JPG files are image files designed specifically for photos. The compression method used has been optimized for working with complicated images, making it especially well suited for transferring photos on the web.

*.PNG Portable Network Graphic file

PNG is an image file format that has gained popularity over GIF in recent years do the the superior color quality of PNG, however transparency problems with Microsofts Internet Explorer 6 have slowed the transition from GIF to PNG. PNG is also the native file format used by Adobe/Macromedia Fireworks, similar to how PSD is the native file format used by Adobe Photoshop. PNG has the ability to store information about layers when used in Fireworks in much the same way that PSD can store information about layers in Photoshop.

*.PSD Photoshop Document file

PSD is an image file format and is the native format used by Adobe Photoshop. PSD allows image authors to store information about layers in an image when edited in Photoshop in much the same way that PNG enables layer information when edited in Fireworks. Unlike PNG which generally has multiple export modes and can be exported for use on the web, PSD is primarily used for raw or drafts before exporting the finished pieces of the image to other image formats such as PNG, GIF, or JPG.

*.SVG Scalable Vector Graphics file

SVG files are vector image files. Unlike common raster image formats that store information about each pixel in the image, vector image formats only store information about how to draw the image, which generally consists of coordinates to place simple shapes and how to fill them with color.

Audio/Video File Formats

Audio/Video file formats are used to store and transfer audio and video.

*.AVI Audio Video Interleave file

AVI files are commonly used to distribute video.

*.FLV Flash Video file

FLV files are usually not observed directly, but rather played through an SWF file. FLV files are used for distributing streaming video.

*.MOV / *.QT Apple QuickTime Video Clip file

MOV or QT files are used to distribute video, similar to AVI files. Quicktime is generally known for a great level of quality in video.

*.MP3 MPEG Audio Stream, Layer III file

MP3 files are used to distribute audio. MP3 files use a compressed version of the audio information and are generally many times smaller in size compared to WAV files, despite including extra information about the audio such as the author, title, album name, and description.

*.MPEG / *.MPG MPEG 1 System Stream file

MPEG or MPG files are used to distribute video, similar to AVI, MOV, and QT files.

*.WAV Waveform Audio file

WAV files are an early audio format file which has all but been replaced by MP3 on the web due to superior compression and information embedding provided by the MP3 audio file format.

*.WMA Microsoft Windows Media Audio file

WMA is an audio file similar to MP3 and WAV developed by Microsoft. Like WAV, WMA has been replaced to a large extend on the web by MP3.

Compression File Formats

Compression file formats are used to apply compression to single, or groups of files in order to reduce the size needed to store and transfer the files, as well as making large groups of files easier to transfer at once.

*.BZ2 BZIP2 compressed archive file

BZ2 files are generally used by programmers to distribute compressed source code packages.

*.GZ GZIP compressed archive

GZ files are sometimes used in the same way BZ2 files are, for programmers to distribute source code packages. Some systems use GZIP compression on their old log files to save space which results in file names such as "date.log.gz". Some web servers use GZIP compression to compress data before sending it from a server to a browser.

*.RAR winRAR compressed archive

RAR files are often used by individuals to compress and transfer large files, or large groups of files. Similar to GZ, BZ2, and ZIP files.

*.ZIP Compressed archive file

ZIP files are similar to RAR, BZ2, and GZ files however ZIP files are generally a lot more common. ZIP files package and to a point compress other files to be transferred from system to system.

Misc File Formats

Misc file formats are generally not designed specifically for web sites, but have found numerous uses on them.

*.*.BAK Backup copy of file

Backup. The second asterisk is generally the original file extension.Rather than trying to open this file, you will usually rename it and remove the .BAK from the end, then open it with the appropriate application

*.DOC Microsoft Word document

DOC files are often used by companies to distribute bundled information suitable for printing. DOC files are a favorite of companies for sending contracts via e-mail. DOC files are similar in concept to PDF files.

*.INI Information/configuration file

INI files are commonly used to store persistent configuration data for web servers and web browsers. INI files are also used in the same way for applications that have nothing to do with web design. Using XML files to store configuration data instead of INI files has been gaining popularity in recent years.

*.KML Google Earth/Keyhole place mark file

KML files are used to share specific locations, or placeholders in the popular Google Earth application. KML files are becoming increasingly popular on business web sites who want to provide directions for customers.

*.PDF Acrobat Portable Document Format file

PDF files are often used by companies to distribute bundled information suitable for printing, similar to DOC files. Some print shops will ask for PDF files when you need to have fliers or brochures printed out. Some companies will make PDF copies of important information found on their web site available for people do download and read offline, or print out and read away from their desk.

*.RDF Resource Description Framework file

RDF files are often used to deliver RSS content. RDF RSS feeds are generally more specialized in comparison to the generic XML versions of RSS files.

*.TXT Plain text file

TXT files are plain text files. TXT files generally display the characters as-is with no consideration for special style codes.

*.XML Extensible Markup Language file

XML files are generally used to store structured information. Many web sites use AJAX to load XML in the background and update small portions of web pages without needing the server to generate the entire web page over again with slightly changed information. XML files are also gaining popularity as a settings or preference file format. The generic yet descriptive format used to section data off makes XML the perfect file format for storing raw information that will be displayed in many different ways.

Server File Formats

Server file formats are generally scripts that web servers execute in order to produce web pages dynamically. these types of files are also often used to perform maintenance on the server through automation.

*.ASP Microsoft Active Server Pages

ASP files are an earlier version of ASPX files. ASP files are similar in concept to CFML, PHP, ASPX, RB, and JSP files.

*.ASPX Microsoft ASP.NET source code file

ASPX files are a more recent version of ASP files. ASPX files are used on web servers to prepare HTML documents to send to a web browser. ASPX files are similar in concept to ASP, CFML, PHP, RB, and JSP files.

*.CFM / *.CFML Coldfusion Markup Language file

CFML files are used on web servers to prepare HTML documents to send to a web browser. CFML files are similar in concept to ASPX, PHP, ASP, RB, and JSP files.

*.CGI Common Gateway Interface file

CGI files are generally used to provide a bridge, or gateway, between a web server and applications installed on the server such as Python, Perl, sed, and many others.

*.JSP Java Server Pages

JSP files are used on web servers to prepare HTML documents to send to a web browser. JSP files are similar in concept to ASPX, PHP, ASP, RB, and CFML files.

*.LOG Log file

LOG files are generally exactly what the name implies, a log. Web servers use them to store details about each visit to a web site as well as to store information useful to administrators and developers in the event of a problem. Old, or archived LOG files are often compressed using GZIP compression, which results in "filename.log.gz" types of file names.

*.MDB Microsoft Access Database file

MDB files are a Microsoft database data storage format. The MySQL database engine has been gaining popularity over MDB in recent years. There are many MDB to MySQL converters and conversion methods available on-line.

I posted a how to for Importing MDB to MySQL on a Debian server not too long ago.

*.PHP Hypertext PreProcessor script file

PHP files are used on web servers to prepare HTML documents to send to a web browser. PHP files are similar in concept to ASPX, JSP, RB, ASP, and CFML files. PHP is one of the most popular pre-processors used on the web today.

*.PL Perl script file

PL files are Perl script files. Perl is one of the first scripting languages to be used on the web. Perl is often used in conjunction with CGI. In recent years PHP has stolen much of Perls thunder, leaving Perl used primarily by veterans.

*.RB Ruby script / Ruby on Rails class file

RB files are used on web servers to prepare HTML documents to send to a web browser. RB files are similar in concept to ASPX, JSP, PHP, and CFML files.

*.SHTML / *.SSI HTML including Server Side Includes

SHTML files are used on web servers to tell the web server that there's lines in the file that need to be replaced with the contents of other files before sending the contents of the file to the web browser. SHTML is generally a very simple version of what file types such as ASP, ASPX, CFML, JSP, PHP, and RB are designed for.

*.SQL Structured Query Language data file

SQL files generally contain the description of a database and the database table layouts. In some cases SQL files will contain information dumps from database tables, though this is generally reserved for small databases.

.htaccess Apache dynamic configuration file

.htaccess files are commonly used to make runtime adjustments to an Apache web server configuration without needing to restart the Apache server. Not all configuration options are able to be altered via .htaccess and depending on the servers configuration at start up there might not be any options that can be configured via .htaccess

Monday, August 11, 2008

Javascript Lorem Ipsum Generator

About 2 years ago I wanted a Lorem Ipsum Javascript to make adding Lorem Ipsum to webpages in progress a little less work & bandwidth consuming.
It's worked well for quite awhile now, but today seemed like a good day to revamp the script.

This new version of the script works the same way as the last version.
HTML comments are placed where Lorem Ipsum should go & the script replaces those comment nodes with text nodes at the DOM level.
Version 2 is also about 3 times faster, the comment scheme is easier to use, & there's some convience methods added.

Starting with the easier comment scheme.
Comments are placed like so depending on whether words, sentences, or paragraphs should replace the comment.
It starts with the number of units to use, followed by what type of units to use. The script is pretty forgiving about the usage of whitespace when defining these. The script also doesn't care if the unit name is pluralized or not.
<-- 2 words -->
<-- 4 sentences -->
<-- 1 paragraph -->


Ranges can also be used for the amount of units.
For instance, if somewhere between 2-5 words should be generated you could use the following comment.
The script is just as forgiving with whitespace between the range numbers as it is with the rest of the format.
<-- 2- 5 word -->


There's a main method included that will start at the <body> element & process all comment nodes in the document. This method can be called at the end of the document, or added as an event listener.
LoremIpsum.LoremIpsum();
window.addEventListener('load', LoremIpsum.LoremIpsum, false);
window.attachEvent('onload', LoremIpsum.LoremIpsum);


The processing can also be rooted at any other node by using the scanElm method.
var trunk = document.getElementById('example');
LoremIpsum.scanElm(trunk);


The script doesn't have to be used to replace comments in the document, or in a certain node.
The word, sentence, & paragraph generation methods can be called directly & will return however many units they're asked for.
The only restriction is that ranges can't be used when calling the methods directly.
If you want random numbers of units, you'll need to generate those numbers yourself.
var elm = document.getElementById('elm');
var word_count = Math.ceil(Math.random() * 10);
var ipsum = LoremIpsum.words(word_count);
elm.appendChild(document.createTextNode(ipsum));


Quite a few aliases are included for each method.
Camel notation, Underscore notation, Lowercase notation.
main & init are included for starting with the root element.
get_* schemes are included for the generation methods.
/* Convenience / aliases / etc */
LoremIpsum.main = LoremIpsum.init = LoremIpsum.LoremIpsum;
LoremIpsum.getWords = LoremIpsum.get_words = LoremIpsum.words;
LoremIpsum.getSentences = LoremIpsum.get_sentences = LoremIpsum.sentences;
LoremIpsum.getParagraphs = LoremIpsum.get_paragraphs = LoremIpsum.paragraphs;
LoremIpsum.scan_elm = LoremIpsum.scanelm = LoremIpsum.scanElm;
lorem_ipsum = loremipsum = loremIpsum = LoremIpsum;


Here's the source, it saves to about 4.5KB fully commented & uncompressed.
The methods include further documentation in the form of comments.

LoremIpsum = {
fullstop: '.', /* Character(s) to add to the end of sentences */
min_wps: 10, /* Minimum words per sentence */
max_wps: 25, /* Maximum words per sentence */
min_spp: 2, /* Minimum sentences per paragraph */
max_spp: 8, /* Maximum sentences per paragraph */

/* Word bank
Words are selected from this array randomly
to generate complete text nodes.

NOTE: This array __can__ be altered provided it remains a single-dimension array.
*/
src: new Array('a','adipiscing','amet','arcu','at','auctor','bibendum','commodo','congue','curabitur','cursus','diam','donec','duis','eget','elementum','enim','eros','et','eu','fusce','gravida','in','integer','ipsum','justo','lectus','leo','ligula','lorem','maecenas','magna','malesuada','massa','mattis','mauris','metus','molestie','morbi','nam','nec','nibh','non','nulla','odio','orci','ornare','pellentesque','pharetra','porta','porttitor','proin','quam','quisque','risus','rutrum','sagittis','sapien','sed','sem','sit','sodales','tellus','tempus','ultricies','urna','ut','vitae','vivamus','vulputate'),

/* words, getWords, get_words
@param words: Number of words to return
@param fullstop: String to append to the words, such as sentence ending punctuation.
@returns String: String of whitespace delimited words.
*/
words: function(words, fullstop){
var lastword, nextword, str, wc = (LoremIpsum.src.length - 1);
lastword = nextword = Math.round(Math.random() * wc);
str = LoremIpsum.src[lastword].charAt(0).toUpperCase() + LoremIpsum.src[lastword].substr(1);
words--;
while(words > 0){
while(lastword == nextword){
nextword = Math.round(Math.random() * wc);
}
str += (' ' + LoremIpsum.src[nextword]);
lastword = nextword;
words--;
}
return str + (fullstop ? fullstop : '');
},

/* sentences, getSentences, get_sentences
@param sentences: Number of sentences to return.
@returns String: String of sentences delimited by current value of LoremIpsum.fullstop
*/
sentences: function(sentences){
var wpsos = LoremIpsum.max_wps - LoremIpsum.min_wps;
var str = LoremIpsum.words((LoremIpsum.min_wps + Math.round(Math.random() * wpsos)), LoremIpsum.fullstop);
sentences--;
while(sentences > 0){
str += (' ' + LoremIpsum.words((LoremIpsum.min_wps + Math.round(Math.random() * wpsos)), LoremIpsum.fullstop));
sentences--;
}
return str;
},

/* paragraphs, getParagraphs, get_paragraphs
@param paragraphs: Number of paragraphs to return.
@param format: How to format each paragraph, where %s is the text.
For instance: <p class="myclass">%s</p>
@returns String: String of paragraphs formated using @format.
*/
paragraphs: function(paragraphs, format){
if(!format){
format = "%s\n\n";
}
var sppos = LoremIpsum.max_spp - LoremIpsum.min_spp;
var str = format.replace(/%s/i, LoremIpsum.sentences(LoremIpsum.min_spp + Math.round(Math.random() * sppos)));
paragraphs--;
while(paragraphs > 0){
str += format.replace(/%s/i, LoremIpsum.sentences(LoremIpsum.min_spp + Math.round(Math.random() * sppos)));
paragraphs--;
}
return str;
},

/* scanElm, scanelm, scan_elm
@param elm: Entry point, DOM Node to begin searching for comment nodes.
@returns Number: The number of comments replaced with text nodes.
*/
scanElm: function(elm){
var rc = 0;
for(var c = 0; c < elm.childNodes.length; c++) {
var child = elm.childNodes[c];
if(child.nodeType == 1){
LoremIpsum.scanElm(child);
}else if (child.nodeType == 8){
var matches = child.data.match(/^\s*(\d+(?:\s*-\s*\d+)?)\s+(words?|sentences?|paragraphs?)\s*$/i);
if(matches){
if(matches[1].indexOf('-') > -1){
var ms = matches[1].split(/\s*-\s*/);
matches[1] = Math.max(ms[0], Math.ceil(Math.random() * ms[1]));
}
child.parentNode.replaceChild(document.createTextNode(LoremIpsum[matches[2]](matches[1])), child);
rc++;
}
}
};
return rc;
},

/* LoremIpsum, main, init
Starts with the root node & recursively processes all comment nodes.
*/
LoremIpsum: function(){
var body = document.documentElement ? document.documentElement : document.body;
LoremIpsum.scanElm(body);
}
};
/* Convenience - aliases - etc */
LoremIpsum.main = LoremIpsum.init = LoremIpsum.LoremIpsum;
LoremIpsum.getWords = LoremIpsum.get_words = LoremIpsum.words;
LoremIpsum.getSentences = LoremIpsum.get_sentences = LoremIpsum.sentences;
LoremIpsum.getParagraphs = LoremIpsum.get_paragraphs = LoremIpsum.paragraphs;
LoremIpsum.scan_elm = LoremIpsum.scanelm = LoremIpsum.scanElm;
lorem_ipsum = loremipsum = loremIpsum = LoremIpsum;

Friday, June 20, 2008

Random Color Generation With Javascript

I'm sure there's quite a few ways to get a random color using JS, I can think of a few such as returning a random index from an array of CSS color names, or generating three random numbers between zero and 255 and formatting from there.

The following method is my favorite though because the single randomly generated integer can be easily converted into pretty much any other format or quickly returned as-is.
To illustrate this I've written the following function which will return a hexidecimal, RGB, or integer format random color depending on the argument passed to the function.

// @format (hex|rgb|null) : Format to return, default is integer
function random_color(format)
{
var rint = Math.round(0xffffff * Math.random());
switch(format)
{
case 'hex':
return ('#0' + rint.toString(16)).replace(/^#0([0-9a-f]{6})$/i, '#$1');
break;

case 'rgb':
return 'rgb(' + (rint >> 16) + ',' + (rint >> 8 & 255) + ',' + (rint & 255) + ')';
break;

default:
return rint;
break;
}
}

Saturday, January 12, 2008

Fancy Blogger Labels Widget

I just noticed Blogger has a post labels widget the other day. After adding it to my layout I discovered I was using quite a few one-time-use labels for my posts. I spent a little while going through my labels & trying to consolidate some of the one-timers into better upper-level groups.
Even after doing this there was still a huge list of words running down the right side of the layout, and I really didn't like how that worked.

So, I fixed it.

With the widget added to my layout, I then modified the HTML used so it was a little cleaner as well as matching the rest of the layout. Blogger templates seem to like using <h2> elements for sidebar items and I like to use <h6> elements.

<b:widget id='Label1' locked='false' title='By Subject' type='Label'>
<b:includable id='main'>
<span class='top'><span/></span>
<div class='content' id='by-subject'>
<b:if cond='data:title'><h6><data:title/></h6></b:if>
<ul><b:loop values='data:labels' var='label'><li><b:if cond='data:blog.url == data:label.url'><data:label.name/><b:else/><a expr:href='data:label.url'><data:label.name/></a></b:if> <small><data:label.count/></small></li></b:loop></ul>
</div>
<span class='bottom'><span/></span>
</b:includable>
</b:widget>


With that, I have a clean matching list of labels in the event JS is disabled.

Now for the fancy part.
I'm having jQuery split that list up into smaller lists, much like the Last 50 Posts navigation works with the dates.
Here's the JS I'm using to do that, note that it's among the things that happen after the document has loaded.
var tags = $('<ul/>');
var branch;
var label = {start:'', end:''};
var tagIndex = 0;
$('#by-subject li').each(function(){
tagIndex++;
label.end = $(this).children('a').text().toLowerCase();
switch(tagIndex){
case 1:
branch = $('<ul/>');
label.start = label.end;
break;
case 10:
tagIndex = 0;
var at = $('<li><a href="#">(' + label.start + ') -- (' + label.end + ')</a></li>');
at.children('a').click(function(){
$(this).siblings('ul').slideToggle(500);
return false;
});
branch.slideUp(1);
branch.appendTo(at);
at.appendTo(tags);
break;
}
$(this).appendTo(branch);
});
var at = $('<li><a href="#">(' + label.start + ') -- (' + label.end + ')</a></li>');
at.children('a').click(function(){
$(this).siblings('ul').slideToggle(500);
return false;
});
branch.slideUp(1);
branch.appendTo(at);
at.appendTo(tags);
$('#by-subject ul').replaceWith(tags);


Basicly, the list is split up into sections of 10 items & each section is labeled with the first and last items in each section. I'll probably switch it to 20 items sometime in the future.

Tuesday, January 8, 2008

Javascript Random Ad Buttons/Banners

I like to think of ad banners on my blog like like the racks in the checkout lines at the grocery store, Impulse Items. I wanted to be as un-obtrusive as possible with ad banners, while still having them stand out.

In order to do this I'm using JS to display them. That way I can defer them from showing untill the content people have come here from search engines to read in the first place has already loaded.
I absolutely hate it when a site makes me stare at a blank section where the article would be while I wait for the advertisements to load. If there's another result I considered clicking on I will immediately close the tab with that blank section in it & go with the alternative instead.
I also don't want to go out of my way to force people to look at advertisements by bypassing blockers & such, doing so appears to be a waste of time.

Now that we know I don't want to intrude, but do want to nag you a little bit, here's how I'm doing it.

First I have an array with objects for all of my banners. Each object includes the alt, href, and src attributes I will need for each banner. Though for some odd reason I decided to use url to denote my href attributes here.
var impulses = new Array(
{alt:'image alt text', url:'click-through-url', src:'image-source'},
{alt:'image alt text', url:'click-through-url', src:'image-source'},
{alt:'image alt text', url:'click-through-url', src:'image-source'}
);


For the sake of simplicity there's only three in that example, but just imagine there's about twenty of those objects in that array.

Now since I don't want the order they're shown in from left to right to be too predictable I'm going cycle a random number of ad banner objects to the end.
Basicly what this code is doing, is geting a random number between zero and the number of ad banner objects there are in the impulses array, and moving the first ad banner object to the end of the array that many times.
for(var i = Math.round(Math.random() * impulses.length); i > 0; i--)
{
impulses.push(impulses.shift());
}


Next I narrow the size of the array down to the number of ad banners I want shown.
Basicly what this code is doing is randomly picking an ad banner object in the array and removing it, untill there's only as many as I want left.
while(impulses.length > 5)
{
impulses.splice(Math.round(Math.random() * (impulses.length - 1)), 1);
}


Once the ad banners that will be displayed are determined I generate the HTML to show them with, I'm using simple <a> and <img> elements for this. I like to generate it using basic data like this so it's easier to modify the actual HTML that's used in a single place later on if I need to.
for(var i = 0; i < impulses.length; i++)
{
impulses[i] = '<a href="'+impulses[i].url+'"><img alt="'+impulses[i].alt+'" src="'+impulses[i].src+'"/></a>';
}


Now with a string of ad banner HTML to use, I make use of the jQuery library to insert it amongst my pages.
var impulse = jQuery("<div id='impulses'>" + impulses.join('') + "</div>").insertBefore('#load-anim');