jQuery选择器:选择<head>中的<link>元素

14
我们使用jQuery解析一些HTML。然后我需要遍历该文档并查找一些元素。在我需要找到的元素中,有<link>元素。
这可以完美地用来提取所有<a>元素:
$(string).find("a")

但是这种方法不能提取 <link> 元素:

$(string).find("link")

“string”参数是HTML内容(例如在请求中接收到的内容)。

有什么想法吗?(我猜“find”只适用于“<body>”元素)。还有,有没有关于如何实际提取这些“<link>”元素的想法?


3
变量string中有什么? - BoltClock
1
你想解析的是一个 HTML 的字符串吗? - Brad Christie
你可以提供更多信息吗?$('link') 从广义上讲运作良好,所以这似乎不是一个问题。 - josh.trow
@BoltClock:一个HTML文档的字符串(!)表示。 - Julien Genestoux
我不理解这个.. $('<html><head><link rel="1"></head><body><p name="john">John</p></body></html>') 返回 [<link rel=​"1">​, <p name=​"john">​John​</p>​],但是 $('<html><head><link rel="1"></head><body><p name="john">John</p></body></html>').find('p') 却什么也没有。 - josh.trow
显示剩余2条评论
4个回答

8

从您正在使用的特性的文档(它是函数jQuery( html, [ownerDocument] ))中可以得知:

当传入复杂的HTML时,一些浏览器可能无法生成与提供的HTML源完全相同的DOM。如上所述,我们使用浏览器的.innerHTML属性来解析传递的HTML并将其插入到当前文档中。在此过程中,一些浏览器会过滤掉某些元素,例如<html><title><head>元素。因此,插入的元素可能不代表传递的原始字符串。

尽量避免使用jQuery来操作整个HTML文档。

请注意,特别是在独立的HTML片段中,link节点可以被“找到”


@下投票者:请解释一下。我认为这很明显。 - Lightness Races in Orbit

1

根据我在jQuery源代码中找到的内容,引擎本身不会创建未“正确安装”的标签(或片段)。即使传递一个字符串,jQuery也会识别到标题已经被提供,并且不会生成它。

毕竟,当jQuery传递HTML字符串时,它实际上是调用document.createElement并创建这些元素的数组列表。

编辑:经过更多的调查,看起来限制元素创建的实际上是浏览器,而不是jQuery。无论哪种方式,你都会缺少标签。这就带我回到了下面的结论。

尽管我不喜欢这样做,但现在可能是使用正则表达式/字符串操作的时候了。


如果您检查以下fiddle的元素,您会发现许多标题标签已被豁免生成(而您无法遍历不存在的内容)。 - Brad Christie
不,这不是jQuery的错。请阅读文档。 - Lightness Races in Orbit
@Tomalak:我实际上对此更加深入地了解,并且似乎是浏览器的某种限制。浏览器会剥离它发现不应该存在/已经存在的标签。所以你很可能是正确的。 - Brad Christie

0

jQuery无法完成,但是您的浏览器可以:(不要像某些人建议的那样尝试使用正则表达式来解析HTML。)

txt = '<DIV><LINK>a</LINK><B>jelo</B></DIV>';

if(window.DOMParser) {
  parser=new DOMParser();
  xmlDoc=parser.parseFromString(txt,"text/xml");
} else { // Internet Explorer
  xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
  xmlDoc.async="false";
  xmlDoc.loadXML(txt);
}

xmlDoc.getElementsByTagName('LINK');

请注意,XML区分大小写,因此您需要使用与HTML中相同的大小写来搜索“LINK”。


不幸的是,这也行不通,因为DOMParser无法解析无效XML格式的HTML :( - Julien Genestoux
没错。我猜你需要解析来自任何网站的随机HTML?在这种情况下,除了编写自己的解析器或使用其他人制作的解析器之外,您唯一的选择是隐藏的iframe(但您需要注意,因为iframe将运行代码)。您应该搜索JavaScript HTML解析器,我已经搜索并找到了很多。 - Ariel

-2

就像 @pimvdb 所指出的那样,这个不起作用:

alert($("<div><link>Test</link></div>").find("link").text());

解释是正确的:

Sizzle使用context.getElementsByTagName,但由于元素不在DOM中,因此失败。

但这种方式可以工作:

alert(("link", $("<div><link>Test</link></div>")).text());

对于一些说第二个方案不工作的人:http://jsfiddle.net/ErickPetru/5Qs3M/。但显然它不能找到 DOM 上不存在的元素(例如在 head 中的元素)。

第一个不起作用是因为它没有附加到DOM。第二个有效是因为你错过了 $,因此根本没有使用 link 选择器。 - pimvdb
@pimvdb:我认为第一个应该可以工作。你对第二个的看法是正确的。 - Lightness Races in Orbit
Sizzle使用context.getElementsByTagName,但由于元素不在DOM中,因此失败。此外,<link>不能包含像这样的文本,因为它从未保持过这样的innerHTML - pimvdb
第一个不起作用是因为您正在尝试获取应为空的标签的“text”。<Link>标签不应该有那样的内容。jQuery似乎会将其剥离。 - david
2
如果你的解释是正确的,那么这个例子将会起作用(http://jsfiddle.net/5Qs3M/1/)。问题不在于 innerText,问题就是简单地解释了标签不会出现在文档中,因此无法被定位。 - Erick Petrucelli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接