PDA

View Full Version : Jquery Slideshow different behaviour on browser's back button in FF and IE



WebSurfer
09-27-2012, 09:35 PM
Hi to you all,

I have a slideshow with links for each image (could also be imagemap). Here is a testrun (http://www.ayu-user.bplaced.net/testrunone/) - Script is below
In FF and Safari I can click on an image, get linked to that page, can read it and on browser's back button I get back to my slideshow EXACTLY WHERE I LEFT IT, SAME IMAGE.
In IE, Chrome and Konq the slideshow starts allover from the beginning.

It is very annoying because my slideshow stops at the last image and shows an imagemap with many links. No visitor will make it to the last link if he has to watch the slideshow each time from beginning on.

I read the thread from Ponder with answers from vwphillips and (of course) John (http://www.dynamicdrive.com/forums/showthread.php?69094-Stop-slideshow-from-starting-over) but hoped for an easier solution... like telling IE, Chrome and Konq to just behave like Firefox.

I am aware that starting the slideshow all over again might also be a feature, but in my case it's not wanted.
Does anybody have an idea why browsers behave so differently and what I can do to fix it? Do I have to use a pause function? Or can I do something to go dirctly to a certain (the last) image of the sildeshow?

Same issue with this completely different slideshow (http://reallysimpleworks.com/slideshow/) (second on page)

Thanks in advance for any support
(The best supporter gets... virtual beer?? No, real beer! The Octoberfest happens right in front of my door for the next 10 days :p Cheers )


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en">
<head>
<title></title>
<style>
#slideshow {
position:relative;
}

#slideshow DIV {
position:absolute;
top:0;
left:0;
z-index:8;
opacity:0.6;
background-color: #006600;
}

#slideshow DIV.active {
z-index:10;
opacity:1.0;
}

#slideshow DIV.last-active {
z-index:9;
}

#slideshow DIV IMG {
height: 600px;
display: block;
border: 0;
}

#hover {
font-size: 18px;
margin: 20px;
background-color: yellow;
}
</style>

<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.1.min.js"></script>
<script type="text/javascript">
function slideSwitch() {
var $active = $('#slideshow DIV.active');

if ( $active.length == 0 ) $active = $('#slideshow DIV:last');

var $next = $active.next().length ? $active.next()
: $('#slideshow DIV:first');

$active.addClass('last-active');

$next.css({opacity: 0.0})
.addClass('active')
.animate({opacity: 1.0}, 800, function() {
$active.removeClass('active last-active');
});
}

jQuery(function($){
setInterval( "slideSwitch()", 2000 );
});
</script>

</head>
<body>


<map name="2" id="2">
<area shape="rect" coords="0,0,400,600" href="page-left.html" title="" target="_self" alt="" />
<area shape="rect" coords="400,0,800,600" href="page-right.html" title="" target="_self" alt="" />
</map>

<div id="slideshow">
<div class="active">
<div id="captionbar">Caption for image 1</div>
<img src="http://i284.photobucket.com/albums/ll12/lexxxijh/Beaches/Wallpaper-green-beach.jpg" alt="Slideshow Image 1" usemap="#2" />
</div>
<div>
<div id="captionbar">Caption for image 2</div>
<img src="http://upload.wikimedia.org/wikipedia/commons/b/ba/Venice_beach_panorama.jpg" alt="Slideshow Image 2" usemap="#2" />
</div>
<div>
<div id="captionbar">Caption for image 3</div>
<img src="http://latitudes.nu/wp-content/uploads/2011/09/Perhentian-Islands.jpg" alt="Slideshow Image 3" usemap="#2" />
</div>
<div>
<div id="captionbar">Caption for image 4</div>
<img src="http://www.my-miami-beach.de/miami-beach-fotos/gross/Wetter-und-Klima-in-Miami-Beach-Florida.jpg" alt="Slideshow Image 4" usemap="#2" />
</div>
</div>

</body>
</html>

