【问题标题】:Using jQuery to search a string of HTML使用 jQuery 搜索 HTML 字符串
【发布时间】:2011-11-01 19:58:00
【问题描述】:

如果我运行这段代码 -

var html= '<html><head></head><body><div class="bar"></div></body></html>';
console.log($(html).find('div'));

如果我运行此代码,我不会返回任何结果 -

var html= '<html><head></head><body><div><div class="bar"></div></div></body></html>';
console.log($(html).find('div'));

然后我得到一个返回的结果 - 内部 div (&lt;div class="bar"&gt;&lt;/div&gt;)。我本来希望第一个代码 sn-p 返回一个结果,第二个 sn-p 返回两个结果。

同样,此代码不返回任何结果 -

var code = $("<div id='foo'>1</div><div id='bar'>2</div>");
console.log(code.find('div'));

但此代码两次提醒“div”-

var code = $("<div id='foo'>1</div><div id='bar'>2</div>");
code.each(function() {
    alert( this.nodeName );
})

鉴于第二个 sn-p 的结果,我本来希望第一个代码 sn-p 返回两个结果。有人可以解释为什么我会得到我得到的结果吗?

http://jsfiddle.net/ipr101/GTCuv/

【问题讨论】:

  • 我把console.log改成了alert,它提醒了[object Object],所以它一定找到了什么……
  • @Eran Zimmerman:那是因为 jQuery 总是返回一个对象,不管为选择器找到多少匹配项。
  • 我假设 [object Object] 指的是 jQuery 返回的空数组。

标签: javascript jquery jquery-selectors


【解决方案1】:

.find 在第三个示例中,搜索每个匹配元素中的子元素。在您的 divs 中没有 div 子级(他们没有任何子级),因此 .find(anything) 不会返回任何元素。

另一方面,.each 迭代集合中的当前元素,其中确实包括 divs(有两个匹配的元素 - divs)。

至于您的第一个示例中的&lt;html&gt;,我不确定- 也许您不允许在页面加载后创建第二个&lt;html&gt; 元素。 $('&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;/body&gt;&lt;/html&gt;'); 只返回 div 所以 .find 不返回任何东西。

【讨论】:

  • jQuery(或更准确地说,浏览器)删除了htmlheadbody标签,只保留body内容。
【解决方案2】:

让我们把这个问题分成两部分。

第一:

var html= '<html><head></head><body><div class="bar"></div></body></html>';
console.log($(html).find('div'));

var html= '<html><head></head><body><div><div class="bar"></div></div></body></html>';
console.log($(html).find('div'));

不工作,因为根据jQuery() docs

在传入复杂的 HTML 时,某些浏览器可能不会生成 DOM 这完全复制了提供的 HTML 源代码。如前所述,我们使用 浏览器的 .innerHTML 属性来解析传递的 HTML 并插入 将其添加到当前文档中。在这个过程中,一些浏览器 过滤掉某些元素,例如&lt;html&gt;&lt;title&gt;&lt;head&gt; 元素。因此,插入的元素可能不具有代表性 传递的原始字符串。

  • 在第一个代码块中,您的&lt;html&gt;&lt;head&gt;&lt;body&gt; 标签将被删除,而&lt;div class="bar"&gt;&lt;/div&gt; 仍然存在。 find 只在结果 &lt;div&gt; 中搜索,找不到任何东西。
  • 在第二个代码块中,您的&lt;html&gt;&lt;head&gt;&lt;body&gt; 标签将被删除,而&lt;div&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;/div&gt; 仍然存在。 find 在结果中搜索,并找到一个 &lt;div&gt;

至于你的第二部分:

var code = $("<div id='foo'>1</div><div id='bar'>2</div>");
console.log(code.find('div'));

你首先给 jQuery 一个字符串,它接受并用两个&lt;div&gt; 组成一个 jQuery 对象。然后,find 在每个 &lt;div&gt; 中进行搜索,没有找到任何结果。

接下来,在

var code = $("<div id='foo'>1</div><div id='bar'>2</div>");
code.each(function() {
    alert( this.nodeName );
})

each 循环遍历 jQuery 对象,获取两个创建的 &lt;div&gt; 中的每一个,并提醒它们的节点名称。因此,您会收到两个警报。

【讨论】:

    【解决方案3】:

    答案很简单。当您使用 jQuery(html) 创建对象时,它会创建节点层次结构,当您找到像“div”这样的节点时,它会搜索除根元素之外的整个层次结构,并且在您的第一个示例中,您没有子“div”节点。在您的第二个示例中,您只有一个子“div”节点。

    因此,如果您在整个层次结构中保留一个额外的根节点,那么您可以轻松找到所有节点。喜欢

    var html= '<html><head></head><body><div class="bar"></div></body></html>';
    console.log($('<div></div>').append(html).find('div'));
    
    var html= '<html><head></head><body><div><div class="bar"></div></div></body></html>';
    console.log($('<div></div>').append(html).find('div'));
    

    【讨论】:

    • 这是应该的。如果有超过 1 个根元素,则接受的答案将不起作用。
    • 那是正确的答案。对我有用的另一种写作是$('&lt;div&gt;'+html+'&lt;/div&gt;').find('div')
    【解决方案4】:

    简单的方法如下:

    给定字符串:

    var html= '<html><head></head><body><div class="bar"></div></body></html>';
    

    使用类栏搜索 div:

    $(html).filter('.bar')
    

    或所有 div:

    $(html).filter('div')
    

    返回类bar的对象

    【讨论】:

    • 太棒了!你拯救了我的一天!
    猜你喜欢
    • 2011-06-03
    • 2012-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多