How to create a sliding popup like the one used at SitePoint using jQuery.
Background
This week, our web ninja needed to add to advertise a survey on the main Uniblue site. Not wanting to have an annoying popup (which would most likely be blocked or ignored) or an overlay (which would interrupt the user), she decided to go for a sliding popup, which is about as unobtrusive as you can get while still being visible.
The script she located and used had some problems; IE6 detection was not working properly, and while the script was supposed to set itself so it would not be shown more than once to a given user, this was not actually happening. Finally, it was blowing up when used in conjunction with other scripts in the page. While she did manage to fix all these items, the script itself was pretty overcomplicated for what it does. This post deals with building a similar feature using jQuery.
Linking jQuery
Like most javascript frameworks, jQuery can be pretty hefty. Google have kindly decided to host a number of such frameworks though, so you can actually link to them. Not only will this save you bandwidth, but it also means that the framework is probably already cached somewhere handy. This means that it gets served to the user much more quickly.
To link to Google’s hosted framework, you can use the URL http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js. Visit http://code.google.com/apis/ajaxlibs/ for details of other hosted frameworks.
Calling the popup
We need to call the popup at some point if we want to display it. A good place for this is in the ready() hook provided by jQuery:
1: $(document).ready(function () {
2: CreatePopup("popup.html", 200, 1500, "testpopup", 5);
3: });
The first argument is the url to the file containing the … um … contents of the popup. The second specifies the height of the popup when the popup is fully open, while the third specifies the amount of time, in milliseconds, that it will take the popup to extend completely. In this case, 1500 means that it will take the popup 1.5 seconds to open to its full size.
The last two arguments are related to the cookie which the popup sets. We’re creating one so that we don’t keep showing the popup every time the user goes into the page. Instead, we store a cookie for a number or days, so that a popup would only ever be shown once. The fourth argument, above, will be the name of the cookie, while the last one is the number of days we will allow the cookie to live. In other words, we’re going to set a cookie called “testpopup” for 5 days.
The popup
The popup will need to be displayed from various pages, since there can be multiple entry points to a site. For this reason, it will be stored in a separate html document, which we will reference from our script. We can do this using jQuery’s get(url, callback) function, which lets us make a request, and fire a callback when that request is received
Creating the popup
The popup is created by inserting an div element at the end of the body, and positioning it under the visible area of the page using fixed css positioning. By specifying a negative value for bottom, we place the element just beneath the visible area. We use –height, so the top of the div is just below the fold:
Script
1: var popup = $("<div>" + data + "</div>")
2: .attr({ "id": "sliding_popup" })
3: .css({"bottom": -1 * height})
4: .height(height)
5: .hide()
6: .appendTo("body");
CSS
1: #sliding_popup {
2: position:fixed;
3: left:0px;
4: display:block;
5: width:100%;
6: padding:0px;
7: margin:0px;
8: }
We can then use the animate() method in jQuery to alter the value to 0, which brings the bottom of the div flush with the bottom of the visible area:
1: popup.show().animate( { bottom: 0 }, duration);
Removing the popup
We want the user to be able to close the popup. To do this, we provide a function which hides the div, and then removes it from the DOM:
1: $("#sliding_popup").animate({
2: bottom: $("#sliding_popup").height() * -1
3: },
4: duration,
5: function () {
6: $("#sliding_popup").remove();
7: });
We’re calling the DOM removal from the callback to the animate function. This lets us wait until the animation is finished before we actually remove the element.
This function can be called from within the popup itself by accessing the parent object, like so:
1: DestroyPopup(1000);
IE6? I see no IE6!
As any designer, developer, and their pets will tell you, IE6 is not so much a browser as a royal pain in the wotzits. Sure, it’s an improvement over IE4, but that was way back before the earth cooled down and the dinosaurs died out. Today, we expect a little bit more cooperation from our browsers.
No, I don’t like IE6 very much. In fact, the script does not support it, period. I can live with that because few of the people who read this blog actually use IE6 (precisely 5 people, according to Google Analytics – you know who you are.)
Since uniblue.com is a front facing website, our friend wasn’t so lucky and had to try and hammer the script into compliance – not a pretty sight. Eventually, she settled for a standard popup for IE6, and the nice slidy animated one for real browsers. Given that the percentage of IE6 users is fairly low there, this is a reasonable compromise – it gets the job done, and doesn’t involve drawing magic circles in goat blood and urine all over your nice clean office floor. If you want to pull a similar trick with this script (or make it work with IE6) you can always check for it using the IsUnsupportedBrowser function and handle accordingly.
Neat!
I downloaded the source code..thanks…
Hello,
I tried this script and it seems the cookie part isn’t working properly? It looks like the cookie doesn’t expire in the amount of days specified, it just stays there. Do you have any ideas on what could be causing this?
Thanks.
Hi John, thanks for leaving a comment 🙂 What browser have you had this problem with?
Also, if you don’t mind my asking, what time zone are you working in? The script uses UTC time, so there may be a few hours difference between the time you’d expect it to expire and the actual time of expiry. (I guess this could be called a bug :$)
hi thanks dear… i was looking for a one time popup but the time i saw this i changed my mind… thank very much again. I’ll try this very soon…
its not working in IE8
Hi saravana – just re-checked this in IE8, and it worked normally. Do you have any error messages related to this problem?
Hi thanks for making the popup. Is there a way to change when the cookie expires?
Cheers,
Darren
Hi Darren, thanks for your comment.
The lifespan of the cookie is set through the last parameter of the function. The parameter is called lifetime, and is set to 5 in the demo; this means that the cookie should live for 5 days.
If you need more control, you can change the ReceivedPopup(description, lifetime) function in sliding_popup.js so that it will change a value other than days.
You can read more about the document.cookie property here: http://msdn.microsoft.com/en-us/library/ms533693(v=vs.85).aspx
Hope that helps 🙂
Hi Karl, thanks for this sliding pop-ul, it’s very helpful!
Check my example http://www.restaurant-chinezesc.ro 😛
Thanks again!
Thanks Liviu – good job on that site, very clean!
Nice!!!
What part of the code should be modified to make the popup fill the browser (width/height 100%) when the webpage loads? I wanted to do an overlay popup.
Hi Mike, thanks you for your comment! The popup should already fill up the entire width of the browser unless you specifically style it to do otherwise; if your div elements are styled in any other way, define #sliding_popup { display:block; width:100% } in your css. For 100% height, you can pass in the body element’s clientHeight to the CreatePopup function:
CreatePopup("popup.html", $(window).height(), 1500, "testpopup", 5);
If you try it on the demo popup.html, you’ll also need to make the following changes in the css:
#sliding_popup .content { position:absolute; left:0px; top:0px; background-color:#AAA; display:block; width:100%; height:100%; border-top:5px solid black;}
Hi Karl,
The modification worked great!!! Thanks for the info and the swift response.
Is it possible to change the transition of the popup content(sliding, fading, etc.)?
Hi again! Glad it helped 🙂
To modify the animation mode, you’d want to alter the ShowPopup function in the js file. This line:
popup.show().animate( { bottom: 0 }, duration);
Should go something like this:
popup.fadeIn(duration);
You’ll also need to alter the style so that the popup starts in position, and has an opacity of 0. The information on http://api.jquery.com/fadeIn/ should help 🙂
Wonder if I should refactor it so that the create method takes the animation as a parameter.
Hello. But how can I automatically destroy popup after a few seconds?
Hi Denis, you should be able to do that using the setTimeout javascript function – the best place to call this would be the “complete” callback in the animate function (inside ShowPopup), something like:
popup.show().animate( { bottom: 0 }, duration, function() { setTimeout("Destroy(1000)", 10000); });
to destroy the popup 10 seconds after the animation completes (refer to http://api.jquery.com/animate/ and http://www.w3schools.com/js/js_timing.asp for more information.)
Hope this helps 🙂
Thank You for an answer, Karl. It works perfectly 🙂
I’ve used this code for paused showhide eff:
setTimeout(‘CreatePopup(“popup.html”, 496, 1500, “popup”, 1)’,5000);
setTimeout(‘DestroyPopup(1000)’,15000);
Glad that’s ok 🙂
is there any way to have it go down automatically like it goes up automatically and can i set it to the top of the site so it slides down from the top.
Hi Jonathan,
To have it disappear automatically, refer to Denis’ comment above.
To have it slide in from the top, change the animation so that it animates the top property, rather than bottom:
popup.show().animate( { top: 0 }, duration);
and set the top property so that it starts at -ve height. Liviu has already done this (see his link, above) so you can get an idea of that from there.
I got it working, I changed the html to php files it still works but when i try to do a php include to another file it doesn’t work why? Does the main page have to be the default page for it to work so for examples my page is homepage.php the script is in test101.php and the second file is test102.php now inside homepage.php i have a include calling the test101.php which is where the script and the jquery is when than calls test102.php but it doesn’t seem to work.
Hi Jonathan – could you give me some more details about this please? Specifically, about the structure of the files – are they in the same folder, what is including what where, and so on?
Yes all the files are in the same folder see i’m trying to add the slide up to my wordpress blog, so what i tried doing is
making a php include for my home page is homepage.php and the popup is test101.php and the other file is test102.php. Now in
my homepage.php i added a php included for file test101.php
It doesnt seem to work in Opera. Any ideas why?
Hi Gloria,
I haven’t tested it in Opera, so no idea at all :$ Will have a look at it later today. What version of Opera are you using?
Hello again Gloria – checked it out in the latest version of Opera, seems to work fine. Do you have more information about this?
Hoi Karl,
I have searched for days to find this great sliding popup code.. theare are not many scripts around with are so small and transparent as yours.. great coding!.. your the man! Simplicity is often the most difficult.
The only thing I can’t get is the time the cookie expires.. I like it to delete itaelf on browser close..
Many thanks
Speciale
Thank you for your comment, Speciale! With regards to the browser cookie, it was necessary to have a timed expiry as the popup only needed to be shown once to each user for the duration of the campaign. If the cookie had been deleted on browser close, the popup would have been shown on every visit 🙂
Hi Karl,
Thanks for the quick reply!
I understand what you mean but i am running a large datingsite and want to alert a member each time they enter the site to upload a profile picture if she/he hasn’t done so.
I read just a lot about cookies (I find cookie code difficult to understand) and found when you delete the expires in:
document.cookie = description + “=true;expires=” + date.toUTCString() + “;path=/”;
the browser delete the cookie on each browser close.
Worked great!
Again thanks for this wonderful script!
Your the man!
regards
Speciale from Holland
No problem! Glad you found it useful!
Hello! I love this code! I seem to be having a problem, however.. the demo works great but the source code I downloaded wont work — tried uploading it and it wont work either! Am I doing something stupid? I’m using Google Chrome on a Mac.
Thank you for your comment, Amber! Regarding your question as to whether you’re doing something stupid, I’ll have to answer that with a definite maybe 🙂 If you can post a link to the page you put it on, we can have a look and see what’s wrong.
Thanks for the fast reply! It’s at: http://cocodecoeur.com/img/lazybones/popup
Looks like that advert at the top of the screen is doing some voodoo that jquery doesn’t like – your hosting provider is injecting some advertising into your page. The problem also affects Firefox on Mac.
Tried to download the test and popup pages back, cleaned out the injected stuff, and it worked again. Try to upload it to a page that doesn’t get those ad thingies, you’ll be fine 🙂
One more question! I promise! I’ve added the popup to a website at lazybonesvintage.com and it doesn’t seem to be working.. is there anything we can do to fix it?
Ok, that one’s easy 🙂 The lazybonesvintage.com site already uses Prototype, so the $ sign is being taken by Prototype before jQuery can get to it.
Normally, I don’t like to use two frameworks in one page, BUT in a pinch, you can replace the $ signs in the sliding popup scripts (in both index.html and sliding_popup.js) with the jQuery long form to avoid clashes – for example
jQuery(document).ready(function () {
jQuery(“#note”).show().click(function () {
…
and so on. Hope that helps 🙂
I’m sorry — where should I add that?
It’s a question of replacing, not adding. Look for every ‘$’ sign in the files you downloaded – index.html and sliding_popup.js – and replace it with ‘jQuery’.
THANKS SO MUCH again. 🙂
Hello,
Love the script, thanks! I want to delay the popup so it takes about 10 seconds to load after the user hits the page. Any suggestions?
Billy
Thank you, Billy!
For the delay, just wrap the function call in a setInterval (http://www.w3schools.com/jsref/met_win_setinterval.asp) call, like so:
setInterval(function () { CreatePopup(“popup.html”, 200, 1500, “testpopup”, 5); }, 10000);
Hi Karl,
Thanks for sharing this code. I have been looking for something like that for my customer. Could you please tell me how to remove cookies and make possible to open this pop-up every time when user visit the page? I know that it is annoying but my customer decided to keep this message for temporary special offer. Thanks Karl!
regards,
Anita
Hi Karl again,
stupid me, I’ve just noticed that there are 5 days and I need to change them… Thanks again for this code!
regards,
Anita
Hi Anita! Glad you found the script useful. Apart from altering the 5-day lifetime on the cookie, you could also do away with it entirely by removing the lines which create and check for the cookie 🙂
i.e. remove HasAlreadyReceivedPopup(description) from the check in CreatePopup, and ReceivedPopup(description, lifetime) from ShowPopup.
Cheers,
Karl
Thanks Karl! You are a star!
Too kind 🙂 But thank you!
Hi Karl
I have been searching for something like this for a while. Is it possible to use it with a jquery lightbox, such as fancybox.net?
Thanks
Hi Tom! Yes, it’s certainly possible – what you’d do is use the script as a trigger for the lightbox. Calling it from inside ShowPopup should do the trick.
Hi Karl, thanks for the quick reply. ShowPopup, is that in the javascript file. Could you provide an example of where this would appear. Thanks again!
Yes, it’s the second method in sliding_popup.js:
function ShowPopup(description, lifetime, popup, duration)
{
popup.show().animate( { bottom: 0 }, duration);
ReceivedPopup(description, lifetime);
}
replace the line “popup.show().animate( { bottom: 0 }, duration);” with a call to the lightbox and you should be set.