jQuery 元素无法选择parent()

发布于 2024-09-25 09:02:56 字数 1205 浏览 4 评论 0 原文

似乎使用 :contains(sub) 和包含 <>sub 选择的元素无法访问它们父母。

以下示例应该说明我在 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>&lt;foo&gt;</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

任何想法为什么第四个是 0 而不是 1 ,或者我怎样才能规避这个问题?

此页面提到了选择器中的转义名称,但这也不起作用(而且,我'我不确定它是否适用)。

It seems elements selected using :contains(sub) with sub containing < or > cannot get to their parents.

The following example should illustrate the problem I'm having in both Safari and Camino (Gecko on Mac):

<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>

Output is:

1
1
1
0
2
2
1

Any ideas why the fourth one is 0 instead of 1, or how I can circumvent this?

This page mentions escaping names in selectors, but that didn't work either (also, I'm not sure if it's applicable).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

是你 2024-10-02 09:02:56

免责声明:这不是使用Tatu的答案的解决方案/解决方法 为此,这只是对问题的描述,以及是什么导致好奇的人出现奇怪的行为。

问题的根源就在这里,jQuery 用于识别 HTML 片段的正则表达式

/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/

的作用 匹配您的选择器:

body strong:contains("<foo>")

您可以尝试一下

alert(/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/.test('body strong:contains("<foo>")​​​'));​

所以它认为它是一个 HTML 片段..所以总的来说,这些目前是等效的:

$('body strong:contains("<foo>")');
$('<foo>');

看到第二个可以更清楚地说明它是一个文档片段......它没有父级。它占据匹配数组中的第二个位置,您可以看到它只是 , 再次尝试一下

alert(/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/.exec('body strong:contains("<foo>")')[1]);​

这会导致您最终到达 jQuery 的 $() 中的这段代码路径,构建一个片段。

简而言之,是的,我认为这是一个 jQuery 错误。

Disclaimer: This isn't a solution/workaround use Tatu's answer for that, this is just a description of the problem and what's going on to cause the weird behavior for those who are curious.

The root of the problem is here, the regex that jQuery uses to identify an HTML Fragment:

/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/

Which does match your selector:

body strong:contains("<foo>")

You can try it out:

alert(/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/.test('body strong:contains("<foo>")​​​'));​

So it thinks it's an HTML fragment..so overall these are currently equivalent:

$('body strong:contains("<foo>")');
$('<foo>');

Seeing the second is a clearer illustration that it's a document fragment...which has no parent. It takes the 2nd position in the match array, which you can see is just <foo>, again try it out:

alert(/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/.exec('body strong:contains("<foo>")')[1]);​

This results in you ultimately ending up at this code path in jQuery's $(), building a fragment.

So in short yes, I'd consider this a jQuery bug.

一场信仰旅途 2024-10-02 09:02:56

不知道是什么导致 contains() 失败,但您可以使用 .filter() 作为替代方案:

alert($('body strong').filter(function() {
    return /<foo>/.test( $(this).text() );
}).parent().length);

它会按预期返回 1。它很丑,但是有效。

No idea what's causing contains() to fail, but you can use .filter() as an alternative:

alert($('body strong').filter(function() {
    return /<foo>/.test( $(this).text() );
}).parent().length);

That returns 1 as expected. It's ugly, but works.

飘落散花 2024-10-02 09:02:56

这显然是 jQuery 选择器解析的问题。如果选择器中存在 <>,则 jQuery 会将参数识别为文档片段而不是选择器。结果是 tagName 为“FOO”的元素,相同的选择器会遇到相同的问题:

$('body <foo>')
$('body strong:not(<foo>')

您的情况唯一的区别是您使用了有效的选择器,并且 jQuery 正在识别它错误地。

我多次尝试基于选择器的解决方法,但是 Tatu Ulmanen 的 是唯一有效的。

编辑:看来你也可以使用.find()

$(document.body).find('strong:contains("<foo>")')

This is clearly an issue with jQuery's selector parsing. If < and > are present in the selector, jQuery identifies the argument as a document fragment instead of a selector. The result is an element with a tagName of "FOO", and the same selectors would have the same issue:

$('body <foo>')
$('body strong:not(<foo>')

The only difference in your case is that you've used a valid selector and jQuery is identifying it incorrectly.

I made several attempts at a selector-based workaround, but Tatu Ulmanen's was the only one that worked.

EDIT: it seems you can also use .find():

$(document.body).find('strong:contains("<foo>")')
卖梦商人 2024-10-02 09:02:56

被评估为一个标签,因此它的父级除了一个空标签之外什么都不包含,因此是 0。

编辑:要完全理解,请看这个: $(' body Strong:contains("foo")').text().length 产生 5。 $('body Strong:contains("")').length 中的 1 表示在强节点中有一个文本节点,因此该节点的长度为 1,文本的长度为 5。

有趣的是尾随的 >,它不能是由于 > 用作 css 选择器,因此 >> 似乎都无法正常工作。因此, 可以工作,但 不行

这是一个可以使用它的小提琴页面: http://jsfiddle.net/2XEUg/1/

The <foo> is being evaluated as a tag, thus the parent of it contains nothing except an empty tag, thus the 0.

EDIT: To fully understand look at this: $('body strong:contains("foo")').text().length which yeilds 5. The 1 from $('body strong:contains("<foo>")').length says there is one text node within the strong so length of that is 1 and the length of the text is 5.

The thing that gets interesting is the trailing > which cannot be selected correctly as the > nor the > seem to work due to the > which is used as a css selector. So, <foo works but not <foo>

Here is a fiddle page to play with it: http://jsfiddle.net/2XEUg/1/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文