【发布时间】:2012-07-26 15:02:57
【问题描述】:
我正在编写一个用户脚本,它检测“运送到”任意设计的地址表单并解析其内容。为此,我需要找到包含地址标签(例如“名称”、“地址 1”等)和相应的“行”(可能是也可能不是 tr 元素)的表单input 该标签的字段。比如在下面的sn-p中:
<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 元素,因为它们每个都包含一个“名称”标签和一个输入字段。但是,由于“MaidenName”标签的原因,我不想匹配 div,因为它的范围比在表内的字段中找到的匹配范围更广。
我当前查找这些行(通常是 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});
这行得通...但是所有这些遍历和比较开销绝对会破坏我的性能(这可能需要 5 秒 或更长时间。)
什么是更好的实现方式?我认为下面的伪代码会更好,但我可能是错的,我不知道如何实现它:
var filteredSet = $().find(*).hasAnyOf(labelNodes).hasAnyOf(nodesWithAddress);
return filteredSet.hasNoneOf(filteredSet);
【问题讨论】:
-
在这种情况下,标签和输入周围是否总是存在类似
td的元素? -
总是一些元素,但是环绕元素的嵌套深度和标签名称会有所不同。
标签: jquery performance jquery-selectors filtering dom-traversal