【问题标题】:Find <style> tag by class not working按类查找 <style> 标记不起作用
【发布时间】:2013-06-10 23:39:21
【问题描述】:

我正在使用 AJAX 来获取一些 HTML 标记。我想使用find() 将获取的标记中的一些样式标签(带有类)附加到我自己的文档中。但是,jQuery 似乎不喜欢下面的方法。

(链接因缺乏声誉而被删除)

有人能解释一下为什么这不起作用,并指出我正确的方向吗?

提前谢谢你。

解决方案

  • 首先使其成为原生元素(并删除脚本标签作为额外的预防措施)是可行的。 http://jsfiddle.net/T6QCR/5/
  • 另外,使用innerHTML 而不是.html() 更简单,因为设置innerHTML 不会评估脚本并允许.find() 起作用。 http://jsfiddle.net/T6QCR/8/
  • 另外,下面是 laconbass 的回答。

感谢您的帮助!

【问题讨论】:

    标签: javascript jquery html styles find


    【解决方案1】:

    解析 HTML 块,而不是仅仅将其传递给 jQuery

    ​​>

    来自jQuery function documentation for the case you are using

    (...) 如果字符串看起来是 HTML sn-p,jQuery 会尝试 按照 HTML 的描述创建新的 DOM 元素。然后是一个 jQuery 对象 被创建并返回引用这些元素。你可以执行 此对象上的任何常用 jQuery 方法。

    (...)

    如果 HTML 比没有属性的单个标签更复杂,如 在上面的例子中,元素的实际创建是 由浏览器的 innerHTML 机制处理。在大多数情况下,jQuery 创建一个新元素并设置 元素到传入的 HTML sn-p。

    (...)

    在传入复杂的 HTML 时,某些浏览器可能不会生成 DOM 这完全复制了提供的 HTML 源代码。如前所述,jQuery 使用浏览器的 .innerHTML 属性来解析传递的 HTML 和 将其插入当前文档。在此过程中,一些 浏览器过滤掉某些元素,例如 , , 或 元素。因此,插入的元素可能不会 代表原始字符串传递。

    The documentation 推荐使用$.parseHtml()

    要将字符串显式解析为 HTML,请使用 $.parseHTML() 方法。

    $.filter 而不是 $.find

    如您所述,$.find 不适用于此示例。我已经成功地用$.filter 调用替换了它。

    // this works
    $html.filter('.test');
    // this doesn't works
    $html.find('.test');
    
    // better if you filter also by tag
    // surely you will have more tags other than <style> on the retrieved html
    $html.filter('style.test');
    

    this fiddle 上查看这如何应用于您的示例。

    【讨论】:

    • 非常有趣。我得出以下结果:jsfiddle.net/T6QCR/7。似乎.find() 只是不适用于样式标签。即使它们只是常规节点。 (使用 parseHTML 时)
    • 我看到$.parseHtml(html) 返回一个数组(你的小提琴中只有一维对应&lt;style&gt; 标签)。使用$( $.parseHtml(html) ),您将获得一个查询有length==1 的jQuery 对象并存储&lt;style&gt; DOM 对象。当您执行 $html.find('.test')` 时,您试图在 &lt;style&gt; DOM 对象中找到 '.test',因此找不到任何结果。
    • 你是对的,.find() 不起作用。您可以改用$.filter()。看看我对答案所做的更新。
    【解决方案2】:

    body 未定义,控制台也会以错误的方式给出指示。如果您想使用 jQuery 选择标记主体并附加样式,那么您需要使用适当的选择器:

    $("body").append($style);
    

    【讨论】:

    • 这是代码示例中的错误,我深表歉意。样式仍然不会是.find-ed。见jsfiddle.net/T6QCR/4 当使用console.log($style) 来检查 $style.length 的长度是多少时,它显示为 0。它应该显示为 1 并包含样式元素。
    【解决方案3】:

    &lt;style&gt; 元素不能有class 属性,因为Uncaught SyntaxError: Unexpected identifier

    这段代码应该可以工作:

    var html = '<html><head><style>aaa</style></head></html>';
    var $html = $.parseHTML(html);
    
    $.each($html, function(i, el) {
        if(el.nodeName == "STYLE") {
            $("head").append(el.outerHTML);
            return false;
        }
    });
    

    【讨论】:

    • 感谢您的意见。但是,我需要使用类名,因为我可以使用多个样式块,并且不需要从获取的标记中“导入”。另外,循环遍历 $html 中的每个元素以检查它是否是样式标签不会影响性能吗?
    【解决方案4】:

    我不太确定这是为什么,但它与文档模型及其工作方式有关。您不能只保存一个包含 html 文本的临时变量,您需要将其全部放在以某种方式附加到文档的元素(如 div)中。这个 div 可以从用户的视图中隐藏。

    <html>
      <head>
        <div></div>
      </head>
      <body>
        <script>
          jQuery(document).ready(function($) {
            $('div').hide().html('<html><head><style class="test"></style></head></html>'); // From AJAX request
    
            var $style = $('div').find('.test');
            document.body.appendChild($style[0]);
          });
        </script>
      </body>
    </html>
    

    【讨论】:

    • 转念一想,可能是因为JQuery的find函数使用了document.findElementById,这样的话,该元素肯定在文档中的某处。
    • 我认为这确实是问题所在。我已经尝试过你的答案并且它有效!然而,另一个问题出现了,即在该 div 上设置 HTML 时,HTML 标记中的任何 Javascript 代码都会被执行。在这个答案的帮助下,我设法规避了这个问题:stackoverflow.com/a/6660151/2472719。最终代码为jsfiddle.net/T6QCR/5。感谢您的帮助!
    • 请查看我的答案,并查看 jQuery 文档。对于您使用的案例,jQuery 函数的行为与您的预期不同。
    猜你喜欢
    • 2020-01-06
    • 1970-01-01
    • 2012-07-05
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    • 2015-03-02
    • 2021-09-20
    • 1970-01-01
    相关资源
    最近更新 更多