繁体   English   中英

脚本只应运行一次就运行很多次

[英]script runs many times when it should only run once

我有一个令人困扰的问题,我花了很多时间试图解决这个问题,但没有运气。 我有一个用于从数据库中删除项目的表格。 这是表格: 编辑:我已经将代码更新为更合理的内容,但是我仍然遇到问题。

    <div id="tabs-3">
            <p>Select Replenish for Books that will be for sale again.<br/>Select Remove for Books that will NOT be for sale again.</p>
            <br/>
            <table>
            <tr>
                <td><input type="radio" name="returnType" value="replenish" checked>Replenish<br></td>
                <td><input type="radio" name="returnType" value="remove">Remove<br></td>
            </tr>
            <tr>
                <td>&nbsp</th>
                <td>&nbsp</th>
            </tr>
            <tr>
                <th>SKU</th>
                <th>Order ID</th>
                <th>Quantity</th>
                <th>Location</th>
            </tr>
            <?php $numberofrow = 10;?>
<!--create the for loop-->
<?php for($counter = 1;$counter<=$numberofrow;$counter++){ ?>
<!--create 1 row for repeating-->
            <tr>
                <td><input type="text" id="sku<?php echo   $counter;?>"/></td>
                <td><input type="text" id="order<?php echo $counter;?>"/></td>
                <td><input type="text" id="reEnterQty<?php echo $counter;?>"/></td>
                <td>
                    <select id="reEnterLocation<?php echo $counter;?>" name="reEnterLocation" class="Location">
                        <option value="">--Select Location--</option>
                        <?php
                        $query = "SELECT location_id, location FROM location ORDER BY location";
                        $result = $conn->query($query);
                        while ($row = $result->fetch_assoc()) {
                            echo '<option value="' . $row['location_id'] . '" >' . $row['location'] . '</option>';
                        }
                        ?>
                    </select>
                </td>
            </tr>
            <?php }?>
            </table>
            <br/>


            <br/>
            <input type="button" id="reEnterSKU" value="Process Returns" /> <br/>

            <div id="returnsNotice"></div>
        </div>

