I created a sliding div animation that is toggled by clicking a link. The div starts in a hidden state, and slides slowly open the first time the link is clicked. The second click hides the div immediately. This simple animation toggles between these two states.
In every browser I have tested (IE 6-8, Safari, Chrome), the animation can be interrupted as it opens by clicking on the toggle link. In other words, the command to hide the div can be accepted by the script at any time while it is opening. The div doesn't have to open completely before it will accept user input. This is true regardless of OS.
Firefox however is the exception. It must wait until the div is completely open before it accepts further input. This is true of Firefox on both Mac and PC. Is there a threading problem with Firefox? The only clue I can offer is that I use setTimeout to drive the animation.
The code is organized and easy to read. An online version can be found at http://www.pmtlogic.co m/slidingdiv.html . The javascript can be found at the top of the source. It also uses some simple markup and css for demonstration purposes. I have also attached it as a text file that can be run from any desktop (change extension to .html).
Even a simple "alert('hi' )" embedded in the onclick handler of the link itself will not be run until the animation has finished - in Firefox, that is, all other browsers work as expected. I searched for a while on the Internet but couldn't find my problem description exactly. It is much easier to demonstrate in a forum like this.
My guess is that there is either a simple explanation or someone with advanced understanding is required to solve the problem.
My deep appreciation in advance.
In every browser I have tested (IE 6-8, Safari, Chrome), the animation can be interrupted as it opens by clicking on the toggle link. In other words, the command to hide the div can be accepted by the script at any time while it is opening. The div doesn't have to open completely before it will accept user input. This is true regardless of OS.
Firefox however is the exception. It must wait until the div is completely open before it accepts further input. This is true of Firefox on both Mac and PC. Is there a threading problem with Firefox? The only clue I can offer is that I use setTimeout to drive the animation.
The code is organized and easy to read. An online version can be found at http://www.pmtlogic.co m/slidingdiv.html . The javascript can be found at the top of the source. It also uses some simple markup and css for demonstration purposes. I have also attached it as a text file that can be run from any desktop (change extension to .html).
Even a simple "alert('hi' )" embedded in the onclick handler of the link itself will not be run until the animation has finished - in Firefox, that is, all other browsers work as expected. I searched for a while on the Internet but couldn't find my problem description exactly. It is much easier to demonstrate in a forum like this.
My guess is that there is either a simple explanation or someone with advanced understanding is required to solve the problem.
My deep appreciation in advance.
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head></head>
<script type='text/javascript'>
function SlidingContent () {
this.content = new Array;
this.add = function (obj) {
if ( ! obj.prompt ) {
obj.prompt = { open: "open", close: "close" };
}
if ( ! obj.state ) {
obj.state = 0;
}
if ( ! obj.rate ) {
obj.rate = 1;
}
obj.timeout = 0;
document.write("<a href='#' onclick='SLIDINGCONTENT.toggle("+ this.content.length +"); return false'><span id='" + obj.spanID + "'>" + obj.prompt.open + "</span></a>");
this.content[this.content.length] = obj;
}
this.toggle = function (index) {
var obj = this.content[index];
if ( obj.state == 0 ) {
obj.state = 1;
this.open (obj);
}
else {
obj.state = 0;
this.close (obj);
}
}
this.close = function (obj) {
if ( obj.timeout != 0 ) {
clearTimeout(obj.timeout);
}
var span = document.getElementById(obj.spanID);
span.innerHTML = obj.prompt.open;
var container = document.getElementById(obj.containerID);
container.style.height = '0px';
}
this.open = function (obj) {
var span = document.getElementById(obj.spanID);
span.innerHTML = obj.prompt.close;
var ref = this.increment(obj);
obj.timeout = setTimeout(ref, 10);
}
this.increment = function (obj) {
var self = this;
var content = document.getElementById(obj.contentID);
var container = document.getElementById(obj.containerID);
return (function () {
if ( container.offsetHeight < content.offsetHeight ) {
if ( container.offsetHeight + obj.rate >= content.offsetHeight ) {
container.style.height = content.offsetHeight + 'px';
}
else {
container.style.height = (container.offsetHeight + obj.rate) + 'px';
self.open(obj);
}
}
});
}
}
var SLIDINGCONTENT = new SlidingContent ();
</script>
<style type='text/css'>
body {
font: 12px verdana;
}
.expanding {
padding: 0px 5px;
width: 400px;
}
.slideheader {
background-color: #eeeeee;
padding-top: 5px;
margin-bottom: 5px;
}
slideheader strong {
display: block;
float: left;
padding-bottom: 2px;
}
.slideheader a {
display: block;
float: right;
font-weight: bold;
}
.slidecontainer {
width: 100%;
height: 0px;
overflow: hidden;
clear: both;
}
.issue {
clear: both;
}
</style>
<body>
<P>
<div class='expanding'>
<P class='slideheader'><STRONG>Click link to right and re-click before it finishes</STRONG>
<script type='text/javascript'>
SLIDINGCONTENT.add({
contentID: "content1",
containerID: "container1",
spanID: "link1",
prompt: {
open: "open",
close: "close"
},
rate: 1
});
</script>
</p>
<p class='issue'>Only firefox will not interrupt the section as it is sliding down. Why?</p>
<div id='container1' class='slidecontainer'>
<div id='content1' class='slidecontent'>
<P>
hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content hidden content
</P>
</div>
</div>
</div>
</P>
</body>
</html>