jscheuer1
09-28-2012, 02:53 AM
Well you need a cookie in those other browsers. This could probably be tightened up and/or have options added, but basically:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en">
<head>
<title></title>
<style>
#slideshow {
position:relative;
visibility: hidden;
}

#slideshow DIV {
position:absolute;
top:0;
left:0;
z-index:8;
opacity:0.6;
background-color: #006600;
}

#slideshow DIV.active {
z-index:10;
opacity:1.0;
}

#slideshow DIV.last-active {
z-index:9;
}

#slideshow DIV IMG {
height: 600px;
display: block;
border: 0;
}

#hover {
font-size: 18px;
margin: 20px;
background-color: yellow;
}
</style>

<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.1.min.js"></script>
<script type="text/javascript">

jQuery(function($){
var cook = {
set: function(n, v, d){ // cook.set takes (name, value, optional_persist_days) - defaults to session if no days specified
if(d){var dt = new Date();
dt.setDate(dt.getDate() + d);
d = '; expires=' + dt.toGMTString();}
document.cookie = n + '=' + escape(v) + (d || '') + '; path=/';
},
get: function(n){ // cook.get takes (name)
var c = document.cookie.match('(^|;)\x20*' + n + '=([^;]*)');
return c? unescape(c[2]) : null;
}
}, re = /[^\d]/g, activeslide;
function slideSwitch() {
var $active = $('#slideshow DIV.active');

if ( $active.length == 0 ) $active = $('#slideshow DIV:last');

var $next = $active.next().length ? $active.next()
: $('#slideshow DIV:first');

$active.addClass('last-active');

$next.css({opacity: 0.0})
.addClass('active')
.animate({opacity: 1.0}, 800, function() {
activeslide = '' + $('#slideshow').children().index($next);
$active.removeClass('active last-active');
});
}
if((activeslide = cook.get('active-slide'))){
$('#slideshow').children().removeClass('active').eq(activeslide).addClass('active');
}
$('#slideshow').css({visibility: 'visible'});
setInterval( slideSwitch, 2000 );
$(window).on('unload', function(){
if(activeslide){
cook.set('active-slide', activeslide);
}
});

});
</script>

</head>
<body>


<map name="2" id="2">
<area shape="rect" coords="0,0,400,600" href="page-left.html" title="" target="_self" alt="" />
<area shape="rect" coords="400,0,800,600" href="page-right.html" title="" target="_self" alt="" />
</map>

<div id="slideshow">
<div class="active">
<div id="captionbar">Caption for image 1</div>
<img src="http://i284.photobucket.com/albums/ll12/lexxxijh/Beaches/Wallpaper-green-beach.jpg" alt="Slideshow Image 1" usemap="#2" />
</div>
<div>
<div id="captionbar">Caption for image 2</div>
<img src="http://upload.wikimedia.org/wikipedia/commons/b/ba/Venice_beach_panorama.jpg" alt="Slideshow Image 2" usemap="#2" />
</div>
<div>
<div id="captionbar">Caption for image 3</div>
<img src="http://latitudes.nu/wp-content/uploads/2011/09/Perhentian-Islands.jpg" alt="Slideshow Image 3" usemap="#2" />
</div>
<div>
<div id="captionbar">Caption for image 4</div>
<img src="http://www.my-miami-beach.de/miami-beach-fotos/gross/Wetter-und-Klima-in-Miami-Beach-Florida.jpg" alt="Slideshow Image 4" usemap="#2" />
</div>
</div>

</body>
</html>

WebSurfer
09-28-2012, 10:45 PM
John, what can I say... It works, of course... as always. And thank you again...
But I have to admit I am completly lost now.
Does it mean that certain browsers do something similar to saving a cookie and others don't?

Your extensions are not Jquery, but JavaScript, right? To me it looks like ancient hieroglyphs from Egypt.

