将Google Places自动完成pac容器与输入字段关联
Associate Google Places Autocomplete pac-container with input field
有没有任何方法可以将自动完成的pac容器div与它所附加的输入元素关联起来?理想情况下,我希望能够将每个pac容器的ID设置为类似"pac-"的值,这样,如果输入消失,我就可以删除它们,并更容易地使用Selenium测试自动完成。
这个问题的答案有一个解决方案,但它是不可持续的,因为谷歌倾向于更改各种缩小的房地产名称(例如,曾经的Mc现在是Rc)
每当添加新的自动完成时,我还尝试修改页面上的最后一个pac容器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容器之间存在延迟。(这里有一个小提琴应该说明这种方法以及它是如何失败的)
我缺少什么方法吗?
我不是通过将每个.pac容器与其输入类型表单字段关联来解决这个问题,而是在每次关注自动完成输入类型时重置所有.pac容器项。
所以基本上:
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) 将focusout事件绑定到这3个输入,并选择相应的选定地址
如果您不愿意对属性名称/结构做出假设(完全合理),那么您基本上只能在Autocomplete对象本身查询具有属性className:"pac-container"
(或其他一些识别功能)的对象。
有一些库可以帮助您做到这一点,例如JSONPath、JSONQuery等。不过,在不添加任何额外库的情况下,我们可以在Autocomplete对象的嵌套层次结构中滚动我们自己的广度优先搜索,但需要注意的是,我不是Javascript专家,虽然这目前有效,但我不能保证我没有错过一个在未来会打破这一局面的边缘案例
不幸的是,由于您指出的时间问题,您将需要在Autocomplete对象的初始实例化之后的某个时刻运行此操作。好消息是,如果您不立即需要pac-container
对象引用,那么只要您将Autocomplete对象引用保持在范围内,就可以推迟到需要时再查找。
功能最终看起来是这样的:
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);
}
总之,这显然是一种非常密集的访问属性的方式(谷歌应该使其在本地可见,抱怨抱怨)。我建议您尝试您链接的StackOverflow问题中一个更"天真"但速度更快的方法,当该方法返回null/empty时,就回到这个方法。
- 为什么不't Javascript对我的输入值进行了一些重新检查
- JS/Jquery - 如果输入具有数组的任何名称,则返回关联的值
- 如何在JavaScript中关联两个输入
- 将输入 html 元素动态关联到颜色选取器
- 如何将动态添加的输入字段关联到父元素/ID
- Ajax 在输入时自动完成,已经有一些事件关联
- 尝试关联两个获得输入值的集合
- 从表单输入创建多维关联数组
- Jquery UI DatePicker,获取默认日期的关联输入文本
- 如何使用 angularfire 将输入与 Firebase 中的用户相关联
- 使用jquery关联输入值
- 仅当关联复选框选中MySql时才插入输入文本数据
- 使用jQuery从输入中获取关联数组
- React:将输入字段的值与删除的组件关联起来
- 更新与输入相关联的DB值元素的值发生变化时
- 将右侧输入文本数据与其相邻的跨度内容相关联
- 将Google Places自动完成pac容器与输入字段关联
- AngularJS / JQuery - 没有关联标签的表单输入
- 如何打印出 3 个项目,它与 2 个输入(价格和数量)相关联
- 如何获得输入的值并分配一个他没有关联的标签