处理此问题的js是:

        $("#reEnterSKU").on('click', function() {

    if($("input[name=returnType]:checked").val() == "remove"){ //executes when Remove radio button is checked
        var arr = {};
        var counter = 0;

        for(var x=1;x<11;x++)
        {
            if($("#sku"+x).val() != "" && $("#order"+x).val() != ""){
            arr[x] ={sku: $("#sku"+x).val(), order: $("#order"+x).val(), quantity: $("#reEnterQty"+x).val()};   
            }
        }   
                $.ajax({
                    type: "POST",
                    async:false,
                    url: "invReturnsRemove.php",
                    dataType: "json",
                    data: {data: JSON.stringify(arr)},//({sku: $("#sku"+x).val(), order: $("#order"+x).val(), quantity: quantity}),
                    success: function(data){

                    }
                });



        $("#returnsNotice").html("<h3>" + x + " return(s) removed.</h3>");

invReturnsRemove.php是:

    <?php
require_once ('../db.php');
$conn = db_connect();
$n=0;

$data =json_decode($_POST['data'], true); 

foreach($data as $value){

$conn->query("UPDATE order_sold SET quantity = (quantity - {$data[$n]['quantity']}) WHERE sku = {$data[$n]['sku']} AND order_id = {$data[$n]['order']}");
$n++;}


$conn->close();
?>

问题是,当我尝试运行它时,即使只删除一条记录,它也会运行数百次。 知道我可能在做什么错了,以及如何解决?

您发表的评论表明,问题的至少一部分来自客户端。

您可能已经多次添加了'click'事件监听器。 如果添加事件侦听器的代码处于循环中,那么几乎可以肯定已经多次添加了它。 例如,如果您在页面上有多个表单,并以以下方式附加了侦听器,则每次按下“提交”按钮时,都会触发多次。

// THIS IS BAD
$('form').each(function() {
    $("#reEnterSKU").on('click', function(e) {
         // details of listener for form1
    });
    $("#reEnterSKU2").on('click', function(e) {
         // details of listener for form2
    });
    $("#reEnterSKU3").on('click', function(e) {
         // details of listener for form3
    });
});

当您使用与form上的button直接关联的事件侦听button时,您可能应该return false; 从事件监听器函数或调用e.preventDefault(); (您必须将e参数添加到点击侦听器函数中)以避免按钮提交form (也许您已经在执行类似的操作,但未包含代码?)我假设您不打算重定向页面,否则您将不会更新<div id="returnsNotice"></div>元素。

可能引起问题的另一件事是,用于查找按钮并将其添加到按钮的选择器的不够具体。 在这种情况下,您可能一次将事件侦听器添加到多个按钮,因此一个按钮可能最终具有多个事件侦听器。

另外,在使用表单时,我认为通常最好避免将事件侦听器附加到特定的表单元素(例如按钮)上,以触发提交,因为在各种提交场景中情况可能会变得复杂,例如用户按下enter文本输入字段具有焦点时按键。 另外,您可以使用jQuery.submit()方法,该方法附加在form元素上,并且应由会导致提交表单的任何情况触发。 这将允许您执行功能(提交侦听器)并以更高的可靠性暂停自动提交。 当您将required属性应用于表单元素( 详细信息兼容性 )时,这还将使您能够利用浏览器内置的表单验证功能。

$("#your-form-id").submit(function() {

    if($("input[name=returnType]:checked").val() === "remove") { //executes when Remove radio button is checked
        var arr = [];
        var counter = 0;

        for(var x = 1; x < 11; x++)
        {
            if( $("#sku"+x).val() !== "" && $("#order"+x).val() !== ""){
                arr[x] = {
                    sku: $("#sku"+x).val(), 
                    order: $("#order"+x).val(), 
                    quantity: $("#reEnterQty"+x).val()
                };   
            }
        }
        console.log('FORM SUBMIT');

        $.ajax({
            type: "POST",
            async:false,
            url: "invReturnsRemove.php",
            dataType: "json",
            data: {data: JSON.stringify(arr)},//({sku: $("#sku"+x).val(), order: $("#order"+x).val(), quantity: quantity}),
            success: function(data){
                console.log('SUCCESS'); // how many times do you see this per button click?
            }
        });

        $("#returnsNotice").html("<h3>" + x + " return(s) removed.</h3>");

        // ... anything that remains in your function
        return false;

关于如何解决该问题,我要做的第一件事是注释掉表单提交语句,以将其排除在等式之外。 然后,在其位置上添加console.log()语句以查看a)如果多次调用它,并且b)尝试弄清楚如何使其多次调用仅执行一次。 您还可以添加一个console.log()语句,该语句在添加click事件监听器时执行以确保仅添加一个click事件监听器。 我将这些更改包括在下面。

console.log('ADDING FORM SUBMISSION click listener -- you should only see this once.');

$("#reEnterSKU").on('click', function(e) {

    e.preventDefault();

    if($("input[name=returnType]:checked").val() === "remove") { //executes when Remove radio button is checked
        var arr = [];
        var counter = 0;

        for(var x = 1; x < 11; x++)
        {
            if( $("#sku"+x).val() !== "" && $("#order"+x).val() !== ""){
                arr[x] = {
                    sku: $("#sku"+x).val(), 
                    order: $("#order"+x).val(), 
                    quantity: $("#reEnterQty"+x).val()
                };   
            }
        }
        console.log('FORM SUBMIT');
        /* 
        $.ajax({
            type: "POST",
            async:false,
            url: "invReturnsRemove.php",
            dataType: "json",
            data: {data: JSON.stringify(arr)},//({sku: $("#sku"+x).val(), order: $("#order"+x).val(), quantity: quantity}),
            success: function(data){
                console.log('SUCCESS');
            }
        }).fail(function(data) {
            console.log('FAIL');
        });
        */
        $("#returnsNotice").html("<h3>" + x + " return(s) removed.</h3>");

我刚刚注意到的另一件事是arr变量实际上是Object ,而不是Array 不知道这是否会影响PHP。 而且,我注意到您以1的值开始x 这也意味着,在将arr创建为Array的情况下,您将拥有undefined第一个元素。

另外, counter是什么? 如果您基于此进行循环,则可能需要考虑一下。

作为解决麻烦的中间步骤,以下版本的JavaScript代码将取消在最近一次未阻止的提交后1.2秒内进行的所有提交调用。 建议您将其作为解决方案(这很令人沮丧),但是在解决存在问题的地方进行故障排除可能会有所帮助。

(function(undefined) { 
    if (window.blockSubmission === undefined) {
        window.blockSubmission = false;
    }
})();

$("#reEnterSKU").on('click', function() {

    // this will make sure your listener only gets called at most once every 1.2 seconds
    if (window.blockSubmission) {
        return false;
    } else {
        window.blockSubmission = true;
        setTimeout(function() { 
            window.blockSubmission = false;
        }, 1200);
    }

    if($("input[name=returnType]:checked").val() == "remove") { //executes when Remove radio button is checked
        var arr = [];
        var counter = 0;

        for(var x = 1; x < 11; x++)
        {
            if( $("#sku"+x).val() != "" && $("#order"+x).val() != ""){
                arr[x] = {
                    sku: $("#sku"+x).val(), 
                    order: $("#order"+x).val(), 
                    quantity: $("#reEnterQty"+x).val()
                };   
            }
        }
        console.log('FORM SUBMIT');

        $.ajax({
            type: "POST",
            async:false,
            url: "invReturnsRemove.php",
            dataType: "json",
            data: {data: JSON.stringify(arr)},//({sku: $("#sku"+x).val(), order: $("#order"+x).val(), quantity: quantity}),
            success: function(data){
                console.log('SUCCESS'); // how many times do you see this per button click?
            }
        });

        $("#returnsNotice").html("<h3>" + x + " return(s) removed.</h3>");

如果那不能解决您的问题,您可能需要详细说明问题。 包括其他代码将很有帮助。 也许更长的PHP / HTML摘录至少会显示整个form元素。 此外,包括更全面的JavaScript摘录也可能会有所帮助。 例如,在您的帖子提供的摘录中,表单提交按钮的click事件侦听器永远不会关闭。 这使得很难看到实际情况。

如果您要编写大量的JS,那么可能值得一读。 它有些陈旧,但这是浏览器调试工具的精彩介绍:

http://jtaby.com/2012/04/23/modern-web-development-part-1.html

没有看到完整的上下文,我猜测是某些重复触发了点击。 这个小技巧可以解决:

var e = false;
$("#reEnterSKU").on('click', function() {
    if (e) return;

    if ($("input[name=returnType]:checked").val() == "remove") { //executes when Remove radio button is checked
        e = true;
        var arr = {};
        var counter = 0;

        for(var x=1;x<11;x++)
        {
            if ($("#sku"+x).val() != "" && $("#order"+x).val() != "") {
                arr[x] ={sku: $("#sku"+x).val(), order: $("#order"+x).val(), quantity: $("#reEnterQty"+x).val()};   
            }
        }  

        $.ajax({
            type: "POST",
            async:false,
            url: "invReturnsRemove.php",
            dataType: "json",
            data: {data: JSON.stringify(arr)},//({sku: $("#sku"+x).val(), order: $("#order"+x).val(), quantity: quantity}),
            success: function(data) {}
        });

        $("#returnsNotice").html("<h3>" + x + " return(s) removed.</h3>");
        e = false;
    }
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM