问题
- There is a function that triggers a callback when finished;
- I call this function 2 or 3 times consecutively;
- Only the callback of the last call does what was expected;
The following description and code exemplifies the true scenario.
I have three pairs of divs. I need to toggle one div of each pair and change the state of the remaining visible divs when it's pair is no more visible.
Then, I made a function to hide a div and change the background color of another one. I did this because I'd like to call this function whenever the user clicked a button to show a description and other non-essential items.
Unfortunately, the result isn't the one I expected. If the user cause the function to be called more than one time, without letting the function finish it's task, only the last bound callback will behave properly, the other ones won't change the background color of the div or will be out of sync with the other div due to delay.
Here is the javascript:
function toggleLayer(layerId,layerId2) {
//element1 is the first div of the pair. The one to be hidden.
element1 = $("#"+layerId);
//element2 is the second div of the pair. The background-color of this one will be changed when the element1 is hidden.
element2 = $("#"+layerId2);
//Hiding the first div
element1.toggle("slow",function() {
//Changing the color of the second div
element2.toggleClass("blue");
});
}
Here is the full HTML, just copy and paste to test:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
<!--
function toggleLayer(layerId,layerId2) {
//element1 is the first div of the pair. The one to be hidden.
element1 = $("#"+layerId);
//element2 is the second div of the pair. The background-color of this one will be changed when the element1 is hidden.
element2 = $("#"+layerId2);
//Hiding the first div
element1.toggle("slow",function() {
//Changing the color of the second div
element2.toggleClass("blue");
});
}
-->
</script>
<style type="text/css">
div{
width:100px;height:300px;background-color:red;float:left;
}
.blue {
background-color: blue !important;
}
</style>
</head>
<body>
<div id="d1"></div>
<div id="d11"></div>
<div id="d2"></div>
<div id="d22"></div>
<div id="d3"></div>
<div id="d33"></div>
<input type="button" onclick="toggleLayer('d1','d11');" value="1" style="clear:both;float:left;" />
<input type="button" onclick="toggleLayer('d2','d22');" value="2" style="clear:both;float:left;" />
<input type="button" onclick="toggleLayer('d3','d33');" value="3" style="clear:both;float:left;" />
<input type="button" onclick="toggleLayer('d1','d11');toggleLayer('d2','d22');" value="1+2" style="clear:both;float:left;" />
<input type="button" onclick="toggleLayer('d1','d11');toggleLayer('d2','d22');toggleLayer('d3','d33');" value="1+2+3" style="clear:both;float:left;" />
</body>
</html>
I was expecting the callback to finish it's task before trying to execute the next call, but it seems the browser is trying to execute them all at the same time. Why does it happen and how do I do it properly?
回答1:
element1 = $("#"+layerId);
element2 = $("#"+layerId2);
You forgot to declare these variables var
, so instead of function-local they're accidental globals. When the function is called a second time, it overwrites the first call's values of element1
/element2
, so when the callback happens element2
is not what you expect.
来源:https://stackoverflow.com/questions/6130249/jquery-when-calling-a-function-multiple-times-in-a-row-why-only-the-callback