jquery 为什么我的按钮只在“each”循环结束时更新?

jv2fixgn  于 2022-11-29  发布在  jQuery
关注(0)|答案(3)|浏览(89)

我试图弄清楚为什么/如何在“each”循环之前更新按钮文本,这样我就可以在它运行时向用户提供反馈...但它似乎只有在“each”循环完成后才更新。
在我的例子中,按钮将去“更新,请等待...”后,每一个运行。所以,如果它需要10秒,按钮保持启用和文字“更新”(原始值)。我希望它被禁用,并显示“更新,请等待...”,而循环(每一个)正在运行。
知道为什么吗?

$("#UpdateRFID").click(function() {
    $('#UpdateRFID').prop("disabled", true).prop("value", "Updating please wait...");
    UpdateRFID();
    //$('#UpdateRFID').prop("disabled", false).prop("value", "Update");
  });

  function UpdateRFID() {
    $('.skurow[submitted="0"]').each(function() {
      sku = $(this).attr('sku');
      $.ajax({
        url: 'class.action.php',
        type: 'post',
        async: false,
        dataType: 'JSON',
        data: {
          "action": "GetDataFromTagID",
          "tagid": sku
        },
        success: function(response) {
          console.log('ok');
        },
        error: function(response) {
          console.log(response.responseText);
        }
      });
    });
  }

按钮:

<input class="MenuButton" name="UpdateRFID" id="UpdateRFID" value="Update" type="button" />

这是我做的另一个测试。在这个例子中,当我点击按钮,我得到一个警告“开始”,然后它等待大约3秒(睡眠在PHP代码测试),然后我得到警告“完成”,然后按钮被禁用,并更改为“Recherche..."。我不知道为什么...我希望它在“每个”开始之前被禁用。

function UpdateRFID() {
    $("#UpdateRFID").prop("disabled", true).prop("value", "Recherche ...");
    alert("Start");

    $('.skurow[submitted="0"]').each(function () {
      sku = $(this).attr("sku");
      $.ajax({
        url: "class.action.php",
        type: "post",
        async: false,
        dataType: "JSON",
        data: {
          action: "GetDataFromTagID",
          tagid: sku,
        },
        success: function (response) {
          console.log("ok");
        },
        error: function (response) {
          console.log(response.responseText);
        },
      });
    });

    alert("Done");
    //$('#UpdateRFID').prop("disabled", false).prop("value", "Mise a jour nom RFID");
  }

以下是重现该问题的完整独立代码:jQuery是2.2.1,PHP是5.4(但我认为这并不相关)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="includes/jquery.min.js"></script>
    <title>Document</title>
</head>

<body>

    <p class="ScanText">SKU</p> <input class="FullSizeBox" type="text" id="SKU" name="SKU" onclick="BoxSelect(this.id);" />
    <script type="text/javascript">
        $('#SKU').focus();
    </script>

    <br><input class="MenuButton" name="UpdateRFID" id="UpdateRFID" value="Mise a jour nom RFID" type="button" />

    <div id="qtsku" style="margin-left:5px">-</div>

    <div id="divSKUScanned">
        <table id="ScannedSKU">
            <thead>
                <tr>
                    <th></th>
                    <th></th>
                </tr>
            </thead>
            <tbody>
                <!-- updated by JavaScript -->
            </tbody>
        </table>

    </div>

    <div class="ScanSubmit"><input class="MenuButton" id="btnsubmit" type="button" value="Soumettre" onclick="SubmitVE();" disabled></div>

    <script>
        function SkuCount() {
            skucount = $('#ScannedSKU tr').length - 1;
            stritem = 'item';
            if (skucount > 1) {
                stritem = 'items';
            }
            $('#qtsku').html('Total ' + stritem + ': ' + skucount);
            if (skucount == 0) {
                $('#qtsku').html('');
            }
        }
        SkuCount();

        $(document.body).on('click', '.delButton', function() {
            sku = $(this).closest("tr").find('.skudesc').text();
            r = confirm('Effacer ' + sku + ' ?');
            if (r == true) {
                $(this).closest("tr").remove();
            }
            SkuCount();
            $('#SKU').focus(); //TODO: That Focus dosent work...
        });

        $('#SKU').keypress(function(event) {
            keycode = (event.keyCode ? event.keyCode : event.which);
            if (keycode == '13') {
                sku = this.value;
                sku.trim();
                this.value = "";
                if (sku != "") {
                    if (!($('.skurow[sku="' + sku + '"').length)) {
                        delBtn = '<input name="delButton" id="delButton" class="delButton" type="button" value="X" style="background-color:gray; color:black">';
                        $('#ScannedSKU > tbody:last-child').append('<tr class="skurow" submitted="0" sku="' + sku + '"><td class="delbtn">' + delBtn + '</td><td class="skudesc">' + sku + '</td></tr>');
                        $("#btnsubmit").prop("disabled", true);
                        SkuCount();
                    }
                }
            }
        });

        $("#UpdateRFID").click(function() {
            UpdateRFID();
        });

        function UpdateRFID() {
            $('#UpdateRFID').prop("disabled", true).prop("value", "Recherche ...");
            alert('Start');

            $('.skurow[submitted="0"]').each(function() {
                sku = $(this).attr('sku');
                $.ajax({
                    url: 'class.action.php',
                    type: 'post',
                    async: false,
                    dataType: 'JSON',
                    data: {
                        "action": "GetDataFromTagID",
                        "tagid": sku
                    },
                    success: function(response) {
                        console.log('ok');
                    },
                    error: function(response) {
                        console.log(response.responseText);
                    }
                });
            });

            alert('Done');
            //$('#UpdateRFID').prop("disabled", false).prop("value", "Mise a jour nom RFID");
        }
    </script>

