jquery 进度条在 AJAX 表单输出中不起作用?

7cwmlq89  于 2023-08-04  发布在  jQuery
关注(0)|答案(2)|浏览(107)

我有一个简单的 AJAX 表单。但是进度条在 AJAX 表单输出上不起作用,它会冻结。我在页面上放了一个例子,这样你就可以看到它正常工作。我的目标是能够提供代码(进度条)在这里 AJAX 输出。https://stackoverflow.com/a/35985771/20310847
这里的问题是,我相信在 AJAX 输出中检查进度条的脚本和ajax之间存在冲突/冲突。它出现了,当它完成时,它消失了,但没有视觉上的进展...我想知道我需要做些什么来使 AJAX 输出的进度条看起来正常而不冻结?
Form.htm

<html>
<head>
    <!-- progress bar style  start -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
    .progress,
    .alert {margin: 8px;}   
    .alert {display: none;} 
    .alert-success {
        --bs-alert-color: #2c4238;
        --bs-alert-bg: #f8faff;
        --bs-alert-border-color: #768478;
        width: auto;
        max-width: max-content;
    }   
    @media screen and (max-width: 1568px) {
        .alert-success {
            width: auto;
            max-width: max-content;
        }
    }
    </style>
</head>
<!-- progress bar style  end -->

<body><br>
    <!-- form start -->
    <script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
    <form class="form" action="process.php" method="POST" name="checkaddress" id="checkaddress">
    <input type="text" name="v" /> </td><input type="submit" id="submit" value="Submit" /> 
    </form>
    <!-- form end -->
    
    <!-- ajax output div is here -->
    <div class="done"></div>
    
    <!-- Here is the progress code I want to reflect in the ajax output. start -->
    <br>====================================
    <br> Example: normally this code(progress bar) works below. but it doesn't work when I call the code with ajax. freezes as above.
    <br>
    <div class='progress col-md-7 ps-0 pe-0'>
        <div class='progress-bar' role='progressbar' aria-valuenow='60' aria-valuemin='0' aria-valuemax='100' style='width: 60%;'></div>
    </div>
    <div class='alert alert-success' role='alert'>hello xxxxx</div><br>
    <!-- end -->
    
    
    <!-- form ajax script start -->
    <script>
    $('#checkaddress').on('submit', function(e) {
        // get formdata in a variable that is passed to the ajax request
        var dataToPassToAjax = $(this).serialize();
        $.ajax({
            url: "process.php",
            type: "POST",
            data: dataToPassToAjax,
            cache: false,
            success: function(resultHtml) {
                // add the returned data to the .done element
                $('.done').html(resultHtml).fadeIn('slow');
            }
        });
        // cancel the default form submit
        return false;
    });
    </script>
    <!-- end -->
    
    <!-- progress bar script start -->
    <script>
    var $progress = $('.progress');
    var $progressBar = $('.progress-bar');
    var $alert = $('.alert');
    setTimeout(function() {
        $progressBar.css('width', '10%');
        setTimeout(function() {
            $progressBar.css('width', '30%');
            setTimeout(function() {
                $progressBar.css('width', '45%');
                setTimeout(function() {
                    $progressBar.css('width', '80%');
                    setTimeout(function() {
                        $progressBar.css('width', '90%');
                        setTimeout(function() {
                            $progressBar.css('width', '95%');
                            setTimeout(function() {
                                $progressBar.css('width', '98%');
                                setTimeout(function() {
                                    $progressBar.css('width', '99%');
                                    setTimeout(function() {
                                        $progressBar.css('width', '100%');
                                        setTimeout(function() {
                                            $progress.css('display', 'none');
                                            $alert.css('display', 'block');
                                        }, 500); // WAIT 5 milliseconds
                                    }, 500); // WAIT 5 milliseconds
                                }, 800); // WAIT 5 milliseconds
                            }, 600); // WAIT 2 seconds
                        }, 700); // WAIT 1 seconds
                    }, 900);
                }, 600); // WAIT 2 seconds
            }, 400); // WAIT 1 seconds
        }, 700); // WAIT 1 seconds
    }, 800); // WAIT 1 second
    </script>
    <!-- progress bar script end -->
