【问题标题】:How to integrate one function into another using jQuery and promise()?如何使用 jQuery 和 promise() 将一个函数集成到另一个函数中?
【发布时间】:2015-05-30 19:11:44
【问题描述】:

我正在尝试使用promise() 方法将一个功能集成到另一个功能中。以下 jQuery/ajax 当前在代码的第一部分提交了一个表单,然后有第二个函数在用户提交表单时尝试模拟标签点击。

需要模拟点击的标签是:

<a href="#contact"><li><label id="contactlink" class="contactbox" for="lightbox-one">Contact</label></li></a>

代码如下:

  <script>
 $(document).ready(function() {
 $("#contactform").submit(function(e)
 {    
 e.preventDefault();
    
    // Bind click handler outside of AJAX call
$('label').click(function() {
    var labelID;
    labelID = $(this).attr('for');
    $('#'+labelID).trigger('click');
});

// Make AJAX call
$.ajax({
    type: "POST",
    url: "contact-form-handler.php",
    dataType: "text",
    data: {
        message: $('#message').val(),
        addy: $('#addy').val(),
        contactsubmit: 'yes'
    }
}).done(function() {
    console.log('success');
    $('label').trigger('click');
});
    
});
});
</script>

除了第二个功能外,一切正常:

.promise().done(function() {            
     $('label').click(function() {
     var labelID;
     labelID = $(this).attr('for');
     $(‘#’+labelID).trigger(‘click’);
                             });

我会以某种方式将.promise().done(function() 和$('label').click(function() 结合起来吗?我不知道如何正确编写第二个函数以模拟在表单提交时单击该标签。你能告诉我我的完整代码应该是什么吗?我很困惑!

更新:该标签旨在在单击时打开此弹出窗口:

<aside class="lightbox">
  <input type="checkbox" class="state" id="lightbox-one" />
  <article class="content">
<h1>Content Here</h1>
  </article>
  <label class="backdrop" for="lightbox-one"></label>
</aside>

这是弹出窗口(灯箱)的 CSS:

[type="checkbox"]:not(:checked),
[type="checkbox"]:checked {
  position: absolute;
  left: -9999px;
}
[type="checkbox"]:not(:checked) + label,
[type="checkbox"]:checked + label {
  position: relative;
  padding-left: 75px;
  cursor: pointer;
}
[type="checkbox"]:not(:checked) + label:before,
[type="checkbox"]:checked + label:before,
[type="checkbox"]:not(:checked) + label:after,
[type="checkbox"]:checked + label:after {
  content: '';
  position: absolute;
}
[type="checkbox"]:not(:checked) + label:before,
[type="checkbox"]:checked + label:before {
  left:0; top: -3px;
  width: 65px; height: 30px;
  background: rgba(200, 200, 200, 0.49);
  border-radius: 15px;
  transition: background-color .2s;
}
[type="checkbox"]:not(:checked) + label:after,
[type="checkbox"]:checked + label:after {
  width: 20px; height: 20px;
  transition: all .2s;
  border-radius: 50%;
  background: #E4E4E4;
  top: 2px; left: 5px;
}

/* on checked */
[type="checkbox"]:checked + label:before {
  background:rgba(125, 208, 139, 0.62); 
}
[type="checkbox"]:checked + label:after {
  background: #ff9a03;
  top: 2px; left: 40px;
}

[type="checkbox"]:checked + label .ui,
[type="checkbox"]:not(:checked) + label .ui:before,
[type="checkbox"]:checked + label .ui:after {
  position: absolute;
  left: 6px;
  width: 65px;
  border-radius: 15px;
  font-size: 16px;
  font-weight: bold;
  line-height: 22px;
  transition: all .2s;
}
[type="checkbox"]:not(:checked) + label .ui:before {
  content: "no";
  left: 32px
}
[type="checkbox"]:checked + label .ui:after {
  content: "yes";
  color: #ff9a03;
}
[type="checkbox"]:focus + label:before {
  border: 1px dashed #777;
  box-sizing: border-box;
  margin-top: -1px;
}    

.state{position:absolute;top:0;left:-100vw}
    .state:checked ~ .content{-webkit-transform:none;-ms-transform:none;transform:none;margin-top: 10%;overflow:auto; border-radius: 9px;height:300px;}
    .state:checked ~ .backdrop{bottom:0;opacity:1;z-index:1}
    .lightbox{position:fixed;top:0;right:0;left:0;height:0;padding:0 20px}
    .lightbox .content{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow:hidden;position:relative;z-index:2;max-width:500px;max-height:95vh;margin:20px auto;padding:20px;background:#fff;-webkit-transform:translateY(-200%);-ms-transform:translateY(-200%);transform:translateY(-200%);-webkit-transition:.3s -webkit-transform ease-in-out;transition:.3s transform ease-in-out;border:1px solid rgba(0,0,0,0.1)}
    .lightbox .header,.lightbox .footer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}
    .lightbox .header .h,.lightbox .footer .h{margin:0}
    .lightbox .header .button:not(:first-child),.lightbox .footer .button:not(:first-child){margin-left:auto}
    .lightbox .header{padding-bottom:10px}
    .lightbox .footer{padding-top:20px}
    .lightbox .main{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}
    .lightbox .backdrop{position:fixed;z-index:-1;top:0;right:0;bottom:100%;left:0;opacity:0;background:rgba(0,0,0,0.3);-webkit-transition:.3s opacity ease-in-out;transition:.3s opacity ease-in-out}

【问题讨论】:

  • 嗯,这个功能已经内置在浏览器中(标签点击会触发for-referenced 输入),不知道你为什么要复制这个?
  • 我很确定您不想将 click 处理程序绑定到 submit 处理程序或 ajax 回调中。
  • 我不知道这里有什么最佳实践。我只需要提交表单并通过模拟单击我发布的标签来打开弹出窗口。在这一点上,您可以提供的任何解决方案都是黄金。
  • 我认为您根本不想绑定任何处理程序 - 您只想调用 $('label').trigger('click');?也许您应该详细说明点击如何打开弹出窗口,可能有比模拟点击更好的方法。
  • 谢谢!!!解决了。多么简单的解决方案……哦,伙计。我最终使用了 $('#lightbox-one').prop('checked', true);在我的成功功能中。非常感谢您的宝贵时间。

标签: jquery ajax forms label jquery-events


【解决方案1】:

在 Bergi 的指导下,我能够通过将这段代码添加到我的成功处理程序中来解决这个问题:$('#lightbox-one').prop('checked', true);

整个代码现在看起来像:

<script>
 $(document).ready(function() {
 $("#contactform").submit(function(e)
 {
          e.preventDefault();
        if ($.trim($("#message").val()) === "" || $.trim($("#addy").val()) === "") 
           {
         return false;
           }
           var value = document.getElementById('message').value;
            if (value.length < 10) {
            return false; 
                                   }
          $.ajax({
                  type: "POST",
                  url: "contact-form-handler.php",
                  dataType:"text",
                  data: {message: $('#message').val(), addy: $('#addy').val(), contactsubmit: 'yes'},

                  success: function()   
             {
                $('#lightbox-one').prop('checked', true); 
             }
                })

    });
});
</script>

【讨论】:

    【解决方案2】:

    $.ajax() 方法自动返回一个 Promise——它是函数的原生。此外,由于您使用的是.done(),因此您不应再使用已弃用的.success() 回调。无需链接.promise().done()。

    关于点击事件绑定,您应该在 AJAX 调用之外进行,否则您会将 多个 点击事件处理程序绑定到每个单独的 &lt;label&gt;通话成功。因此,您应该在AJAX调用外部绑定事件处理程序,然后在AJAX调用时简单地使用.trigger()触发点击事件。

    您尚未提供您所定位的&lt;label&gt; 元素的上下文...

    // Bind click handler outside of AJAX call
    $('label').click(function() {
        var labelID;
        labelID = $(this).attr('for');
        $('#'+labelID).trigger('click');
    });
    
    // Make AJAX call
    $.ajax({
        type: "POST",
        url: "contact-form-handler.php",
        dataType: "text",
        data: {
            message: $('#message').val(),
            addy: $('#addy').val(),
            contactsubmit: 'yes'
        }
    }).done(function() {
        console.log('success');
        $('label').trigger('click');
    });
    

    另外,我不知道这是否是故意的,但您在 .done() 函数的最后一行使用了智能引号(‘ 和 ’)。您应该改用哑引号'。

    【讨论】:

    • 哇,谢谢特里!我现在就试试。至于
    • 如果它是 only &lt;label&gt; 元素,它应该可以工作。试一试,如果不起作用,请告诉我:)
    • 它成功提交了带有详细信息的表单,但不会打开弹出窗口。我假设我应该将您的代码嵌套在 $(document).ready(function() { $("#contactform").submit(function(e) 否则它不会知道在提交表单时启动。我有更新了我的问题代码以反映最新的更改。为什么它不会打开弹出窗口?也许它应该模拟“检查”而不是“点击”?因为输入类型是复选框。谢谢
    • 确实如此。您应该将它放在提交事件处理程序中。
    • 您只需将.done() 链接到$.ajax() 方法,就像我的回答一样。函数中的success对象是jqXHR.success()方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-22
    • 2020-10-11
    • 1970-01-01
    • 2020-11-19
    • 2011-05-07
    • 1970-01-01
    • 2017-11-04
    相关资源
    最近更新 更多