【问题标题】:How to extract content from a full page HTML string using jQuery find如何使用 jQuery 查找从整页 HTML 字符串中提取内容
【发布时间】:2014-08-15 21:59:30
【问题描述】:

我有一个 TypeScript 方法,旨在从传入的 Ajax 加载的 HTML 字符串中提取特定的部分视图元素(如果它是完整视图)。

即使字符串包含class="body-content" 的元素,下面的行也返回0 长度:

$(html).find('.body-content')

功能:

    // Extract a panel from a HTML string
    // Allow for multiple child elements
    private _extractPanel(html: string): JQuery
    {
        var $panel: JQuery;

        // Test for full vs. partial view in html
        if (/<html>/i.test(html))
        {
            // Full view: Match the content selector and extract its children
            $panel = $(html).find('.body-content').first().children();
            // *** THE LINE ABOVE GIVES ZERO MATCHES! ***
        }
        else
        {
            // Partial view: Simply return the entire partial view
            $panel = $(html);
        }
        return $panel;
    }

是因为根是 HTML 元素还是我错过的其他东西? $(html) 返回一个长度为 63 的对象,但 find 没有返回匹配项。

这里是来自调试器的html 参数值示例:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Index - My ASP.NET Application</title>
        <link href="/Content/bootstrap.css" rel="stylesheet" />
        <link href="/Content/site.css" rel="stylesheet" />
        <script src="/Scripts/modernizr-2.7.2.js"></script>
    </head>

    <body>
        <div class="navbar navbar-inverse navbar-fixed-top">
            <div class="container">
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span>
 <span class="icon-bar"></span>
 <span class="icon-bar"></span>

                    </button> <a class="navbar-brand" href="/">jQuery Tardis</a>

                </div>
                <div class="navbar-collapse collapse">
                    <ul class="nav navbar-nav">
                        <li><a href="/">Home</a>
                        </li>
                        <li><a href="/Home/About">About</a>
                        </li>
                        <li><a href="/Home/Contact">Contact</a>
                        </li>
                    </ul>
                    <ul class="nav navbar-nav navbar-right">
                        <li><a href="/Account/Register" id="registerLink">Register</a>
                        </li>
                        <li><a href="/Account/Login" id="loginLink">Log in</a>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
        <div class="container body-content">
            <div id="testpanel" class="row">
                <div class="AddinListView"> <a href="/">Home</a>

                     <h2>Tardis transition examples</h2>

                    <ul>
                        <li><a href="/Transition/Transition/1?transition=none" target="_self">No transition (hide/show)</a>
                        </li>
                        <li><a href="/Transition/Transition/1?transition=slide" target="_self">Slide out/in</a>
                        </li>
                        <li><a href="/Transition/Transition/1?transition=fade" target="_self">Fade out/in transtions</a>
                        </li>
                    </ul>
                </div>
            </div>
            <hr />
        </div>
        <footer>
            <p>&copy; 2014 - My ASP.NET Application</p>
        </footer>
    </body>

</html>

跟进:http://jsfiddle.net/TrueBlueAussie/7AvmW/2/

根据Jack的回答,我把上面的JSFiddle放在一起看看是怎么回事。

结果:

基本上$(html)在包含无效子元素的字符串上,如HTMLHEADBODY,这些元素被jQuery解包。效果我发现当然是一个扁平化第一级的BODY只回到成为根元素。

解决方案:

最简单的解决方案是始终使用虚拟父元素创建页面元素以进行搜索。

例如

$html =$('<div>').html(html);

那么任何典型的搜索都可以工作:

$html.find('.selector');

【问题讨论】:

  • 愚蠢的问题,但你试过$(html).filter('.body-content')吗?
  • @Jack:事实证明一点也不傻。返回长度为 1。你能解释一下为什么 DOM 显然是扁平的(为什么会这样)?请张贴作为答案:)

标签: javascript jquery html ajax typescript


【解决方案1】:

当您使用jQuery(html) 时,它会创建一个临时的&lt;div&gt;,然后将其.innerHTML 属性设置为给定的HTML 内容。之后,它会遍历 .childNodes 属性来构建 jQuery 集。

文档还指出:

在传入复杂的 HTML 时,某些浏览器可能无法生成完全复制提供的 HTML 源的 DOM ... 在此过程中,某些浏览器会过滤掉某些元素,例如 &lt;html&gt;&lt;title&gt;&lt;head&gt;元素。因此,插入的元素可能不代表传递的原始字符串。

在 Chrome(可能还有其他浏览器)上,当以这种方式加载整个页面时,临时 &lt;div&gt;.firstChild 属性是 &lt;body&gt; 的第一个子元素:

var d = document.createElement('div');
d.innerHTML = '<html><body><span>hi</span></body></html>';
console.log(d.firstChild); // <span>hi</span>

解决方案

要可靠地使用.find(),您可以将页面加载到临时元素中,如下所示:

var $root = $('<div>', {html: html});
var $items = $root.find('.body-content');

如果你已经知道页面结构,你也可以使用.filter()

var $items = $(html).filter('.body-content');

【讨论】:

  • 这可以解释为什么以前的版本可以工作:var $panel = $('&lt;div/&gt;').html(html);,然后进行检查。
  • $() 的这种奇怪行为是否记录在任何地方?
  • $(html).filter('.body-content').index() 返回7,但不是body的第8个子元素,大致是body中依次找到的第8个元素。我想我现在唯一的问题是:为什么会变平?
  • 我将进行一些实验,例如显示从上述代码和 HTML 创建的层次结构,并返回报告。感谢您的帮助(确实解决了眼前的问题)。
  • 这是我的实验结果......它显然只是让身体变平。值得知道:jsfiddle.net/TrueBlueAussie/7AvmW/2我会用这个信息更新问题。
猜你喜欢
  • 2012-02-29
  • 2021-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-06
  • 2012-07-10
相关资源
最近更新 更多