</body>
</html>

字符串
process.php

<?php 
$v= $_POST['v'];
echo "<div class='progress col-md-7 ps-0 pe-0'> 
<div class='progress-bar' role='progressbar' aria-valuenow='60' aria-valuemin='0' 
aria-valuemax='100' style='width: 60%;'></div>  
</div>
<div class='alert alert-success' role='alert'>hello $v</div>";
?>

pwuypxnk

pwuypxnk1#

你的进度条在 AJAX 中不起作用,因为当页面第一次加载时,没有进度条可供使用--它只在AJAX调用后出现。当页面加载时,您的进度条脚本会立即运行,它会尝试访问.progress.progress-bar.alert元素,这些元素还不存在,因为它们只是在 AJAX 调用后才添加到页面中。
要使其工作,您应该将进度条脚本包含到 AJAX 调用的success函数中。这样,它将在新元素添加到页面后被调用。
下面是修改后的JavaScript代码:

$('#checkaddress').on('submit', function(e) {
    // get formdata in a variable that is passed to the ajax request
    var dataToPassToAjax = $(this).serialize();
    $.ajax({
        url: "process.php",
        type: "POST",
        data: dataToPassToAjax,
        cache: false,
        success: function(resultHtml) {
            // add the returned data to the .done element
            $('.done').html(resultHtml).fadeIn('slow');
            
            // run the progress bar script here
            var $progress = $('.progress');
            var $progressBar = $('.progress-bar');
            var $alert = $('.alert');
            setTimeout(function() {
                $progressBar.css('width', '10%');
                setTimeout(function() {
                    $progressBar.css('width', '30%');
                    setTimeout(function() {
                        $progressBar.css('width', '45%');
                        setTimeout(function() {
                            $progressBar.css('width', '80%');
                            setTimeout(function() {
                                $progressBar.css('width', '90%');
                                setTimeout(function() {
                                    $progressBar.css('width', '95%');
                                    setTimeout(function() {
                                        $progressBar.css('width', '98%');
                                        setTimeout(function() {
                                            $progressBar.css('width', '99%');
                                            setTimeout(function() {
                                                $progressBar.css('width', '100%');
                                                setTimeout(function() {
                                                    $progress.css('display', 'none');
                                                    $alert.css('display', 'block');
                                                }, 500); // WAIT 5 milliseconds
                                            }, 500); // WAIT 5 milliseconds
                                        }, 800); // WAIT 5 milliseconds
                                    }, 600); // WAIT 2 seconds
                                }, 700); // WAIT 1 seconds
                            }, 900);
                        }, 600); // WAIT 2 seconds
                    }, 400); // WAIT 1 seconds
                }, 700); // WAIT 1 seconds
            }, 800); // WAIT 1 second
        }
    });
    // cancel the default form submit
    return false;
});

字符串
这应该可以解决您的问题。在 AJAX 调用成功后,进度条脚本现在将运行,新元素将添加到DOM中,因此它应该能够按预期找到并操作它们。

改进

当前的JavaScript代码包含了很多嵌套的setTimeout函数,这使得它很难阅读和维护。我们可以用更动态和模块化的方法来简化它。
考虑一下这样的情况:

$('#checkaddress').on('submit', function(e) {
    // get formdata in a variable that is passed to the ajax request
    var dataToPassToAjax = $(this).serialize();
    $.ajax({
        url: "process.php",
        type: "POST",
        data: dataToPassToAjax,
        cache: false,
        success: function(resultHtml) {
            // add the returned data to the .done element
            $('.done').html(resultHtml).fadeIn('slow');
            
            // run the progress bar script here
            var $progress = $('.progress');
            var $progressBar = $('.progress-bar');
            var $alert = $('.alert');
            
            var width = 0;
            var increment = 10; // change the increment value to control the speed of the progress bar
            var interval = setInterval(function() {
                width = width + increment;
                if(width >= 100) { // when progress reaches 100, stop interval and show alert
                    clearInterval(interval);
                    $progress.css('display', 'none');
                    $alert.css('display', 'block');
                }
                $progressBar.css('width', width + '%');
            }, 800); // this value controls the delay between each increment
        }
    });
    // cancel the default form submit
    return false;
});


