我正在编写一个用户脚本,它检测“运送到”任意设计的地址表单并解析其内容。为此,我需要找到tr
包含地址标签(例如“名称”、“地址 1”等)和相应input
字段的表单“行”(可能是元素也可能不是元素)标签。例如,在以下代码段中:
<div>
<label>MaidenName</label>
<table><tbody>
<tr>
<td><label>FirstName</label></td>
<td><input value = "Bob"></td>
</tr>
<tr>
<td><label>LastName</label></td>
<td><input value = "Smith"></td>
</tr>
<tr>
<td><label>CompanyName</label></td>
<td><input value = "Ink Inc"></td>
</tr>
</tbody></table>
</div>
我想匹配所有tr
元素,因为它们每个都包含一个“名称”标签和一个输入字段。但是,我不想匹配div
“MaidenName”标签,因为它的范围比为表内字段找到的匹配范围更广。
我当前查找这些行(通常是div
元素而不是元素tr
)的算法是:
- 查找具有适当“名称”标签的所有节点
- 在每个节点的 DOM 中向上工作,直到找到一个作为输入字段祖先的节点
- 然后删除我遍历到达那里的孩子,只留下集合的父元素。
从我正在使用的端口翻译,JQuery Javascript 如下所示:
// set up my two lists
var labelNodes = getLabelNodes();
var nodesWithAddress =
$().find("input[type='text']:visible, select:visible");
var pathToCommonParents = getLabelNodes()
.parentsUntil(nodesWithAddressChildren.parents()).parent();
// keep the highest-level nodes, so we only have the common paths -
//not the nodes between it and the labels.
return combinedNodeSet.filter(
function (index) {return $(this).find(combinedNodeSet).length == 0});
这行得通……但是所有这些遍历和比较开销绝对会破坏我的表现(这可能需要五秒钟或更长时间。)
有什么更好的方法来实现这一点?我认为下面的伪代码会更好,但我可能是错的,我不知道如何实现它:
var filteredSet = $().find(*).hasAnyOf(labelNodes).hasAnyOf(nodesWithAddress);
return filteredSet.hasNoneOf(filteredSet);