【问题标题】:jQuery selector is overlooking elements from a separate contextjQuery 选择器从单独的上下文中忽略元素
【发布时间】:2018-05-30 12:22:19
【问题描述】:

我正在向我网站上的页面发出 ajax 请求,并使用此元素作为 body 标记的直接子元素:

<div class="container" id="wantme"><div class="content"></div></div>

只有一个.container,我想抢它的ID,我不知道。

据我所知,这段代码应该做我想做的事:

$.get('/page', function(data) {
    id = $('.container', data).attr('id');
});

但是.container 选择器找不到任何东西。

我确实找到了这两种解决方法。我可以找到.content,我可以这样爬树:

id = $('.content', data).parent().attr('id');

但我不能直接跳到那里。

我在 StackOverflow 的其他地方发现了这个可行的解决方法:

html = $('<div></div>').html(data);
id = html.find('.container').attr('id');

但为什么看似显而易见的答案却行不通呢?

【问题讨论】:

  • 我不确定我是否理解。我使用 .find() 的唯一地方它实际上在这里工作。第一段代码坏了,后两段是我发现的解决方法。
  • $(data).find(".container").attr("id"); 呢?
  • @31piy 好主意,遗憾的是它的行为仍然相同。
  • @TylerRoper 它表现出同样的古怪行为。我制作了一个 jsfiddle,希望能让任何想玩的人更容易玩。 jsfiddle.net/8vcu4Lo1
  • 那么 JSFiddle 为我澄清了答案。我会在下面发布。

标签: javascript jquery html dom


【解决方案1】:

更新的答案:我将把我原来的答案留在底部,但我担心它可能会因浏览器而行为不端。 jQuery 的 .html() 使用了 Javascript 的 innerHTML - 一些浏览器在使用 innerHTML 时会选择去除 &lt;head&gt;&lt;body&gt; 标签,而其他浏览器则不会。

实现您所追求的最安全的方法可能仍然是您提到的解决方法,如下所示:

var data = '<!doctype html><html><body><div class="container" id="findme"><div class="content"></div></div></body></html>';

var $container = $("<div />").html(data).find(".container");
var id = $container.attr("id");

console.log(id);
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;&lt;/script&gt;

有关浏览器相关问题的更多信息can be found here


以前的答案:

当您将 HTML 传递给 jQuery 元素时,它将忽略 &lt;body&gt; 标记,以及它们之外的任何 标记。给定 JSFiddle 中的数据字符串,$(data) 将创建如下所示的内容:

<div class="container" id="findme">
    <div class="content"></div>
</div>

正如您在上面的 HTML 中看到的,您的 .container 不在$(data)内部 - 它 $(data)

因为$(data) 代表您的.container 元素,所以您应该能够执行$(data).attr("id") 来检索您所追求的内容。

var data = '<!doctype html><html><body><div class="container" id="findme"><div class="content"></div></div></body></html>';
var id = $(data).attr('id');
console.log(id);
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;&lt;/script&gt;

【讨论】:

  • 太棒了,就是这样!优秀作品!附带问题,当有多个顶级元素时会发生什么(我的整个页面确实有一个或两个用于 .container 的兄弟),有没有办法避免这种精简?
  • $(data) 将对应于第一个顶级元素,忽略其后的兄弟姐妹。关于你的第二点,看看at this question - 它可能会有所帮助。鉴于其中包含的信息,我相信您的$(&lt;div&gt;&lt;/div&gt;") 解决方法实际上可能更安全。不过,它可以缩短为 $("&lt;div /&gt;")
  • @Different55 经过调查,我编辑了我的答案。我认为我之前的答案不适用于所有浏览器。建议的解决方法不仅可以跨浏览器兼容,而且我认为它也可以解决您的兄弟问题。
【解决方案2】:

您没有从 $('.container', data).attr('id'); 获取 ID 是因为您正在设置第二个参数的值。你要做的是:$('.container ' + data).attr('id');.

更新: 如果 data 是一个字符串,那么你应该将它转换成一个 DOM 元素:$('.container', $(data)).attr('id');

【讨论】:

  • 我不太确定这在这种情况下是否有意义。 data 是一个包含完整 HTML 文档的字符串。我将它设置为第二个参数,以便将其解释为一个完全属于它自己的文档,并在该上下文中执行选择器。请参阅documentation 的这一点。将 HTML 字符串附加到选择器以 ".container &lt;!DOCTYPE html&gt;&lt;html&gt;&lt;head&gt;..." 结尾并吐出语法错误。
猜你喜欢
  • 2014-01-03
  • 2012-11-10
  • 2017-06-07
  • 2017-11-28
  • 2016-04-29
  • 2014-02-17
  • 1970-01-01
  • 1970-01-01
  • 2010-12-04
相关资源
最近更新 更多