在这里,进度条宽度每800毫秒增加10%,直到达到100%,此时将清除间隔并显示警报。
这种方法比我推荐的方法灵活性稍差,但更容易理解。如果你想给予一下,我个人会这样实现它。

async function delay(duration) {
    return new Promise(resolve => setTimeout(resolve, duration));
}

async function updateProgressBar($progressBar, $progress, $alert, values) {
    for(let i = 0; i < values.length; i++) {
        await delay(values[i].delay);
        $progressBar.css('width', `${values[i].width}%`);
    }
    $progress.css('display', 'none');
    $alert.css('display', 'block');
}

$('#checkaddress').on('submit', function(e) {
    // get formdata in a variable that is passed to the ajax request
    var dataToPassToAjax = $(this).serialize();
    $.ajax({
        url: "process.php",
        type: "POST",
        data: dataToPassToAjax,
        cache: false,
        success: function(resultHtml) {
            // add the returned data to the .done element
            $('.done').html(resultHtml).fadeIn('slow');
            
            // run the progress bar script here
            var $progress = $('.progress');
            var $progressBar = $('.progress-bar');
            var $alert = $('.alert');
            var values = [
                {width: 10, delay: 800},
                {width: 30, delay: 700},
                {width: 45, delay: 400},
                {width: 80, delay: 600},
                {width: 90, delay: 900},
                {width: 95, delay: 700},
                {width: 98, delay: 600},
                {width: 99, delay: 800},
                {width: 100, delay: 500}
            ];
            updateProgressBar($progressBar, $progress, $alert, values);
        }
    });
    // cancel the default form submit
    return false;
});


如果第二个例子太难理解,也不用担心。专注于让你的代码工作,并尝试留意代码重复。每当你重复很多代码时,可能有更好的方法来做。:)

kqqjbcuj

kqqjbcuj2#

1.我建议preventDefault()来阻止表单的提交,而不是返回false。如果在返回false之前出现错误,那么表单也会提交

$('#checkaddress').on('submit', function(e) { 
  e.preventDefault(); // stop the submission
  progress(0); /* my code */`
  /* rest of your code */

字符串
1.进度条从60%开始
1.您需要在提交时调用进度条
1.这是一个非常干燥的(干燥:Don't Repeat Yourself)进度代码
https://jsfiddle.net/mplungjan/r1hsom07/
我还建议你淡入淡出完成在进度条的末尾。

let $progress = $('.progress'),
 $progressBar = $('.progress-bar'),
 $alert = $('.alert'),
 steps = [
  { percent:  '10%', delay: 800}, 
  { percent:  '30%', delay: 700}, 
  { percent:  '45%', delay: 400}, 
  { percent:  '80%', delay: 600}, 
  { percent:  '90%', delay: 900}, 
  { percent:  '95%', delay: 700}, 
  { percent:  '98%', delay: 600}, 
  { percent:  '99%', delay: 800}, 
  { percent: '100%', delay: 500}, 
  { percent: 'none', delay: 500} 
];

const progress = i => {
  if (i >= steps.length) return;
  setTimeout(() => {
    if (steps[i].percent === 'none') {
      $progress.css('display', 'none');
      $alert.css('display', 'block');
    } else {
      $progressBar.css('width', steps[i].percent);
    }
    progress(i + 1);
  }, steps[i].delay);
}
progress(0); // Start (move this to your ajax)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<div class='progress col-md-7 ps-0 pe-0'>
        <div class='progress-bar' role='progressbar' aria-valuenow='60' aria-valuemin='0' aria-valuemax='100' style='width: 0%;'></div>
    </div>
    <div class='alert alert-success' role='alert'>hello xxxxx</div><br>

的数据

相关问题