在 JS 中滑动 and/or 动画的问题
Issues with swipe and/or animate in JS
它是什么:
我的可滑动表单有问题。它使用 vanilla JS 方法实现滑动识别和 .animate 循环遍历表单的每个部分。
我的问题:
当连续执行太多滑动或连续单击太多下一个按钮时,.animate 似乎会失败并且它们开始堆积在可见区域的中心。
我尝试过的事情:
我试过 stopPropagation() 和 setTimeout(),但都没有帮助。我也试过在函数开始时删除监听器,然后在 nextPrev() 函数的末尾添加它们,这也没有解决问题。
我不确定到底哪里出错了,因此不知道如何解决这个问题。我在不同的阶段尝试过不同的东西,但似乎没有什么可以解决这个问题。我正在寻找一种方法来防止这种情况发生。
对于没有展示 MCVE,我深表歉意,我故意留下了所有内容,以便有人可以体验循环浏览表单并重现问题。
代码:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js">
</script>
<style>
body {
align-items: center;
width: 100%;
font-size: 2em;
}
#form {
display: flex;
margin: auto;
align-items: center;
text-align: center;
width: 750px;
height: 750px;
border: 1px solid black;
position: relative;
overflow: hidden;
}
#btns {
margin: auto;
text-align: center;
width: 250px;
height: 50px;
}
#back {
float: left;
}
#next {
float: right;
}
table {
margin: auto;
}
.part:not(:first-child) {
display: inline-block;
position: absolute;
right: 0px;
left: 5000px;
}
.part:first-child {
display: inline-block;
position: absolute;
right: 0px;
left: 0px;
}
input[type=text],input[type=number],input[type=date],input[type=time], select {
width: 500px;
padding: 30px 20px;
margin: 8px 0;
border: 1px solid Black;
border-radius: 10px;
box-sizing: border-box;
font-size: 1em;
color: Black;
}
input[type=radio] {
width: 100px;
height: 100px;
}
input[type=checkbox] {
width: 40px;
height: 40px;
}
</style>
</head>
<body>
<div id="form">
<div id="0" class="part"><h3>Driver Information</h3></div>
<div id="1" class="part">Company:<br><input type="text" name="carrier"></div>
<div id="2" class="part">Station:<br><table>
<tr><td>PDX:</td><td><input type="radio" id="pdx" name="address"></td></tr>
<tr><td>EUG:</td><td><input type="radio" id="pdx" name="address"></td></tr>
<tr><td>SEA:</td><td><input type="radio" id="pdx" name="address"></td></tr>
<tr><td>SFO:</td><td><input type="radio" id="pdx" name="address"></td></tr></table></div>
<div id="3" class="part">Name:<br><input type="text" name="name" placeholder="Your Full Name"></div>
<div id="4" class="part">Employee Number:<br><input type="number" name="employeeNumber" placeholder="Your Employee Number"></div>
<div id="5" class="part">Date:<br><input type="date" id="date" name="date"></div>
<div id="6" class="part">Time:<br><input type="time" id="time" name="time"></div>
<div id="7" class="part"><h3>Vehicle<br>Information</h3></div>
<div id="8" class="part">Tractor/Truck Number:<br><input type="number" id="tractorTruckNumber" name="tractorTruckNumber"></div>
<div id="9" class="part">Odometer:<br><input type="number" id="odometer" name="odometer"></div>
<div id="10" class="part"><h4><p>Vehicle Inspection<br><small></small></p></h4></div>
<div id="11" class="part">
<table>
<tr><td>Air Compressor:</td><td><input type="checkbox" class="truck" id="aircompressor"></td></tr>
<tr><td>Air Lines:</td><td><input type="checkbox" class="truck" id="airlines"></td></tr>
<tr><td>Battery:</td><td><input type="checkbox" class="truck" id="battery"></td></tr>
<tr><td>Belts and Hoses:</td><td><input type="checkbox" class="truck" id="beltsandhoses"></td></tr>
<tr><td>Body:</td><td><input type="checkbox" class="truck" id="body"></td></tr>
</table>
</div>
<div id="12" class="part">
<table>
<tr><td>Brake Accessories:</td><td><input type="checkbox" class="truck" id="brakeaccessories"></td></tr>
<tr><td>Brakes, Parking:</td><td><input type="checkbox" class="truck" id="brakesparking"></td></tr>
<tr><td>Brakes, Service:</td><td><input type="checkbox" class="truck" id="brakesservice"></td></tr>
<tr><td>Clutch:</td><td><input type="checkbox" id="clutch"></td></tr>
<tr><td>Coupling Devices:</td><td><input type="checkbox" class="truck" id="couplingdevices"></td></tr>
</table>
</div>
<div id="13" class="part">
<table>
<tr><td>Defroster/Heater:</td><td><input type="checkbox" class="truck" id="defrosterheater"></td></tr>
<tr><td>Drive Line:</td><td><input type="checkbox" class="truck" id="driveline"></td></tr>
<tr><td>Engine:</td><td><input type="checkbox" class="truck" id="engine"></td></tr>
<tr><td>Exhaust:</td><td><input type="checkbox" class="truck" id="exhaust"></td></tr>
<tr><td>Fifth Wheel:</td><td><input type="checkbox" class="truck" id="fifthwheel"></td></tr>
</table>
</div>
<div id="14" class="part">
<table>
<tr><td>Fluid Levels:</td><td><input type="checkbox" class="truck" id="fluidlevels"></td></tr>
<tr><td>Frame and Assembly:</td><td><input type="checkbox" class="truck" id="frameandassembly"></td></tr>
<tr><td>Front Axle:</td><td><input type="checkbox" class="truck" id="frontaxle"></td></tr>
<tr><td>Fuel Tanks:</td><td><input type="checkbox" class="truck" id="fueltanks"></td></tr>
<tr><td>Horn:</td><td><input type="checkbox" class="truck" id="horn"></td></tr>
</table>
</div>
<div id="15" class="part">
<table>
<tr><td>Lights:</td><td><input type="checkbox" class="truck" id="lights"></td></tr>
</table>
<small><center><p>Head/Stop, Tail/Dash, Turn Indicators, Clearance/Marker</p></center></small>
</div>
<div id="16" class="part">
<table>
<tr><td>Mirrors:</td><td><input type="checkbox" class="truck" id="mirrors"></td></tr>
<tr><td>Muffler:</td><td><input type="checkbox" class="truck" id="muffler"></td></tr>
<tr><td>Oil Pressure:</td><td><input type="checkbox" class="truck" id="oilpressure"></td></tr>
<tr><td>Radiator:</td><td><input type="checkbox" class="truck" id="radiator"></td></tr>
<tr><td>Read End:</td><td><input type="checkbox" class="truck" id="rearend"></td></tr>
<tr><td>Reflectors:</td><td><input type="checkbox" class="truck" id="reflectors"></td></tr>
</table>
</div>
<div id="17" class="part">
<table>
<tr><td>Safety Equipment:</td><td><input type="checkbox" class="truck" id="safetyequipment"></td></tr>
</table>
<small><center><p>Fire Extinguisher, Flags/Flares/Fusees, Reflective Triangles, Spare Bulbs/Fuses, Spare Seal Beam</p></center></small>
</div>
<div id="18" class="part">
<table>
<tr><td>Starter:</td><td><input type="checkbox" class="truck" id="starter"></td></tr>
<tr><td>Steering:</td><td><input type="checkbox" class="truck" id="steering"></td></tr>
<tr><td>Suspension System:</td><td><input type="checkbox" class="truck" id="suspensionsystem"></td></tr>
<tr><td>Tire Chains:</td><td><input type="checkbox" class="truck" id="tirechains"></td></tr>
<tr><td>Tires:</td><td><input type="checkbox" class="truck" id="tires"></td></tr>
<tr><td>Transmission:</td><td><input type="checkbox" class="truck" id="transmission"></td></tr>
</table>
</div>
<div id="19" class="part">
<table>
<tr><td>Trip Recorder:</td><td><input type="checkbox" class="truck" id="triprecorder"></td></tr>
<tr><td>Wheels and Rims</td><td><input type="checkbox" class="truck" id="wheelsandrims"></td></tr>
<tr><td>Windows</td><td><input type="checkbox" class="truck" id="windows"></td></tr>
<tr><td>Windshield Wipers:</td><td><input type="checkbox" class="truck" id="windshieldwipers"></td></tr>
<tr><td>Other:</td><td><input type="checkbox" class="truck" id="other"></td></tr>
</table>
</div>
<div id="20" class="part">Remarks:<br><input type="text" id="truckremarks"></div>
<div id="21" class="part"><h3>Trailer Inspection</h3></div>
<div id="22" class="part">Trailer Number:<br><input type="number" id="trailernumber"><br><h6>(if no trailer, click next)</h6></div>
</div>
<div id="btns"><input type="button" id="back" onclick="nextPrev(-1)" value="<< Back"><input type="button" id="next" onclick="nextPrev(1);" value="Next >>"></div>
</body>
<script>
var part = $('.part')
var currentPart = 0;
checkButtons();
var isSwiping = false;
function startSwipe(){
if (isSwiping){
return false;
}
else {
isSwiping = true;
$('#back, #next').attr('disabled',true);
return true;
}
}
function endSwipe(){
$('#back, #next').removeAttr('disabled');
isSwiping = false;
}
function nextPrev(n){
if (startSwipe()){//this doesn't work when swiping with startSwipe(), but buttons still work
if (n === 1){
if (currentPart !== part.length-1){
$('#'+currentPart).filter(':not(:animated)').animate({'left':'-5000px'},500,function(){
$(this).css({'left':'-5000px'});//set current left
});//move current left
$('#'+(currentPart+n)).delay(200).filter(':not(:animated)').animate({'left':'0'},500,function(){
$(this).css({'left':'0'});//set next centered
currentPart = currentPart + n;
checkButtons();
endSwipe();
});//move next right
}
}
if (n === -1){
if (currentPart !==0){
$('#'+currentPart).filter(':not(:animated)').animate({'left':'5000px'},500,function(){
$('#'+currentPart).css({'left':'5000px'});//set current right
});//move current left
$('#'+(currentPart+n)).delay(200).filter(':not(:animated)').animate({'left':'0'},500,function(){
$('#'+(currentPart+n)).css({'left':'0'});//set next centered
currentPart = currentPart + n;
checkButtons();
endSwipe();
});//move next right
}
}
}
}
function checkButtons(){
if (currentPart == 0){
$('#back').css({'display':'none'});
}
else if (currentPart == part.length-1){
$('#next').css({'display':'none'});
}
else {
$('#back').css({'display':'block'});
$('#next').css({'display':'block'});
}
}
document.getElementById('form').addEventListener('touchstart', handleTouchStart, false);
document.getElementById('form').addEventListener('touchmove', handleTouchMove, false);
document.getElementById('form').addEventListener('touchend', handleTouchEnd, false);
var xDown = null;
var yDown = null;
function getTouches(evt) {
return evt.touches || // browser API
evt.originalEvent.touches; // jQuery
}
function handleTouchStart(evt) {
if (startSwipe()){
const firstTouch = getTouches(evt)[0];
xDown = firstTouch.clientX;
yDown = firstTouch.clientY;
}
};
function handleTouchMove(evt) {
if (isSwiping){
if ( ! xDown || ! yDown ) {
return;
}
var xUp = evt.touches[0].clientX;
var yUp = evt.touches[0].clientY;
var xDiff = xDown - xUp;
var yDiff = yDown - yUp;
if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/
if ( xDiff > 0 ) {
nextPrev(1);
} else {
nextPrev(-1);
}
}
/* reset values */
xDown = null;
yDown = null;
}
};
function handleTouchEnd(evt) {
endSwipe();
};
</script>
</html>
更新:ariel 的解决方案很好,虽然它没有解决我的问题。这种标记很重要,我的代码应该已经配备了它。我仍然遇到问题,尽管我在这里发现了一些有希望的东西:https://css-tricks.com/full-jquery-animations/
虽然它没有完全解决我的问题,但它已经非常接近解决方案了,我会在有解决方案时更新。
您需要使用标志来防止在动画发生时触发事件:
var isSwiping = false;
function startSwipe() {
if (isSwiping) {
return false;
} else {
isSwiping = true;
$("button#back, button#next").attr("disabled", true);
return true;
}
}
function endSwipe() {
$("button#back, button#next").removeAttr("disabled");
isSwiping = false;
}
function nextPrev(n) {
if (startSwipe()) {
...
// Inside animate callback:
endSwipe();
...
}
...
document.getElementById('form').addEventListener('touchstart', handleTouchStart, false);
document.getElementById('form').addEventListener('touchmove', handleTouchMove, false);
document.getElementById('form').addEventListener('touchend', handleTouchEnd, false);
...
function handleTouchStart(evt) {
if (startSwipe()) {
...
}
};
function handleTouchMove(evt) {
if (isSwiping) {
...
}
};
function handleTouchEnd(evt) {
endSwipe();
};
它是什么: 我的可滑动表单有问题。它使用 vanilla JS 方法实现滑动识别和 .animate 循环遍历表单的每个部分。
我的问题: 当连续执行太多滑动或连续单击太多下一个按钮时,.animate 似乎会失败并且它们开始堆积在可见区域的中心。
我尝试过的事情: 我试过 stopPropagation() 和 setTimeout(),但都没有帮助。我也试过在函数开始时删除监听器,然后在 nextPrev() 函数的末尾添加它们,这也没有解决问题。
我不确定到底哪里出错了,因此不知道如何解决这个问题。我在不同的阶段尝试过不同的东西,但似乎没有什么可以解决这个问题。我正在寻找一种方法来防止这种情况发生。
对于没有展示 MCVE,我深表歉意,我故意留下了所有内容,以便有人可以体验循环浏览表单并重现问题。
代码:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js">
</script>
<style>
body {
align-items: center;
width: 100%;
font-size: 2em;
}
#form {
display: flex;
margin: auto;
align-items: center;
text-align: center;
width: 750px;
height: 750px;
border: 1px solid black;
position: relative;
overflow: hidden;
}
#btns {
margin: auto;
text-align: center;
width: 250px;
height: 50px;
}
#back {
float: left;
}
#next {
float: right;
}
table {
margin: auto;
}
.part:not(:first-child) {
display: inline-block;
position: absolute;
right: 0px;
left: 5000px;
}
.part:first-child {
display: inline-block;
position: absolute;
right: 0px;
left: 0px;
}
input[type=text],input[type=number],input[type=date],input[type=time], select {
width: 500px;
padding: 30px 20px;
margin: 8px 0;
border: 1px solid Black;
border-radius: 10px;
box-sizing: border-box;
font-size: 1em;
color: Black;
}
input[type=radio] {
width: 100px;
height: 100px;
}
input[type=checkbox] {
width: 40px;
height: 40px;
}
</style>
</head>
<body>
<div id="form">
<div id="0" class="part"><h3>Driver Information</h3></div>
<div id="1" class="part">Company:<br><input type="text" name="carrier"></div>
<div id="2" class="part">Station:<br><table>
<tr><td>PDX:</td><td><input type="radio" id="pdx" name="address"></td></tr>
<tr><td>EUG:</td><td><input type="radio" id="pdx" name="address"></td></tr>
<tr><td>SEA:</td><td><input type="radio" id="pdx" name="address"></td></tr>
<tr><td>SFO:</td><td><input type="radio" id="pdx" name="address"></td></tr></table></div>
<div id="3" class="part">Name:<br><input type="text" name="name" placeholder="Your Full Name"></div>
<div id="4" class="part">Employee Number:<br><input type="number" name="employeeNumber" placeholder="Your Employee Number"></div>
<div id="5" class="part">Date:<br><input type="date" id="date" name="date"></div>
<div id="6" class="part">Time:<br><input type="time" id="time" name="time"></div>
<div id="7" class="part"><h3>Vehicle<br>Information</h3></div>
<div id="8" class="part">Tractor/Truck Number:<br><input type="number" id="tractorTruckNumber" name="tractorTruckNumber"></div>
<div id="9" class="part">Odometer:<br><input type="number" id="odometer" name="odometer"></div>
<div id="10" class="part"><h4><p>Vehicle Inspection<br><small></small></p></h4></div>
<div id="11" class="part">
<table>
<tr><td>Air Compressor:</td><td><input type="checkbox" class="truck" id="aircompressor"></td></tr>
<tr><td>Air Lines:</td><td><input type="checkbox" class="truck" id="airlines"></td></tr>
<tr><td>Battery:</td><td><input type="checkbox" class="truck" id="battery"></td></tr>
<tr><td>Belts and Hoses:</td><td><input type="checkbox" class="truck" id="beltsandhoses"></td></tr>
<tr><td>Body:</td><td><input type="checkbox" class="truck" id="body"></td></tr>
</table>
</div>
<div id="12" class="part">
<table>
<tr><td>Brake Accessories:</td><td><input type="checkbox" class="truck" id="brakeaccessories"></td></tr>
<tr><td>Brakes, Parking:</td><td><input type="checkbox" class="truck" id="brakesparking"></td></tr>
<tr><td>Brakes, Service:</td><td><input type="checkbox" class="truck" id="brakesservice"></td></tr>
<tr><td>Clutch:</td><td><input type="checkbox" id="clutch"></td></tr>
<tr><td>Coupling Devices:</td><td><input type="checkbox" class="truck" id="couplingdevices"></td></tr>
</table>
</div>
<div id="13" class="part">
<table>
<tr><td>Defroster/Heater:</td><td><input type="checkbox" class="truck" id="defrosterheater"></td></tr>
<tr><td>Drive Line:</td><td><input type="checkbox" class="truck" id="driveline"></td></tr>
<tr><td>Engine:</td><td><input type="checkbox" class="truck" id="engine"></td></tr>
<tr><td>Exhaust:</td><td><input type="checkbox" class="truck" id="exhaust"></td></tr>
<tr><td>Fifth Wheel:</td><td><input type="checkbox" class="truck" id="fifthwheel"></td></tr>
</table>
</div>
<div id="14" class="part">
<table>
<tr><td>Fluid Levels:</td><td><input type="checkbox" class="truck" id="fluidlevels"></td></tr>
<tr><td>Frame and Assembly:</td><td><input type="checkbox" class="truck" id="frameandassembly"></td></tr>
<tr><td>Front Axle:</td><td><input type="checkbox" class="truck" id="frontaxle"></td></tr>
<tr><td>Fuel Tanks:</td><td><input type="checkbox" class="truck" id="fueltanks"></td></tr>
<tr><td>Horn:</td><td><input type="checkbox" class="truck" id="horn"></td></tr>
</table>
</div>
<div id="15" class="part">
<table>
<tr><td>Lights:</td><td><input type="checkbox" class="truck" id="lights"></td></tr>
</table>
<small><center><p>Head/Stop, Tail/Dash, Turn Indicators, Clearance/Marker</p></center></small>
</div>
<div id="16" class="part">
<table>
<tr><td>Mirrors:</td><td><input type="checkbox" class="truck" id="mirrors"></td></tr>
<tr><td>Muffler:</td><td><input type="checkbox" class="truck" id="muffler"></td></tr>
<tr><td>Oil Pressure:</td><td><input type="checkbox" class="truck" id="oilpressure"></td></tr>
<tr><td>Radiator:</td><td><input type="checkbox" class="truck" id="radiator"></td></tr>
<tr><td>Read End:</td><td><input type="checkbox" class="truck" id="rearend"></td></tr>
<tr><td>Reflectors:</td><td><input type="checkbox" class="truck" id="reflectors"></td></tr>
</table>
</div>
<div id="17" class="part">
<table>
<tr><td>Safety Equipment:</td><td><input type="checkbox" class="truck" id="safetyequipment"></td></tr>
</table>
<small><center><p>Fire Extinguisher, Flags/Flares/Fusees, Reflective Triangles, Spare Bulbs/Fuses, Spare Seal Beam</p></center></small>
</div>
<div id="18" class="part">
<table>
<tr><td>Starter:</td><td><input type="checkbox" class="truck" id="starter"></td></tr>
<tr><td>Steering:</td><td><input type="checkbox" class="truck" id="steering"></td></tr>
<tr><td>Suspension System:</td><td><input type="checkbox" class="truck" id="suspensionsystem"></td></tr>
<tr><td>Tire Chains:</td><td><input type="checkbox" class="truck" id="tirechains"></td></tr>
<tr><td>Tires:</td><td><input type="checkbox" class="truck" id="tires"></td></tr>
<tr><td>Transmission:</td><td><input type="checkbox" class="truck" id="transmission"></td></tr>
</table>
</div>
<div id="19" class="part">
<table>
<tr><td>Trip Recorder:</td><td><input type="checkbox" class="truck" id="triprecorder"></td></tr>
<tr><td>Wheels and Rims</td><td><input type="checkbox" class="truck" id="wheelsandrims"></td></tr>
<tr><td>Windows</td><td><input type="checkbox" class="truck" id="windows"></td></tr>
<tr><td>Windshield Wipers:</td><td><input type="checkbox" class="truck" id="windshieldwipers"></td></tr>
<tr><td>Other:</td><td><input type="checkbox" class="truck" id="other"></td></tr>
</table>
</div>
<div id="20" class="part">Remarks:<br><input type="text" id="truckremarks"></div>
<div id="21" class="part"><h3>Trailer Inspection</h3></div>
<div id="22" class="part">Trailer Number:<br><input type="number" id="trailernumber"><br><h6>(if no trailer, click next)</h6></div>
</div>
<div id="btns"><input type="button" id="back" onclick="nextPrev(-1)" value="<< Back"><input type="button" id="next" onclick="nextPrev(1);" value="Next >>"></div>
</body>
<script>
var part = $('.part')
var currentPart = 0;
checkButtons();
var isSwiping = false;
function startSwipe(){
if (isSwiping){
return false;
}
else {
isSwiping = true;
$('#back, #next').attr('disabled',true);
return true;
}
}
function endSwipe(){
$('#back, #next').removeAttr('disabled');
isSwiping = false;
}
function nextPrev(n){
if (startSwipe()){//this doesn't work when swiping with startSwipe(), but buttons still work
if (n === 1){
if (currentPart !== part.length-1){
$('#'+currentPart).filter(':not(:animated)').animate({'left':'-5000px'},500,function(){
$(this).css({'left':'-5000px'});//set current left
});//move current left
$('#'+(currentPart+n)).delay(200).filter(':not(:animated)').animate({'left':'0'},500,function(){
$(this).css({'left':'0'});//set next centered
currentPart = currentPart + n;
checkButtons();
endSwipe();
});//move next right
}
}
if (n === -1){
if (currentPart !==0){
$('#'+currentPart).filter(':not(:animated)').animate({'left':'5000px'},500,function(){
$('#'+currentPart).css({'left':'5000px'});//set current right
});//move current left
$('#'+(currentPart+n)).delay(200).filter(':not(:animated)').animate({'left':'0'},500,function(){
$('#'+(currentPart+n)).css({'left':'0'});//set next centered
currentPart = currentPart + n;
checkButtons();
endSwipe();
});//move next right
}
}
}
}
function checkButtons(){
if (currentPart == 0){
$('#back').css({'display':'none'});
}
else if (currentPart == part.length-1){
$('#next').css({'display':'none'});
}
else {
$('#back').css({'display':'block'});
$('#next').css({'display':'block'});
}
}
document.getElementById('form').addEventListener('touchstart', handleTouchStart, false);
document.getElementById('form').addEventListener('touchmove', handleTouchMove, false);
document.getElementById('form').addEventListener('touchend', handleTouchEnd, false);
var xDown = null;
var yDown = null;
function getTouches(evt) {
return evt.touches || // browser API
evt.originalEvent.touches; // jQuery
}
function handleTouchStart(evt) {
if (startSwipe()){
const firstTouch = getTouches(evt)[0];
xDown = firstTouch.clientX;
yDown = firstTouch.clientY;
}
};
function handleTouchMove(evt) {
if (isSwiping){
if ( ! xDown || ! yDown ) {
return;
}
var xUp = evt.touches[0].clientX;
var yUp = evt.touches[0].clientY;
var xDiff = xDown - xUp;
var yDiff = yDown - yUp;
if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/
if ( xDiff > 0 ) {
nextPrev(1);
} else {
nextPrev(-1);
}
}
/* reset values */
xDown = null;
yDown = null;
}
};
function handleTouchEnd(evt) {
endSwipe();
};
</script>
</html>
更新:ariel 的解决方案很好,虽然它没有解决我的问题。这种标记很重要,我的代码应该已经配备了它。我仍然遇到问题,尽管我在这里发现了一些有希望的东西:https://css-tricks.com/full-jquery-animations/ 虽然它没有完全解决我的问题,但它已经非常接近解决方案了,我会在有解决方案时更新。
您需要使用标志来防止在动画发生时触发事件:
var isSwiping = false;
function startSwipe() {
if (isSwiping) {
return false;
} else {
isSwiping = true;
$("button#back, button#next").attr("disabled", true);
return true;
}
}
function endSwipe() {
$("button#back, button#next").removeAttr("disabled");
isSwiping = false;
}
function nextPrev(n) {
if (startSwipe()) {
...
// Inside animate callback:
endSwipe();
...
}
...
document.getElementById('form').addEventListener('touchstart', handleTouchStart, false);
document.getElementById('form').addEventListener('touchmove', handleTouchMove, false);
document.getElementById('form').addEventListener('touchend', handleTouchEnd, false);
...
function handleTouchStart(evt) {
if (startSwipe()) {
...
}
};
function handleTouchMove(evt) {
if (isSwiping) {
...
}
};
function handleTouchEnd(evt) {
endSwipe();
};