将Google商家信息自动填充pac-container与输入字段相关联

时间:2014-04-16 17:19:04

标签: javascript autocomplete google-places-api

有没有办法将pac-container div的自动完成与它附加的输入元素相关联?理想情况下,我希望能够将每个pac容器的ID设置为" pac - ",以便在输入消失时将其删除,并使其成为可能使用Selenium更容易测试自动复合。

This question的答案有一个解决方案,但它并不具有远程可持续性,因为谷歌倾向于改变各种缩小的属性名称(例如,曾经的Mc现在是Rc )

每当添加新的自动填充功能时,我也尝试修改页面上的最后一个pac-container div,如下所示:

function attachAutocomplete(id) {
    var input = document.getElementById(id);
    var autocomplete = new google.maps.places.Autocomplete(input);
    $(".pac-container:last").attr("id", "pac-" + id);
}

这可以很好地处理页面加载后的新自动填充功能,但由于某种原因,分配的前几个自动填充功能和它们的pac容器之间出现延迟。 (Here's a fiddle that should illustrate this approach and how it fails

我有什么方法可以丢失吗?

2 个答案:

答案 0 :(得分:1)

我解决了这个问题,不是将每个.pac-container与其输入类型表单字段相关联,而是每次重置自动填充输入类型时重置所有.pac-container项目。

基本上是这样的:

1)我们假设我们有3个地址输入,google.maps.places.Autocomplete已设置

2)使用jquery,让焦点事件绑定到这3个输入

$('#address_1, #address_2, #address_2'.focus(function (e) 
{
    $('.pac-container').each( function() {
        $(this).html( '' );
    });
});

3)将聚焦事件绑定到这3个输入,并选择相应的选定地址

答案 1 :(得分:0)

如果您不愿意对属性名称/结构做出假设(完全合理),那么您基本上可以查询具有属性className:"pac-container"(或其他一些识别功能)的对象的Autocomplete对象本身

有些库可以帮助解决这个问题,比如JSONPath,JSONQuery等等,可以帮助你做到这一点。但是,如果不添加任何其他库,我们可以通过自动完成对象的嵌套层次结构进行自己的广度优先搜索,但需要注意的是我不是Javascript专家,而且这虽然现在可行,我不能保证我不会错过将在未来打破这个问题的边缘案例。

不幸的是,由于您指出的时间问题,您需要在自动完成对象的初始实例化之后的某个时刻运行它。好消息是,如果您不立即需要pac-container对象引用,只要您将自动完成对象引用保留在范围内,就可以推迟查找它,直到您需要它为止。

该功能最终看起来像这样:

var autocompleteDropdown = breadthFirstSearch(autocomplete, function(val) {
    return val.className === "pac-container";
}

将breadthFirstSearch函数定义为:

function breadthFirstSearch(object, matchesCriteria) {
    var queue = [];
    var visited = [];
    queue.push(object);
    visited.push(object);
    while (queue.length) {
        var val = queue.shift();
        if (val && typeof val == "object") {
            if (matchesCriteria(val)) {
                return val;
            }
            if (Object.prototype.toString.call(val) == "[object Array]") {
                for (var i=0; i<val.length; i++) {
                    breadthFirstSearchProcessValue(val[i], queue, visited);
                }
            }
            else if (val instanceof Node) {
                if (val.hasChildNodes()) {
                    var children = val.childNodes;
                    for (var i=0; i<children.length; i++) {
                        breadthFirstSearchProcessValue(children[i], queue, visited);
                    }
                }
            }
            else {
                for (var property in val) {
                    breadthFirstSearchProcessValue(val[property], queue, visited);
                }
            }
        }
    }
}
function breadthFirstSearchProcessValue(val, queue, visited) {
    for (var i=0; i<visited.length; i++) {
        if (visited[i] === val) {
            return;
        }
    }
    queue.push(val);
    visited.push(val);
}

总而言之,这显然只是一种非常密集的方式来访问一个属性(Google 应该本地可见,抱怨发牢骚)。我建议你尝试一下更多的&#34;天真的&#34;但是你链接的StackOverflow问题的方法更快,当该方法返回null / empty时,它会回退到这个。