如何将 submit() 事件延迟到 Geocoder 完成后?

Posted

技术标签:

【中文标题】如何将 submit() 事件延迟到 Geocoder 完成后?【英文标题】:How to delay submit() event until after Geocoder is finished? 【发布时间】:2011-08-19 03:19:20 【问题描述】:

我正在开发 Google 地图/Google 电子表格混搭。

此时我正在开发一个 javascript/jquery 位,它允许用户填写表单,然后将该表单提交到 Google 电子表格。

当用户点击“提交”时,脚本会快速将用户的街道地址发送到 Google 的 Geocoder,它会返回等效的 lat 和 lng。

我遇到的问题是表单信息在我的 Geocoder 例程完成之前提交到 Google 电子表格。我不知道如何修改 .submit() 事件以防止它在获得 lat 和 lng 之后才提交。

在我的 jQuery 就绪处理程序中,我有这个:

    $("#ss-form").submit(function(event) 
        var street    = $('#entry_1').val();
        var citystate = $('#entry_2').val();
        var country   = $('#entry_3').val();
        findAddress(street,citystate,country);              
    );

它正在调用这个函数:

function findAddress(street, citystate, country) 
    var myAddress = [
        street,
        citystate.toLowerCase(),
        country.toLowerCase()
    ].join(', ');

    geocoder.geocode(
        address: myAddress, 
        function(result,status) 
            var myLat = result[0].geometry.location.lat();
            var myLng = result[0].geometry.location.lng();
            $('#entry_5').val(myLat);
            $('#entry_6').val(myLng);
            console.log(myLat+','+myLng);
        
    );

相关的 html 是一个包含六个输入(#entry_0 到 #entry_6)的简单表单。

所以我要做的是获取 Lat 和 Lng,然后将它们作为值放入 HTML 表单中,然后让表单提交。如何让提交延迟到 findAddress 函数完成后?

【问题讨论】:

这是一个示例页面,其中包含以下给出的答案之一:joshrenaud.com/pd/testcase/google-maps-spreadsheet-test.html 当我在 Chrome 中尝试时,控制台显示相同的输出重复多次,直到它'无法读取 null 的属性'0''。我还在学习 JS,但在我无知的头脑中,findAddress 中的 submit() 调用似乎导致它陷入无限循环。 一方面,我想通过提交处理程序来完成这项工作。我知道用户一旦单击提交就完成了他们的信息,此时查找 LatLng 是有意义的。但考虑到我让它工作的麻烦,我可能只是将 LatLng 查找移动到表单输入字段上的焦点事件。每当一个字段获得焦点时,检查所有地址字段是否完整。如果是这样,请运行 LatLng 检查。然后在按下提交按钮之前,LatLng 数据将准备就绪。 【参考方案1】:
$("#ss-form").submit(function(event) 
        event.preventDefault(); //prevent the submit
        var street    = $('#entry_1').val();
        var citystate = $('#entry_2').val();
        var country   = $('#entry_3').val();
        findAddress(street,citystate,country,$(this));        

    );

在函数中提交表单

function findAddress(street, citystate, country, form ) 
    var myAddress = [
        street,
        citystate.toLowerCase(),
        country.toLowerCase()
    ].join(', ');

    geocoder.geocode(
        address: myAddress, 
        function(result,status) 
            var myLat = result[0].geometry.location.lat();
            var myLng = result[0].geometry.location.lng();
            $('#entry_5').val(myLat);
            $('#entry_6').val(myLng);
            console.log(myLat+','+myLng);

            form[0].submit(); //submit the form here  
        
    );


【讨论】:

这不起作用,因为 findAddress() 触发了一个异步请求(这是他的问题的路由),因此请求将启动,然后将触发提交。您的代码将与当前代码的行为方式相同。 还是不行。您需要在地理编码器的回调中移动form.submit()。我已将其更新为应有的状态。 当我尝试时,这种方法和下面的方法似乎都会导致无限循环。我将建立一个测试页面并添加一条评论,其中包含指向我的问题的链接。 哦,是的,没想到。调用提交函数,将重新触发提交处理程序...:/ @Kirkman14:看看这个问题的答案 (***.com/questions/5843277/…)。它展示了如何修复这个无限循环。我还更新了上述答案以解决该问题。选择原始 HTML 元素(使用[0])并调用其提交方法,不会重新触发 jQuery 处理程序。【参考方案2】:

你可以试试这个

$("#ss-form").submit(function(event) 
     if(!$(this).data("geocodeset"))
        findAddress();              
        return false;
     
);

function findAddress() 
    var $form = $("#ss-form");
    var street    = $('#entry_1').val();
    var citystate = $('#entry_2').val();
    var country   = $('#entry_3').val();

    var myAddress = [
        street,
        citystate.toLowerCase(),
        country.toLowerCase()
    ].join(', ');

    geocoder.geocode(
        address: myAddress, 
        function(result,status) 
            var myLat = result[0].geometry.location.lat();
            var myLng = result[0].geometry.location.lng();
            $('#entry_5').val(myLat);
            $('#entry_6').val(myLng);
            console.log(myLat+','+myLng);

            $form.data("geocodeset", true).submit(); 
        
    );


【讨论】:

您可能需要在提交处理程序中更新您对findAddress() 的签名。它与您拥有的功能不匹配。 请看我上面的评论。我发布了一个包含您的答案的示例页面,但它不起作用。 @Kirkma14 - 地理编码器结果为空,结果 [0] 为空,因此您在该行收到 js 异常。现在您需要找出地理编码器给出空响应的原因。 地理编码器仅在循环大约 20 次后才给出 null。您的解决方案创建了一个无限循环。为了确定,我添加了一个计数器。 为什么我的解决方案会创建一个无限循环?我只是在地理编码器回调方法中添加了提交表单的代码。

以上是关于如何将 submit() 事件延迟到 Geocoder 完成后?的主要内容,如果未能解决你的问题,请参考以下文章

如何触发延迟到用户暂停输入的 onkeyup 事件?

如何将方法调用延迟 1 秒?

Socket io 延迟一个事件

如何在 iOS 中延迟 UISlider 的开始触摸事件?

如何正确地将单击按钮属性值传递给表单提交事件?

.submit()在setTimeout之后不提交表单[重复]