似乎使用包含:contains(sub)
或sub
的{{1}}的{{1}}选择的元素无法访问其父母。
以下示例应说明我在Safari和Camino(Mac上的Gecko)中遇到的问题:
<
输出是:
>
任何想法为什么第四个是<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
</head>
<body>
<p><strong>bar</strong></p>
<p><strong><foo></strong></p>
<script type="text/javascript">
alert($('body strong:contains("bar")').length);
alert($('body strong:contains("bar")').parent().length);
alert($('body strong:contains("<foo>")').length);
alert($('body strong:contains("<foo>")').parent().length); // this fails
alert($('body strong').length);
alert($('body strong').parent().length); // two p elements
alert($('body strong').parent().parent().length); // one body
</script>
</body>
</html>
而不是1
1
1
0
2
2
1
,或者我如何绕过这个?
This page提到在选择器中转义名称,但这也不起作用(另外,我不确定它是否适用)。
答案 0 :(得分:3)
免责声明:这不是使用Tatu's answer的解决方案/解决方法,这只是对问题的描述以及导致奇怪行为的奇怪行为。
问题的根源在于the regex that jQuery uses to identify an HTML Fragment:
/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/
哪个 匹配您的选择器:
body strong:contains("<foo>")
alert(/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/.test('body strong:contains("<foo>")'));
所以它认为它是一个HTML片段......总的来说这些是等价的:
$('body strong:contains("<foo>")');
$('<foo>');
看到第二个更清楚的说明它是一个文件片段......没有父母。它位于匹配数组中的第二个位置,您只能看到<foo>
,again try it out:
alert(/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/.exec('body strong:contains("<foo>")')[1]);
这导致您最终以this code path in jQuery's $()
结束,构建片段。
所以简而言之是,我认为这是一个jQuery错误。
答案 1 :(得分:2)
不知道导致contains()
失败的原因,但您可以使用.filter()
替代:
alert($('body strong').filter(function() {
return /<foo>/.test( $(this).text() );
}).parent().length);
按预期返回1。这很难看,但很有效。
答案 2 :(得分:1)
<foo>
被评估为标记,因此它的父项除了空标记外都不包含任何内容,因此为0。
编辑:要完全理解这一点:$('body strong:contains("foo")').text().length
其中的$('body strong:contains("<foo>")').length
来自>
的1表示强者中有一个文本节点,因此长度为1,文本长度为1是5。
有趣的是跟踪>
无法正确选择>
,而>
似乎有效,因为<foo
用作<foo>
一个css选择器。因此,{{1}}有效,但不是{{1}}
这是一个小提琴页面:http://jsfiddle.net/2XEUg/1/
答案 3 :(得分:1)
这显然是jQuery的选择器解析的问题。如果选择器中存在<
和>
,则jQuery将该参数标识为文档片段而不是选择器。结果是一个 tagName 为“FOO”的元素,相同的选择器会出现同样的问题:
$('body <foo>')
$('body strong:not(<foo>')
你的情况唯一的区别是你使用了一个有效的选择器,jQuery正确地识别它。
我在基于选择器的解决方法上做了几次尝试,但Tatu Ulmanen's是唯一有效的方法。
编辑:似乎你也可以使用 .find():
$(document.body).find('strong:contains("<foo>")')