Log in

View Full Version : jquery sliding div



TheJoshMan
07-29-2008, 10:34 AM
Wondering if anyone knows how I could use this to display just ONE single image in the box with a sliding description div on mouseover. Right now I can't get the script to work unless there is at least two images with sliding descriptions.

the "slider.js" file:


// ========================================================
// ===== images slider ====
// script: Gerard Ferrandez - Ge-1-doot - February 2008
// http://www.dhteumeuleu.com
// CC-BY-NC
// ========================================================

/* ==== slider nameSpace ==== */
var slider = function() {
/* ==== private methods ==== */
function getElementsByClass(object, tag, className) {
var o = object.getElementsByTagName(tag);
for ( var i = 0, n = o.length, ret = []; i < n; i++) {
if (o[i].className == className) ret.push(o[i]);
}
if (ret.length == 1) ret = ret[0];
return ret;
}
function setOpacity (obj,o) {
if (obj.filters) obj.filters.alpha.opacity = Math.round(o);
else obj.style.opacity = o / 100;
}
/* ==== Slider Constructor ==== */
function Slider(oCont, speed, iW, iH, oP) {
this.slides = [];
this.over = false;
this.S = this.S0 = speed;
this.iW = iW;
this.iH = iH;
this.oP = oP;
this.oc = document.getElementById(oCont);
this.frm = getElementsByClass(this.oc, 'div', 'slide');
this.NF = this.frm.length;
this.resize();
for (var i = 0; i < this.NF; i++) {
this.slides[i] = new Slide(this, i);
}
this.oc.parent = this;
this.view = this.slides[0];
this.Z = this.mx;
/* ==== on mouse out event ==== */
this.oc.onmouseout = function () {
this.parent.mouseout();
return false;
}
}
Slider.prototype = {
/* ==== animation loop ==== */
run : function () {
this.Z += this.over ? (this.mn - this.Z) * .5 : (this.mx - this.Z) * .5;
this.view.calc();
var i = this.NF;
while (i--) this.slides[i].move();
},
/* ==== resize ==== */
resize : function () {
this.wh = this.oc.clientWidth;
this.ht = this.oc.clientHeight;
this.wr = this.wh * this.iW;
this.r = this.ht / this.wr;
this.mx = this.wh / this.NF;
this.mn = (this.wh * (1 - this.iW)) / (this.NF - 1);
},
/* ==== rest ==== */
mouseout : function () {
this.over = false;
setOpacity(this.view.img, this.oP);
}
}
/* ==== Slide Constructor ==== */
Slide = function (parent, N) {
this.parent = parent;
this.N = N;
this.x0 = this.x1 = N * parent.mx;
this.v = 0;
this.loaded = false;
this.cpt = 0;
this.start = new Date();
this.obj = parent.frm[N];
this.txt = getElementsByClass(this.obj, 'div', 'text');
this.img = getElementsByClass(this.obj, 'img', 'diapo');
this.bkg = document.createElement('div');
this.bkg.className = 'backgroundText';
this.obj.insertBefore(this.bkg, this.txt);
if (N == 0) this.obj.style.borderLeft = 'none';
this.obj.style.left = Math.floor(this.x0) + 'px';
setOpacity(this.img, parent.oP);
/* ==== mouse events ==== */
this.obj.parent = this;
this.obj.onmouseover = function() {
this.parent.over();
return false;
}
}
Slide.prototype = {
/* ==== target positions ==== */
calc : function() {
var that = this.parent;
// left slides
for (var i = 0; i <= this.N; i++) {
that.slides[i].x1 = i * that.Z;
}
// right slides
for (var i = this.N + 1; i < that.NF; i++) {
that.slides[i].x1 = that.wh - (that.NF - i) * that.Z;
}
},
/* ==== HTML animation : move slides ==== */
move : function() {
var that = this.parent;
var s = (this.x1 - this.x0) / that.S;
/* ==== lateral slide ==== */
if (this.N && Math.abs(s) > .5) {
this.obj.style.left = Math.floor(this.x0 += s) + 'px';
}
/* ==== vertical text ==== */
var v = (this.N < that.NF - 1) ? that.slides[this.N + 1].x0 - this.x0 : that.wh - this.x0;
if (Math.abs(v - this.v) > .5) {
this.bkg.style.top = this.txt.style.top = Math.floor(2 + that.ht - (v - that.Z) * that.iH * that.r) + 'px';
this.v = v;
this.cpt++;
} else {
if (!this.pro) {
/* ==== adjust speed ==== */
this.pro = true;
var tps = new Date() - this.start;
if(this.cpt > 1) {
that.S = Math.max(2, (28 / (tps / this.cpt)) * that.S0);
}
}
}
if (!this.loaded) {
if (this.img.complete) {
this.img.style.visibility = 'visible';
this.loaded = true;
}
}
},
/* ==== light ==== */
over : function () {
this.parent.resize();
this.parent.over = true;
setOpacity(this.parent.view.img, this.parent.oP);
this.parent.view = this;
this.start = new Date();
this.cpt = 0;
this.pro = false;
this.calc();
setOpacity(this.img, 100);
}
}
/* ==== public method - script initialization ==== */
return {
init : function() {
// create instances of sliders here
// parameters : HTMLcontainer name, speed (2 fast - 20 slow), Horizontal ratio, vertical text ratio, opacity
this.s1 = new Slider("slider", 8, 3.5/3.5, 3.3/6.3, 100);
setInterval("slider.s1.run();", 16);
}
}
}();


