我的ajax请求提交一次,然后两次,然后提交4次并保持加倍

时间:2016-03-01 17:51:01

标签: javascript jquery ajax

我在底部有下一个和上一个按钮的标签,当我第一次加载页面ajaxloads数据到标签一,当我点击下一个表格将提交罚款,但如果我按下前一个后按下它'拉另一个ajax填充第一次潜水,就像我在加载时一样,但当我点击下一步提交表格时,ajax请求加倍并提交两次,然后4次8等,我怎么能阻止这种情况发生.. ..我的jquery在我的一个页面上是相同的:

$(document).on("click",".previous", function()
{
    $.ajax({
        url: '<?php echo Config::get('URL'); ?>wizzard/personal_information',
        type: 'GET',
        success: function(data){
            $('#tab2').html('');
            $('#tab2').removeClass('active');
            $('.tab_2').removeClass('active');
            $('#tab1').html(data);
            $('#tab1').addClass('active');
            $('.tab_1').addClass('active');
        }
    });
});

$(document).on("click",".next", function()
{
    $('#update_contact_information').on("submit", function()
    {

        $.ajax({
            url: $(this).attr('action'),
            type: $(this).attr('method'),
            dataType: 'json',
            data: $(this).serialize(),
            success: function(data){
                if(!data.success){
                    $.notify(data.error,{
                        className:'error',
                        clickToHide: true,
                        autoHide: true,
                        globalPosition: 'bottom right'
                    });

                    $.ajax({
                        url: '<?php echo Config::get('URL'); ?>wizzard/employment_history',
                        type: 'GET',
                        success: function(data){
                            $('#tab2').removeClass('active');
                            $('.tab_2').removeClass('active');
                            $('#tab2').html('');
                            $('#tab3').html(data);
                            $('#tab3').addClass('active');
                            $('.tab_3').addClass('active');
                        }
                    });
                }else{
                    $.notify(data.success,{
                        className:'success',
                        clickToHide: true,
                        autoHide: true,
                        globalPosition: 'bottom right'
                    });
                    $.ajax({
                        url: '<?php echo Config::get('URL'); ?>wizzard/employment_history',
                        type: 'GET',
                        success: function(data){
                            $('#tab2').html('');
                            $('#tab2').removeClass('active');
                            $('.tab_2').removeClass('active');
                            $('#tab3').html(data);
                            $('#tab3').addClass('active');
                            $('.tab_3').addClass('active');
                        }
                    });
                }
            }
        });
        return false;
    });

    $('#update_contact_information').trigger('submit');
});

我的标签:

    <div class="panel-body">
        <div id="rootwizard">
                <div class="navbar">
                  <div class="navbar-inner">
                    <div class="container">
                <ul class="nav nav-pills">
                    <li class="active tab_1"><a href="#tab1" data-toggle="tab"><?php echo System::translate("Personal information"); ?></a></li>
                    <li class="tab_2"><a href="#tab2" data-toggle="tab"><?php echo System::translate("Contact information"); ?></a></li>
                    <li class="tab_3"><a href="#tab3" data-toggle="tab"><?php echo System::translate("Employment history"); ?></a></li>
                    <li class="tab_4"><a href="#tab4" data-toggle="tab"><?php echo System::translate("Qualification history"); ?></a></li>
                    <li class="tab_5"><a href="#tab5" data-toggle="tab"><?php echo System::translate("Avatar"); ?></a></li>
                </ul>
                 </div>
                  </div>
                </div>
                <div class="tab-content">
                    <div class="tab-pane active" id="tab1">

                    </div>
                    <div class="tab-pane" id="tab2">

                    </div>
                    <div class="tab-pane" id="tab3">

                    </div>
                    <div class="tab-pane" id="tab4">

                    </div>
                    <div class="tab-pane" id="tab5">

                    </div>
                    <ul class="pager wizard">
                        <li class="previous"><a href="javascript:;"><?php echo System::translate("Previous"); ?></a></li>
                        <li class="next"><a href="javascript:;"><?php echo System::translate("Next"); ?></a></li>
                    </ul>
                </div>  
            </div>

和初次通话:

<script>
$(function(){

    $.ajax({
        url: '<?php echo Config::get('URL'); ?>wizzard/personal_information',
        type: 'GET',
        success: function(data){
            $('#tab1').html(data);
        }
    });
});
</script>

8 个答案:

答案 0 :(得分:8)

