如果您不愿意对属性名称/结构做出假设(完全合理),那么您基本上只能在自动完成对象本身中查询具有属性 className:"pac-container"(或其他一些识别功能)的对象。
有一些库可以帮助您解决此问题,例如 JSONPath、JSONQuery 以及更多可以帮助您执行此操作的库。不过,在不添加任何其他库的情况下,我们可以通过自动完成对象的嵌套层次结构滚动我们自己的广度优先搜索,但需要注意的是我不是 Javascript 专家,虽然这现在可以工作,但我不能保证我不会错过任何会在未来打破这种情况的边缘案例。
不幸的是,由于您指出的时间问题,您需要在 Autocomplete 对象的初始实例化后的某个时间点运行它。好消息是,如果您不立即需要 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 应该在本机上使其可见,grumble grumble)。我建议从您链接的 StackOverflow 问题中尝试一种更“天真”但速度更快的方法,并在该方法返回 null/empty 时回退到此。