</body>

</html>

这是php页面的一部分,用于class. action. php

<?php
if ($_POST["action"] == "GetDataFromTagID") {
sleep(3);
}
?>
osh3o9ms

osh3o9ms1#

你所拥有的可能会起作用;或者可以不随时间变化。
你应该做的是使用一个Promise,在所有的循环和 AJAX 完成后,你可以解决这个问题。
这不是一个经过测试的解决方案,也不是一个超级可靠的解决方案。我确实添加了一些东西,比如如何基于自定义事件触发器启用和禁用按钮,如何在函数UpdateRFID中 Package Promise等。
我删除了onclick="BoxSelect(this.id);",因为看到点击文本输入是很奇怪的,而且它在代码中并不存在;而且,您可以在JavaScript代码中添加一个单击处理程序(更好),使用$('#SKU').on('click',function(){BoxSelect(this.id);});
我确实看到了很多其他的事情,我可能会改变,但只是承诺是你需要在这里关注的。
第一个

fae0ux8s

fae0ux8s2#

更新#4:修补这是工作,但最终的解决方案是在更新#5。
感谢@freedomn-m,我只添加了一个小的超时,它修复了它。希望我可以做“更新按钮,然后这样做”,但如果它是这样工作,我可以接受它!

$("#UpdateRFID").click(function() {
    $('#UpdateRFID').prop("disabled", true).prop("value", "Recherche ...");
    setTimeout(UpdateRFID, 100);
  });

请注意,setTimeout(UpdateRFID(), 100);不起作用。不知道为什么。

jm2pwxwz

jm2pwxwz3#

更新#5:已解决
这是我的最终代码。我设法使用函数$.when来运行我所有 AJAX 请求,然后执行操作。现在我的按钮正确更新,我也设法获得更好的async: false。我的页面更新每次“ajax”调用被解决,并在所有ajax调用结束时(完成或失败),我重新启用按钮。
谢谢这里所有的帮助。帮助我走上正确的方向

function UpdateRFID() {
    $('#UpdateRFID').trigger("disable-me");

    const UpdateRFIDajaxes = [];

    $('.skurow[submitted="0"]')
      .each(function() {
        sku = $(this).attr('sku');
        const skuData = {
          "action": "GetDataFromTagID",
          "tagid": sku
        };
        UpdateRFIDajaxes.push(
          $.ajax({
            url: 'class.action.php',
            type: 'post',
            dataType: 'JSON',
            data: skuData
          })
          .done(function(response) {
            //do ok stuff.
           console.log('ok')
          })
          .fail(function(response) {
            //do failed stuff.
            console.log('failed');
          })
        );
      });
    $.when.apply($, UpdateRFIDajaxes)
      .always(function() {
        $('#UpdateRFID').trigger("enable-me");
        EnableSubmit();
        $('#SKU').focus();
      }).done(function() {
        //console.log('Done.');
      })
      .fail(function() {
        alert('Erreur, ca ne fonctionne pas, etes vous sur le WiFi?');
      });
  }

  $("#UpdateRFID")
    .on('click', function() {
      UpdateRFID();
    })
    .on('enable-me', function() {
      $(this).prop("disabled", false).prop("value", "Mise a jour nom RFID");
    }).on('disable-me', function() {
      $(this).prop("disabled", true).prop("value", "Recherche ...");
    });

相关问题