每次单击按钮时,都会将新的提交事件绑定到表单,这就是为什么它会加倍。从clickk处理程序

中删除绑定
$(document).on("click",".next", function()
{

    $('#update_contact_information').trigger('submit');
});

$(document).on("submit", '#update_contact_information', function()
{

    $.ajax({
        url: $(this).attr('action'),
        type: $(this).attr('method'),
        dataType: 'json',
        data: $(this).serialize(),
        success: function(data){
            if(!data.success){
                $.notify(data.error,{
                    className:'error',
                    clickToHide: true,
                    autoHide: true,
                    globalPosition: 'bottom right'
                });

                $.ajax({
                    url: '<?php echo Config::get('URL'); ?>wizzard/employment_history',
                    type: 'GET',
                    success: function(data){
                        $('#tab2').removeClass('active');
                        $('.tab_2').removeClass('active');
                        $('#tab2').html('');
                        $('#tab3').html(data);
                        $('#tab3').addClass('active');
                        $('.tab_3').addClass('active');
                    }
                });
            }else{
                $.notify(data.success,{
                    className:'success',
                    clickToHide: true,
                    autoHide: true,
                    globalPosition: 'bottom right'
                });
                $.ajax({
                    url: '<?php echo Config::get('URL'); ?>wizzard/employment_history',
                    type: 'GET',
                    success: function(data){
                        $('#tab2').html('');
                        $('#tab2').removeClass('active');
                        $('.tab_2').removeClass('active');
                        $('#tab3').html(data);
                        $('#tab3').addClass('active');
                        $('.tab_3').addClass('active');
                    }
                });
            }
        }
    });
    return false;
});

答案 1 :(得分:3)

在之前的两个回答中,人们(正确地)建议您重构代码,以避免在另一个事件处理程序中注册事件处理程序。然而,由于你不接受这些答案,我认为这并没有完全回答这个问题。

您要做的是在点击&#34; next&#34;时简单地提交表单的内容。按钮。同时,此按钮不是表单的一部分,因此只需单击它就不会触发&#34;提交&#34;事件。所以你手动触发事件。

现在您的描述中有些奇怪的是,您的ajax请求在每次点击时都会加倍。通常情况下,每次点击您都会再添加一个请求。请参阅我的小提琴here,这是您的代码的简化版本。

var form = $('form');

$(document).on('click', '.next', function(){
  form.on('submit', function() {//with every click one more handler is registered. Click the "click" link several times to see
      alert('submit fired'); 
      return false;
  });
  form.trigger('submit')
})

