【问题标题】:jQuery() not finding elements in jQuery.parseHTML() resultjQuery() 在 jQuery.parseHTML() 结果中找不到元素
【发布时间】:2019-07-11 17:07:50
【问题描述】:

我正在使用 QUnit 编写测试,并使用 $.ajax() 为我本地运行的开发站点中的一些测试提取 HTML:

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$(selector, $.parseHTML(data)) 将不返回任何内容!我想要一个 jQuery 对象作为 div#app-container 元素。

这就是要我的命:

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

这里发生了什么?似乎发生的事情是$ 没有查看$.parseHTML(data)$($.parseHTML(data))) 返回的任何顶级元素,而只是查看它们的子元素。

如何从这个$.parseHTML(data) 获取div#app-containerjQuery 对象?

回答

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

【问题讨论】:

  • 感谢您对filter 的更新,这比下面的答案要好得多。虽然这也行得通:)
  • 您能否提供一个示例,说明$.filter 正在努力从$.parseHTML 获取输出的最外层节点?如何将 parseHTML 的输出传递给 $.filter ?它只接受一个参数。

标签: javascript jquery


【解决方案1】:

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

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

我使用了您的示例并使其正常工作:http://jsfiddle.net/gEYgZ/

.parseHTML() 函数似乎卡在了&lt;script&gt; 标签上,所以我不得不删除它们。

PS.显然&lt;output&gt;不是真正的HTML标签,只是用来举例

【讨论】:

  • 是的,你是对的。它需要被附加到 first 的内部,然后进行搜索。在这种情况下,jQuery 没有找到顶级标签。我想知道为什么。
  • 感谢您的提琴。我正在考虑做一个。应该在发布之前完成。
  • @dimadima 不是顶级标签,$.parseHTML(str) 的结果还不是 DOM 元素。如果你愿意的话,它有点像炼狱状态,需要被带入 DOM 世界。通过.append().html() 等。
  • 真的吗?我本以为将其包装在$() 中就足够了。比如,来自jquery.com/upgrade-guide/1.9:如果一个字符串已知为 HTML,但可能以非 HTML 标记的任意文本开头,则将其传递给jQuery.parseHTML(),它将返回一个表示标记的 DOM 节点数组。可以由此创建一个 jQuery 集合,例如:$($.parseHTML(htmlString))。例如,在处理 HTML 模板时,这将被视为最佳实践。"
  • @dimadima 也许可以和 jQuery 的人一起讨论这个问题:P
【解决方案2】:

你可以试试这个:

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

对于以&lt; 开头的字符串,您可以将该代码缩短为:

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

【讨论】:

  • 啊,对,但是$($.parseHTML('&lt;div&gt;&lt;span id="foo"&gt;hello&lt;/span&gt;&lt;/div&gt;')).find('div') 呢?产生一个空数组。反正上面.find()的方法和$('#foo', $($.parseHTML('&lt;div&gt;&lt;span id="foo"&gt;hello&lt;/span&gt;&lt;/div&gt;')))是一样的
  • @dimadima 它为我返回元素,我在发布答案之前进行了测试。
  • @dimadima 它不会找到 div 因为它是 html 的根如果你想找到 div 然后只需使用 $($.parseHTML('&lt;div&gt;&lt;span id="foo"&gt;hello&lt;/span&gt;&lt;/div&gt;')) 并且你得到了 div。
  • 有效。注意双 $
【解决方案3】:

刚刚碰到这个。

原来$.parseHTML 返回一个普通的Array DOM 元素,它不支持你想要的 jQuery 查找。

我认为这是将 HTML 字符串转换为 jQuery 对象的最简洁的解决方案:

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

注意:您可能希望在您的 html 字符串周围使用$.trim,这样 jQuery 就不会被空格混淆。

【讨论】:

    【解决方案4】:

    这与 html 不是 DOM 的一部分没有任何关系。只是无论出于何种原因,在解析的 HTML 中都找不到顶级标签。如果您要查找的元素包含在另一个标签中,则查找将按您的预期工作。顺便说一句,将元素包装在 body 标记中是行不通的,但我尝试过的所有其他元素都可以正常工作。

    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
    

    在 jQuery 1.11 中肯定是这种情况,不确定在以后的版本中会发生什么。这是一个演示:http://jsfiddle.net/ndnnhf94/

    【讨论】:

      【解决方案5】:

      以上答案对我不起作用,但确实如此:

      使用 jQuery.parseHTML 将 HTML 解析为元素数组;然后您就可以将其转换为 jQuery 集合使用过滤器 将集合限制为匹配选择器的元素。

      var html =
      '<td class="test">asd</td>' +
      '<td class="last">jkl</td>';
      var obj = $($.parseHTML(html)).filter('.test');
      

      【讨论】:

        【解决方案6】:

        我认为你应该试试这个:

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

        【讨论】:

        • 这与我的问题无关。我的问题是 jQuery 没有找到 div#app-container。感谢您抽出宝贵时间,但如果您有更多时间,请重新阅读问题。
        • 嗯...这只是一个建议尝试一下。
        • 那也是一个空数组。
        • 发生了什么是$ 没有查看$.parseHTML(data)$($.parseHTML(data))) 返回的任何顶级元素,而只是查看它们的子元素。
        • 为什么不用id 创建一个元素并附加到那个元素中。
        【解决方案7】:

        我相信这会奏效,尤其是当您特别需要通过 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;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-08-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-08-31
          • 2023-03-09
          相关资源
          最近更新 更多