2013-03-14 65 views
21

我正在写与QUnit测试和使用$.ajax()在HTML中拉了一段从dev的现场测试对我的本地运行:的jQuery()没有找到在jQuery.parseHTML元素()结果

add_elements = function(location, selector) { 
    $.ajax(location, {async: false}).done(function(data) { 
    stor.$els = $(selector, $.parseHTML(data)); 
    stor.$els.appendTo($('body')); 
    }) 
} 

在某一位置使用此功能,我得到以下data传递给我的.done()回调:

<!DOCTYPE html> 
<html lang="en"> 

<head> 
    <title>Home</title> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <link href="/static/css/bootstrap.min.css" rel="stylesheet" media="screen"> 

</head> 

<body> 
<div id="app-container" class="container-fluid"> 
    <div class="page-header"> 
     <h1> 
      <a href="/">Home</a> 
      <small>Text</small> 
     </h1> 
    </div> 

    <div id="hero-units" class="carousel-inner slide"> 

     <div class="hero-unit home item active"> 
      <h1> 
       Text text text 
      </h1> 
      <p> 
       More text! 
      </p> 
      <div id="app-nav"> 
       <a id="lets-go" class="btn btn-primary btn-large nav-forward" href="/what-up/"> 
        Let's go 
       </a> 
      </div> 
     </div> 

    </div> 
</div> 

<script src="/static/js/jquery.js"></script> 
<script src="/static/js/underscore.js"></script> 
<script src="/static/js/backbone.js"></script> 
<script src="/static/js/bootstrap.js"></script> 
<script src="/static/js/site-fiddle.js"></script> 
<script src="/static/js/site.js"></script> 

</body> 
</html> 

一切正常,如果selector#hero-units.hero-unit,但如果selector#app-container,则不返回任何内容!我想为div#app-container元素设置一个jQuery对象。

这里是什么杀死我:

  • $.parseHTML(data)确实包含div#app-container元素。这只是$.parseHTML(data)[7]
  • 然而,$('#app-container', $.parseHTML(data))是一个空数组。
  • $('div', $.parseHTML(data))包括div#app-container内部的所有div,但不包括div#app-container本身。

这是怎么回事?看来发生了什么事情是$没有看到由$.parseHTML(data)$($.parseHTML(data)))返回的任何顶级元素,而只是他们的子女。

如何从$.parseHTML(data)获得jQuery对象div#app-container

ANSWER

$(selector, $.parseHTML(data))式的查找使用$.find。因为我正在寻找这个jQuery对象中最高层的元素,所以我应该使用$.filter。瞧。

+1

感谢您的更新比下面的答案'filter'漂亮多得到它。尽管这也可以起作用:) – MMachinegun 2014-06-02 15:00:48

+1

您能否提供一个'$ .filter'的示例来获取'$ .parseHTML'输出的最外层节点?你如何将parseHTML的输出传递给'$ .filter'?它只接受一个参数。 – Ade 2014-11-20 17:33:17

回答

22

您需要先创建一个DOM元素,以便首先附加.parseHTML()的结果,以便它c在jQuery可以遍历它之前创建一个DOM树并找到div#app-container

var tempDom = $('<output>').append($.parseHTML(str)); 
var appContainer = $('#app-container', tempDom); 

我用你的榜样,并得到它的工作:http://jsfiddle.net/gEYgZ/

.parseHTML()功能似乎窒息了<script>标签,所以我不得不将其删除。

PS。显然<output>是不是一个真正的HTML标记,只是用它为例子

+0

是的,你说得对。它需要附加在_first_之后,然后进行搜索。在这种情况下,jQuery没有找到顶级标签。我想知道为什么。 – 2013-03-14 07:59:02

+0

谢谢你的小提琴。我正在考虑制作一个。张贴之前应该做到这一点。 – 2013-03-14 08:00:02

+0

@dimadima这不是关于顶级标签,'$ .parseHTML(str)'的结果还不是DOM元素。如果你愿意的话,它可能处于炼狱状态,需要被带入DOM世界。可以通过'.append()','.html()'等等 – sweetamylase 2013-03-14 08:01:12

0

我想你应该有这样尝试:

$('body', $.parseHTML(data)) 
+0

这与我的问题无关。我的问题是'div#app-container'没有被jQuery找到。我很感激你的时间,但如果你有更多的时间,请重新阅读这个问题。 – 2013-03-14 07:47:11

+0

呃...它只是一个建议尝试这个。 – Jai 2013-03-14 07:51:38

+0

这也是一个空数组。 – 2013-03-14 07:52:37

8

你可以试试这个:

$($.parseHTML('<div><span id="foo">hello</span></div>')).find('#foo'); 

用于与<你可以更短的代码只是开头的字符串:

$('<div><span id="foo">hello</span></div>').find('#foo'); 
+0

嗯,没错,但怎么样'$($。parseHTML( '

hello
'))。找到(' DIV')'?产生一个空数组。无论如何,'.find()'方法上面是一样的'$( '#富',$($。parseHTML( '
hello
')))' – 2013-03-14 07:56:47

+0

@dimadima这对我归元,我测试了我之前发布答案。 – jcubic 2013-03-14 07:59:18

+1

是的,它返回'#foo',但返回'div'吗? – 2013-03-14 08:01:24

2

恰好碰到了这一点。

原来$.parseHTML回报香草DOM元素Array,而且不支持的jQuery找到你想要的。

我觉得这是一个HTML字符串转换为一个jQuery对象的干净的解决方案:

var html = '<div><span id="foo">hello</span></div>'; 
var $foo = $(html).find('#foo'); 

注意:您可能希望使用在你的HTML字符串$.trim这样的jQuery没有得到通过空格迷惑。

1

它不会有什么与HTML不是DOM的一部分。只是出于某种原因,解析的HTML中的顶级标记无法找到。如果您正在查找的元素包裹在另一个标签中,那么该查找会按照您的预期工作。顺便说一句,包装在身体标签元素将无法正常工作,但所有其他人我已经尝试工作正常。

var bad = $.parseHTML('<ul><<li><one/li>/<li>two</li></ul>'); 
console.log($(bad).find('li').length); //will be 2 
console.log($(bad).find('ul').length); //will be 0 

var good = $.parseHTML('<div><ul><<li><one/li>/<li>two</li></ul></div>'); 
console.log($(good).find('li').length); //will be 2 
console.log($(good).find('ul').length); //will be 1 

下面是展示小提琴:http://jsfiddle.net/ndnnhf94/

0

我相信这会工作,特别是如果你特别需要找到由ID的元素;

function findInParsed(html, selector){ 
    return $(selector, html).get(0) || $(html).filter(selector).get(0); 
} 

如果你所需要的对象的jQuery的版本,那么你可以用这个

function findInParsed(html, selector){ 
    var check = $(selector, html).get(0); 
    if(check) 
     return $(check); 
    check = $(html).filter(selector).get(0) 
    return (check)? $(check) : false; 
}