因此,问题就出现了:你在哪里用$(document).on("click",".next", function()注册你的处理程序?您需要确保此处理程序仅注册一次。为此,您可以在代码中将alert('registering handler')放在代码前面以进行检查。 注册事件处理程序的正确顺序显示在此modified fiddle中。代码是:

var form = $('form');

$(document).on('click', '.next', function(){

  form.trigger('submit')
})
form.on('submit', function() {//with every click one more handler is registered. Click the "click" link several times to see
  alert('submit fired'); 
  return false;
});

所以,为了继续,你可以尝试我的建议并让我知道结果吗?

P.S。我不确定为什么你需要触发表单提交。对于您的ajax请求,您正在序列化表单并取消初始提交(您return false;)。因此,我建议避免使用&#34;提交&#34;事件,只是为了完成所有的工作&#34;点击&#34;处理程序。

更新(在以下评论中添加更多信息后)

所以问题的第二部分是如下。随着每一个&#34; next&#34;单击您正在附加新事件侦听器,并且您正在替换选项卡的html,如$('#tab2').html(data);data不仅包含标记,还包含插入时正在执行的js代码(btw,我不知道它是这样的,它很好)。我认为你期待的是,一旦删除了标记(html),相应的事件监听器也将被删除。但实际情况并非如此。为什么?因为您委派您的活动正在使用以下代码开头的document收听:

$(document).on("click",".next", function()

此处$(document)是您将听众附加到的内容。我强烈建议您查看this original jquery explanation of event delegation,而不是详细说明。

那么你如何解决它?有几种不同的方式。可能最简单的一个(最少量的代码编辑)是在执行.html(data)之前删除事件监听器。另一种方式,也很简单,就是写

$('.next').on("click", function(), 

正如您在qualification_history.php中所做的那样。这样,您将事件附加到元素本身,而不是文档。唯一的事情是你要确保在执行此代码之前有一个相应的DOM元素(所以你可以在标记后放置代码)。

答案 2 :(得分:2)

在不知道所涉及页面的完整html的情况下,有一些猜测。 OP中的代码结构不正确,并且存在其他逻辑错误。简而言之,问题是您已经定义了一个事件处理程序来添加事件处理程序。

$('#update_contact_information').on("submit", function(){...})放在$(document).on("click",".next", function(){...})的处理程序定义中,您说:

每次我点击类next的按钮时,我都想为我的元素update_contact_information创建一个新的事件处理程序。因此,当您第一次点击next时,您会定义然后触发submit。第二次单击next时,已经存在提交的现有处理程序,另外还添加了另一个处理程序。

由于您没有提供所涉及的其余HTML和JavaScript,因此不清楚代码的存在位置。可能还有其他问题。

我会重构JavaScript,将jQuery中的所有事件处理程序放在页面的就绪函数中。这允许您定义一次事件处理程序,并仍然进行初始调用以加载页面。

这样的事情:

$(function() {
  $(document).on("click", ".previous", function() {
    $.ajax({
      url: '<?php echo Config::get('
      URL '); ?>wizzard/personal_information',
      type: 'GET',
      success: function(data) {
        $('#tab2').html('');
        $('#tab2').removeClass('active');
        $('.tab_2').removeClass('active');
        $('#tab1').html(data);
        $('#tab1').addClass('active');
        $('.tab_1').addClass('active');
      }
    });
  });

  $('#update_contact_information').on("submit", function() {
    $.ajax({
      url: $(this).attr('action'),
      type: $(this).attr('method'),
      dataType: 'json',
      data: $(this).serialize(),
      success: function(data) {
        if (!data.success) {
          $.notify(data.error, {
            className: 'error',
            clickToHide: true,
            autoHide: true,
            globalPosition: 'bottom right'
          });

          $.ajax({
            url: '<?php echo Config::get('
            URL '); ?>wizzard/employment_history',
            type: 'GET',
            success: function(data) {
              $('#tab2').removeClass('active');
              $('.tab_2').removeClass('active');
              $('#tab2').html('');
              $('#tab3').html(data);
              $('#tab3').addClass('active');
              $('.tab_3').addClass('active');
            }
          });
        } else {
          $.notify(data.success, {
            className: 'success',
            clickToHide: true,
            autoHide: true,
            globalPosition: 'bottom right'
          });
          $.ajax({
            url: '<?php echo Config::get('
            URL '); ?>wizzard/employment_history',
            type: 'GET',
            success: function(data) {
              $('#tab2').html('');
              $('#tab2').removeClass('active');
              $('.tab_2').removeClass('active');
              $('#tab3').html(data);
              $('#tab3').addClass('active');
              $('.tab_3').addClass('active');
            }
          });
        }
      }
    });
    return false;
  });

  $(document).on("click", ".next", function() {
    $('#update_contact_information').trigger('submit');
  });

  $.ajax({
    url: '<?php echo Config::get('
    URL '); ?>wizzard/personal_information',
    type: 'GET',
    success: function(data) {
      $('#tab1').html(data);
    }
  });
});

根据您网页的其他HTML和JavaScript代码,这可能会或可能不会对您有效。我正在提供一个演示类似行动的小提琴。它不是原始帖子的精确副本,因为该示例不起作用的逻辑。它应该是一个充分的起点:

  1. 解决现有的多事件绑定问题
  2. 为您提供更好的解决原始示例中的逻辑问题的地方
  3. Here is the fiddle

答案 3 :(得分:1)

这应该帮助与您的活动的顺序和逻辑

//bind only when the doc has rendered...
$(document).ready(function() {

    //bind click to and element with class previous
    $(".previous").on("click", function()
    {
        //... previous code
        alert("test me ;-)");
    }

    //bind click to and element with class next
    $(".next").on("click", function()
    {
        //... next code.
        alert("test me ;-)");
    }

}

答案 4 :(得分:0)

我认为元素女巫id #update_contact_information在开头并不存在。您想绑定.next点击的活动。所以,我建议您在元素显示之前使用$.delegate来绑定事件。 更多信息,请参阅.delegate()

e.g。

$(document).delegate('#update_contact_information','submit', function(){
    $.ajax({
        url: $(this).attr('action'),
        type: $(this).attr('method'),
        dataType: 'json',
        data: $(this).serialize(),
        success: function(data){
            if(!data.success){
                $.notify(data.error,{
                    className:'error',
                    clickToHide: true,
                    autoHide: true,
                    globalPosition: 'bottom right'
                });

                $.ajax({
                    url: '<?php echo Config::get('URL'); ?>wizzard/employment_history',
                    type: 'GET',
                    success: function(data){
                        $('#tab2').removeClass('active');
                        $('.tab_2').removeClass('active');
                        $('#tab2').html('');
                        $('#tab3').html(data);
                        $('#tab3').addClass('active');
                        $('.tab_3').addClass('active');
                    }
                });
            }else{
                $.notify(data.success,{
                    className:'success',
                    clickToHide: true,
                    autoHide: true,
                    globalPosition: 'bottom right'
                });
                $.ajax({
                    url: '<?php echo Config::get('URL'); ?>wizzard/employment_history',
                    type: 'GET',
                    success: function(data){
                        $('#tab2').html('');
                        $('#tab2').removeClass('active');
                        $('.tab_2').removeClass('active');
                        $('#tab3').html(data);
                        $('#tab3').addClass('active');
                        $('.tab_3').addClass('active');
                    }
                });
            }
        }
    });
    return false;
});

答案 5 :(得分:0)

根据我的评论

$(document).on("click",".previous", function(){
    $.ajax({
        url: '<?php echo Config::get('URL'); ?>wizzard/personal_information',
        type: 'GET',
        success: function(data){
            $('#tab2').html('');
            $('#tab2').removeClass('active');
            $('.tab_2').removeClass('active');
            $('#tab1').html(data);
            $('#tab1').addClass('active');
            $('.tab_1').addClass('active');
       }
    });
});

$(document).on("click",".next", function(){
    /* Submit binding code from here moved just after this block. */
    $('#update_contact_information').trigger('submit');
});

/* submit binding code from above block */
$('#update_contact_information').on("submit", function(){
    $.ajax({
        url: $(this).attr('action'),
        type: $(this).attr('method'),
        dataType: 'json',
        data: $(this).serialize(),
        success: function(data){
            if(!data.success){
                $.notify(data.error,{
                    className:'error',
                    clickToHide: true,
                    autoHide: true,
                    globalPosition: 'bottom right'
                });

                $.ajax({
                    url: '<?php echo Config::get('URL'); ?>wizzard/employment_history',
                    type: 'GET',
                    success: function(data){
                        $('#tab2').removeClass('active');
                        $('.tab_2').removeClass('active');
                        $('#tab2').html('');
                        $('#tab3').html(data);
                        $('#tab3').addClass('active');
                        $('.tab_3').addClass('active');
                    }
                });
            }else{
                $.notify(data.success,{
                    className:'success',
                    clickToHide: true,
                    autoHide: true,
                    globalPosition: 'bottom right'
                });
                $.ajax({
                    url: '<?php echo Config::get('URL'); ?>wizzard/employment_history',
                    type: 'GET',
                    success: function(data){
                        $('#tab2').html('');
                        $('#tab2').removeClass('active');
                        $('.tab_2').removeClass('active');
                        $('#tab3').html(data);
                        $('#tab3').addClass('active');
                        $('.tab_3').addClass('active');
                    }
                });
            }
        }
    });
    return false;
});

答案 6 :(得分:0)

这个问题对于Google几乎是不可能的,因此我将在此处添加一些搜索词:
 每个提交后,Asp.net MVC Ajax.BeginForm()都会导致指数回发。

我知道这个问题不是关于MVC的,但我找不到其他问题来发布解决方案。
如果找到一个,请用链接发表评论。谢谢。

解决方案:
对我来说,我已经在部分视图(或我的<script>的元素)中包含了UpdateTargetID标签。
我认为脚本是在每次回发时发送过来的,并堆积在客户端/ Web浏览器上。
使我感到不寒而栗,但我将脚本移到 Ajax.BeginForm()之外后,重复的回发/提交就停止了。

我应该注意,这个特定的脚本在经过一定时间间隔后正在启动提交,这可以解释为什么我在添加到UpdateTargetID内的其他脚本之前没有注意到这种行为。

答案 7 :(得分:0)

我每次点击都收到两次请求,这使每次获取的应用程序变慢 您所做的仍然是“可以接受的” #user4655002

在重组代码之前请求

Request Log A. 您可以通过查看HTML代码的总体布局来摆脱此错误。 将请求完全放到页脚处。

这适用于我的情况

可能无法将整个项目发布在SO上,但我希望这个实用建议对您有所帮助。

重组代码后的请求 Request Log B.