The HTML:


<html>
<head>
<title>Slider Test</title>
<script type="text/javascript" language="javascript" src="<?php bloginfo('template_directory'); ?>/Scripts/slider.js">slider.js</script>
<script type="text/javascript" language="javascript" src="<?php bloginfo('template_directory'); ?>/Scripts/jquery-1.2.3.pack.js"></script>
<script type="text/javascript" language="javascript">
$(document).ready(
function () {
$('.themes:last').css('margin','0')
});
</script>
</head>
<body>
<div id="slider">

<div style="border-left: medium none; right: 0px;" class="slide">
<a href="#"><img src="<?php bloginfo('template_directory'); ?>/images/likno_awm.jpg" height="205px" width="410px" alt="Likno All Web Menus Pro v5" title="Likno All Web Menus Pro v5" style="opacity: 1; visibility: visible;" class="diapo"></a>
<div style="top: 205px;" class="backgroundText"></div>
<div style="top: 205px;" class="backgroundText"></div><div style="top: 0px;" class="text">
<span class="title"> <a href="#">This is the title</a></span>
<p>Blah blah blah, descriptive text here...</p>


</div>
</div>
<div style="background: rgb(0, 0, 0) none repeat scroll 0% 0%; left: 97px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" class="slide">
<a href="#"><img src="<?php bloginfo('template_directory'); ?>/images/fill_green.png" height="205px" width="410px" alt="Likno All Web Menus Pro v5" title="Likno All Web Menus Pro v5" style="opacity: 0; visibility: hidden;" class="diapo"></a>
<div style="top: 205px;" class="backgroundText"></div>
<div style="top: 205px;" class="backgroundText"></div><div style="top: 0px;" class="text">
<span class="title"> <a href="#">This is the title</a></span>
<p>Blah blah blah blah, descriptive text here</p>


</div>
</div>


<script type="text/javascript">
/* ==== start script ==== */
slider.init();
</script> </div>

The CSS:



/* Slider */

div.wide #slider {margin-bottom: 0px;}
#slider {height: 205px; position:relative; overflow: hidden; margin-top: 0px; border:1px #a4c634 solid;}
#slider .slide {position: absolute; height:205px; width: 100%;background: #202020;overflow: hidden;border-left: #a4c634 solid 1px;cursor: default;}
#slider .title {font-family:Corbel, Calibri, Verdana, Arial;color: #f0f0f0;font-weight: 80; font-size: 1.2em;}
#slider .backgroundText {position: absolute;
width: 100%;
height: 100%;
top: 100%;
background: #000;
filter: alpha(opacity=80);
opacity: 0.8; }
#slider .text { position: absolute; top: 1%;top: 100%;color: #f0f0f0; font-family: Corbel, Calibri, Verdana, Arial;font-size: 1em;text-align: justify;width: 85%; left: 10px; }
#slider .diapo {position: absolute; filter: alpha(opacity=100); opacity: 1; visibility: hidden; }
</body>
</html>

jscheuer1
07-29-2008, 05:45 PM
You should know by now that this sort of thing is much easier for us to assist you with if you post a link to a live demo of the page:

Please post a link to the page on your site that contains the problematic code so we can check it out.

Without all of the resources (the exact version of jquery used, the images, any other scripts, etc.), creating a local demo for testing would be a huge chore. Just dealing with a live page of this for trouble shooting purposes would be bad enough.

One thought though (without looking through the code or having the advantage of seeing a demo), if the only problem is that you seem to just need two images, how about making the second image the same src as the first, set one of its dimensions to 1px, the other to whatever is required to make this work, and its visibility to hidden.

TheJoshMan
07-29-2008, 09:28 PM
not a bad idea... I didn't think about that. Sorry, I was in a rush to get to work this morning, so I didn't have time to upload the files to my site and make a demo page of it. If this idea you gave me doesn't work, then I'll definitely upload everything and let you take a look at it if you don't mind.