Well, anyways, let me get this right: The active image is always being saved in a cookie.
Now I removed the loop from the slideshow script (http://www.ayu-user.bplaced.net/testruntwo/) (the if-else) and the slideshow comes to an end. And this last image remains saved in the cookie. I can now go back and forth and will always see the last image when I come back.

What I find strange is that I can delete cookies from the browser menu and on reload the slideshow will still show the last image. Is that normal? If yes I must obviously have understood something wrong.

I want the slideshow to start again from the beginning when I click on either the logo or the reload button. But does it help at all to remove the cookie? I was going to try to understand what your script does with the help of this page (http://techpatterns.com/downloads/javascript_cookies.php) and this one (http://www.quirksmode.org/js/cookies.html).
But if I'm not even half way on the right track?, I am lost... and can only ask you again.

jscheuer1
09-29-2012, 12:29 AM
Only two browsers, there could be more, that I know of remember the state of javascript so that the back button resumes scripts where they left off. Opera and Firefox. They don't use cookies, it's done internally. It's good Opera does this because Opera doesn't fire the onunload event reliably, and as you will see reading on here, that's what I'm using to set the cookie.

Understanding cookies can be hard. But they're just bits of text left on the user's hard drive that can later be read by the browser. They are specific to the page or to the domain or to the path. In this case I chose domain as that's usually the most useful. So only if the browser comes back to that domain and there's a cookie and the page reads it will any information be gotten back from it. They do expire at various times depending upon how they're set. The cookie we're setting here expires when the browser closes.

What's being stored here is the index of the div that was last shown. I don't save it each time it changes though, that's too resource intensive for some browsers/computers. I save a reference to the index each time there's a change, but only set the cookie when the page unloads.

That's why clearing the cookie will not prevent the page from remembering when you reload. You clear the cookie, you reload (which first unloads and sets the cookie), then as its loading it finds the cookie and remembers.

Now, if you're concerned that the user will not see all of the slideshow if it keeps starting over I would think you would not want it restarting on reload. I think you just want this for your own diagnostic/design purposes.

If you were to clear the cookie, and set the variable that's holding the reference to the index to null, and reload - then it would start at the beginning. You could do all three without having to use the browser to clear the cookie or to reload the page.

The variable that holds the reference and the cookie code on the page are both protected though, so you would need to either make them global or create a function that can access them and assign that to something on the page. The variable is activeslide.

So you could do like so, the addition is highlighted and comments are as well and shown in green:


. . . okie = n + '=' + escape(v) + (d || '') + '; path=/';
},
get: function(n){ // cook.get takes (name)
var c = document.cookie.match('(^|;)\x20*' + n + '=([^;]*)');
return c? unescape(c[2]) : null;
}
}, re = /[^\d]/g, activeslide;
$('#activeslidekill').click(function(e){
cook.set('active-slide', '', -1); // set the cookie to an empty value with an expiration date in the past
activeslide = null; // empty the variable with a reference to the active div's index
e.preventDefault() // prevent the link that's being clicked on from firing normally
window.location.reload(true); // reload the page before a new reference to the active div can be made
});
function slideSwitch() {
var $active = $('#slideshow DIV.active');

if ( $active.length == 0 ) $act . . .

Then you could put in the body of the page:


. . . ript>

</head>
<body>
<a href="#" id="activeslidekill">Kill Cookie and Reload</a>

<map name="2" id="2">
<area shape="rect" coords="0,0,400,600" href="page-left.html" title="" target="_self" alt="" />
<area shape="rect" coords="400,0,800 . . .

Clicking on that link will now reload the page with the slideshow starting from the beginning. I used the true modifier on the reload() method because that tells the browser that nothing should be remembered about the state of the page during the reload. It's a little like clearing the cache. Some browsers might remember the script state, but I doubt it.

WebSurfer
09-29-2012, 01:05 AM
John, it is incredibile what you are doing here. And so detailed and fast...
I'm about to get it... And now that you say that the cookie is only set when the page unloads I find it in the script and it gets clearer.
I was just going to figure out how to do the erase function in the script and realised that it is a set function with negative time etc...
I even came close to what you did. The Cookie function is even quite straight forward.

Thank you again. That will help (for the moment)