Thanks.
Josh

TheJoshMan
07-29-2008, 10:39 PM
Ok, so I tried what you said and it still doesn't work. It did the same thing it does when there isn't a second image to slide in, the script breaks. So, I've created a demo page and uploaded all the files...

http://www.m-pulsedesigns.com/Testing/Sliding_Description_Test/slider_demo.html

Thanks in advance for any light you can shed on this situation.

TheJoshMan
07-30-2008, 01:25 AM
Anybody got any ideas about this?

TheJoshMan
07-30-2008, 03:33 AM
I'm still getting nowhere with it, so if anyone else has any ideas I'd be happy to try them...

jscheuer1
07-30-2008, 04:15 AM
Let's get this clear, as it appears to 'work'. Right now there are two sliding divisions and two images (at least that I can see). One image is in what appears to be the background (both sliding division slide over it, depending upon where you hover), the other image looks to be a plain green image in the division that slides in from the right. Is there an image in the division that slides in from the bottom?

Now, do you want to end up with one or two sliding divisions? What image do you want to get rid of (I'd think it is the plain green one, just want to be sure). Are there any other major differences from what the current demo is doing that you want to achieve?

TheJoshMan
07-30-2008, 08:03 PM
sorry I wasn't more specific...

What I'm trying to acheive is to get rid of the green image completely as well as the corresponding black sliding div that comes in from the bottom.

I want to keep the image that is "in the background" along with the sliding div which corresponds to that image.

Thanks

TheJoshMan
07-30-2008, 11:58 PM
Here is an image to show you EXACTLY what I'm trying to get...

http://www.m-pulsedesigns.com/Testing/example.png

I want to keep this image, along with the black div that slides in from the bottom which corresponds with it. I want to completely remove the green image and the black div which slides in from the bottom and corresponds to it (the green image).

I've tried every possible way I can think of, but no matter how I remove the image or shrink it or make it "hidden", the script breaks.

Medyman
07-31-2008, 02:07 AM
@Nyne Lyvez...

I think you're overly complicating the matter. I'm not familiar with the script that you're using, so I won't comment on it. But what you're trying to do can be done with fairly simple jQuery syntax. So, you don't have to go about mucking with other code and trying to make it work. Just code the jQuery yourself!

Here (http://www.visualbinary.net/files/tutorials/sliding-div/) is an example of what I'm assuming you need.

I would explain the code, but I think you should be able to figure it out by reading it. Let me know if something is unclear.

TheJoshMan
07-31-2008, 02:13 AM
I just laughed hysterically when I opened that link because that is EXACTLY what I'm trying to accomplish and I had no clue that there was already something which did that without having to tweak it.

So, to keep from kicking myself in the behind and crying, I could only LAUGH.

Thank you so very much!
You just saved me a couple days worth of hair pulling.

TheJoshMan
07-31-2008, 02:33 AM
Ok, so that demo you showed me a link to works great in FF, however it shows an error in IE

I've tracked it down to this code on the page, but don't know how to fix it



<script type="text/javascript">
$(document).ready(function(){
$(".photo").hover(
function() {
$(this).next().animate({
bottom: "0",
}, 400 );
},
function() {
$(this).next().animate({
bottom: "-40px",
}, 400 );
}
);
});
</script>


The error it's throwing is: "Expected identifier, string or number"

The Demo Page (http://www.visualbinary.net/files/tutorials/sliding-div/)

rangana
07-31-2008, 02:43 AM
<script type="text/javascript">
$(document).ready(function(){
$(".photo").hover(
function() {
$(this).next().animate({
bottom: "0px",
}, 400 );
},
function() {
$(this).next().animate({
bottom: "-40px",
}, 400 );
}
);
});
</script>

TheJoshMan
07-31-2008, 02:47 AM
nope, that still didn't do the trick. I'm beginning to think that I'm apparently not meant to have a sliding div on my page, otherwise it would all have worked by now. LOL

jscheuer1
07-31-2008, 03:25 AM
That demo doesn't work too well in FF either. If you place the cursor at the bottom, over the area where the panel will be, it slides up and down continuously. It needs a cancel or looping pause routine for when it is still over the image but is also over the slide in panel itself. I'm pretty sure there are scripts that do this well cross browser using jQ, or maybe it was Moo Tools where I saw that though.

Here's the fix for IE:


<script type="text/javascript">
$(document).ready(function(){
$(".photo").hover(
function() {
$(this).next().animate({
bottom: "0"}, 400 );
},
function() {
$(this).next().animate({
bottom: "-40px"}, 400 );
}
);
});
</script>

You cannot have a comma after the last property in an object. FF error corrects for this in almost all cases though.

jscheuer1
07-31-2008, 03:04 PM
Someone with a greater knowledge of jQuery than I might be able to simplify, and/or make this smoother, but this is pretty good (takes care of the problem that occurs if one enters the trigger area from the bottom):


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Visual Binary | Tutorials | Sliding Div</title>

<style type="text/css">
html { margin:0; padding:0; }
body { margin:10px auto; padding:0; width:500px; }
img { border:none; }

div.slide { width:500px; height:334px; position:relative; overflow:hidden; }
div.caption { margin:0; background:#eee; color:#444; position:absolute; bottom:-40px; width:100%; }
h1.title { margin:0; font:bold 14px Arial; padding:5px; height:30px; }

#attribution { font:bold 11px Arial; color:#888; position:fixed; bottom:0px; left:0; width:100%; }
#attribution a { color:#aaa; text-decoration:none; }
#attribution p { margin:0; padding:5px; background:#eee; }

</style>
<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.2.6.pack.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$(".photo").hover(
function(e) {
if($.browser.msie)
$(this).next().stop();
$(this).next().animate({
bottom: "0"}, 400 );
},
function(e) {
if(!$.browser.msie){
var r = e.relatedTarget;
while(r.parentNode){
if(r.className && r.className == 'caption')
return;
r = r.parentNode;
};
}else $(this).next().stop();
$(this).next().animate({
bottom: "-40px"}, 400 );
}
);
$(".caption").hover(
function(e) {
if($.browser.msie)
$(this).stop();
$(this).animate({
bottom: "0"}, 400 );
},
function(e) {
if(!$.browser.msie){
var r = e.relatedTarget;
while(r.parentNode){
if(r.className && r.className == 'photo')
return;
r = r.parentNode;
};
}else $(this).stop();
$(this).animate({
bottom: "-40px"}, 400 );
}
);
});
</script>
</head>
<body>


<div class="slide">
<div class="photo"><a href="http://www.flickr.com/photos/antifluor/2627534389/"><img title="" src="http://farm4.static.flickr.com/3118/2627534389_0223dabfbb.jpg" alt="http://www.flickr.com/photos/antifluor/2627534389/"></a></div>
<div class="caption"><h1 class="title">Caption</h1></div>
</div>


<div id="attribution">
<p>This work is licensed under a <a href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-Share Alike 3.0 Unported License</a>. Images are properties of their respective owners.</p>
</div>

</body>
</html>

However, I've noticed in the past (before any script libraries existed) that there is often no good way to stop/start/switch animated movement on the basis of anything in javascript. Some minor jerkiness is always a possibility.

TheJoshMan
08-01-2008, 03:42 AM
Ok, so everything works GREAT in IE, however IE SUCKS! I have noticed now, that when I view this demo in FF3, the DIV seems to have a memory.

Explanation:
When you pass the mouse over the DIV to make it slide up, it works just fine. However, if you happen to pass your mouse over the DIV a few times repeatedly, the script apparently counts how many times the mouse passed over the DIV and plays the animation that many times.

The Link:
http://www.eight7teen.com/tester.html

This only happens in FF that I'm aware of, I couldn't recreate it in IE, but I can see as how this might become a problem in the future if I use this for what I intend.

Is there any way to alleviate this problem?

jscheuer1
08-01-2008, 09:19 AM
Actually, it happens in all but IE. But I hadn't noticed it yet. So maybe IE doesn't suck at everything. By way of explanation, when trying to take care of the bouncing effect when entering the trigger area slowly from the bottom, I first hit upon the idea of similar events for the caption class. But I noticed this by itself didn't fix it. So I decided that if I knew where the mouse was coming from (e.relatedTarget), I could exit (return) when the mouse was coming from somewhere where there was a redundant call. This seemed fine in all but IE, which appeared to need a stop() to work. Then I figured, well that's simpler, why not do all browsers that way? But it was jerkier (under certain situations) in FF and others than the relatedTarget method.

However, now we find that without a stop, there is the queue effect. This is a feature of jQ (and other script library) effects. It may even have been a problem with the original, we just didn't notice it.

The good news is that we can now simplify things a great deal, not have to sniff ($.browser.msie), and that the jerkiness is still minimal, just not as minimal as before in non-IE:


<script type="text/javascript">
$(document).ready(function(){
var c = $(".caption");
$(".photo").hover(
function() {
c.stop();
c.animate({bottom: "0"}, 400);
},
function() {
c.stop();
c.animate({bottom: "-40px"}, 400);
}
);
c.hover(
function() {
c.stop();
c.animate({bottom: "0"}, 400);
},
function() {
c.stop();
c.animate({bottom: "-40px"}, 400);
}
);
});
</script>

Out of curiosity I went back and checked the 'original' (http://www.visualbinary.net/files/tutorials/sliding-div/) and it suffered from this same queue effect as I suspected, we just hadn't noticed it there.

TheJoshMan
08-01-2008, 08:06 PM
thank you very much, I just got off work so I'll give it a shot when I get home.

TheJoshMan
08-01-2008, 10:56 PM
Works perfectly, thank you very much sir. It's a little jumpy/jerky, but it's functional and it doesn't remember anything anymore (which is good), so I'm going to stick with it.

jscheuer1
08-02-2008, 03:49 PM
Works perfectly, thank you very much sir. It's a little jumpy/jerky, but it's functional and it doesn't remember anything anymore (which is good), so I'm going to stick with it.

You're welcome, just for future reference - I saw very little jumpiness in IE, slightly more in others. But regardless of the browser, this only happened (with one exception, noted below) when one entered the trigger area by passing over that portion of it where the slide up div would appear, causing the script to have to jump back and forth between the two .hover assignments. Is that what you are seeing?

The exception. I don't think I saw this in IE. In others there could be a random momentary jerk to the motion at any time - similar to how other browsers sometimes do that with any javascript scripted movement.

One could make things smoother by having the actual trigger element outside the current trigger area, a show/hide button or link. But this would change the UI.

Muzza
09-03-2008, 04:36 AM
Hi Guys,

just found this script, its exactly what I was looking for so thank-you very much! Thing is Im a front-end designer, so my Javascript is none too hot and I want to take it a little further.

I've implemented your code into my design and it works perfectly. Thing is I now want to add more images, each with their own rollover and cant work out how to make each overlay unique to its image. At the moment when I rollover any image, all of the overlays are triggered at once because the script is looking for "caption", of which there are many. I thought I could give each "slide" div a unique ID, then target "caption" within that div ID. Just dont know how to go about it?????

Hope this makes sense. Any help would be super appreciated!
Cheers

Muzza
09-03-2008, 05:29 PM
is anyone able to help? I need to launch this site asap, if no one can help today then I'll scrap this code for now and come back to it another day. Even just a refering link to how I might go about this.....:)

jscheuer1
09-04-2008, 03:52 PM
Hi Guys,

just found this script, its exactly what I was looking for so thank-you very much! Thing is Im a front-end designer, so my Javascript is none too hot and I want to take it a little further.

I've implemented your code into my design and it works perfectly. Thing is I now want to add more images, each with their own rollover and cant work out how to make each overlay unique to its image. At the moment when I rollover any image, all of the overlays are triggered at once because the script is looking for "caption", of which there are many. I thought I could give each "slide" div a unique ID, then target "caption" within that div ID. Just dont know how to go about it?????

Hope this makes sense. Any help would be super appreciated!
Cheers

There are probably other ways, here's one - Use this script:


<script type="text/javascript">
$(document).ready(function(){
for(var i = 0; i < $(".caption").length; ++i){
var c = $("#caption_" + i);
var p = $("#photo_" + i);
p.hover(
function() {
$(this).next().stop();
$(this).next().animate({bottom: "0"}, 400);
},
function() {
$(this).next().stop();
$(this).next().animate({bottom: "-40px"}, 400);
}
);
c.hover(
function() {
$(this).stop();
$(this).animate({bottom: "0"}, 400);
},
function() {
$(this).stop();
$(this).animate({bottom: "-40px"}, 400);
}
);};
});
</script>

And, this sort of markup (important changes highlighted):


<div class="slide">
<div id="photo_0"><a href="http://www.flickr.com/photos/antifluor/2627534389/"><img title="" src="http://farm4.static.flickr.com/3118/2627534389_0223dabfbb.jpg" alt="http://www.flickr.com/photos/antifluor/2627534389/"></a></div>
<div class="caption" id="caption_0"><h1 class="title">Caption</h1></div>
</div>

<div class="slide">
<div id="photo_1"><a href="http://www.flickr.com/photos/antifluor/2627534389/"><img title="" src="http://farm4.static.flickr.com/3118/2627534389_0223dabfbb.jpg" alt="http://www.flickr.com/photos/antifluor/2627534389/"></a></div>
<div class="caption" id="caption_1"><h1 class="title">Caption</h1></div>
</div>

You may, of course, use different images.

Muzza
09-04-2008, 04:47 PM
thanks very much John! I'll implement that code now and let you know how I get on.