【问题标题】:Failed to apply CSS via class attribute in XML无法通过 XML 中的类属性应用 CSS
【发布时间】:2012-02-13 15:12:04
【问题描述】:

如果我通过 jQuery 读取 XML,我无法通过 class 属性将 CSS 规则应用于包含的元素。

例子:

我有以下 XML:

<?xml version="1.0" encoding="UTF-8"?>
<div class="alpha">won't be found by CSS!</div>

我通过 AJAX 将它加载到我的 HTML:

$(document).ready(function() {
    $.ajax({
      url: 'snippet.xml',
      type: 'GET',
      dataType: 'xml',
      timeout: 10000,
      error: function() { alert('Error loading XML document'); },
      success: function(xml) {
        $(xml).find('div.alpha').each(function() {
          $(this).appendTo($('#result'));
        });
      }
    });
});

然后,我有以下 CSS:

.alpha {
    color: red;
}

最后,原始的 HTML 看起来像这样(在附加之前):

<div class="alpha">will be found by CSS!</div>
<div id="result"></div>

所以最后会有两个带有class=alpha的div。奇迹是 CSS 将应用于第一个而不是第二个,它来自 XML 输入。我做错了什么?

【问题讨论】:

  • 显示 完整 呈现的 HTML + CSS 定义。不可能。您的 html 可能无效
  • 如果你发回 HTML,你应该把它作为 HTML,而不是 XML。
  • jQuery 现在迫切需要一个$.ajah() 方法和一个$a.ajaj() 方法。
  • @Boltclock:如果您的意思是在返回时期望 HTML 或 javascript,那么您可以使用 dataType 告诉它它将返回什么......这可能对这里有用将数据类型更改为“xml html”,我的阅读应该假设它接收 XML,然后将其转换为 HTML。我不知道它是否会有所帮助,但我只能想象将其视为 HTML 而不是 XML 的事实导致了问题......(有关文档,请参阅 api.jquery.com/jQuery.ajax
  • @Chris:我知道这一点。我只是在取笑 $.ajax() 这个名称是如何指代异步 JavaScript 和 XML :)

标签: javascript jquery html css xml


【解决方案1】:

HTML 不是 XML。 正如 Ryan P 所说,如果您以 HTML 格式发送响应,最简单的解决方案是实际将其作为 HTML 而非 XML 发送。

但是,如果您出于某种原因需要在 XML 响应中发送 HTML 标记,正确的方法是将 HTML 放入 CDATA 部分,然后读取该 CDATA 部分。这是一个修改后的snippet.xml 例如:

<?xml version="1.0" encoding="UTF-8"?>
<response>
    <html><![CDATA[<div class="alpha">will also be found by CSS!</div>]]></html>
</response>

然后,使用 jQuery 的 .find() 方法检索 XML &lt;html&gt; 元素,获取其文本,然后将该文本附加到 #result。这是修改后的success 回调:

success: function(xml) {
  $(xml).find('html').each(function() {
    var html = $(this).text();
    $(html).appendTo($('#result'));
  });
}

带有html 字符串的.appendTo() 调用将如下所示:

$('<div class="alpha">will also be found by CSS!</div>').appendTo($('#result'));

所以它会起作用,给你这个结果 HTML:

<div class="alpha">will be found by CSS!</div>
<div id="result"><div class="alpha">will also be found by CSS!</div></div>

以下是对问题中发生的事情的一些解释,供任何感兴趣的人使用(如果您愿意,可以将“HTML”替换为“XHTML”):

您的 XML &lt;div&gt; 元素不是 HTML &lt;div&gt; 元素;它只是一个 XML &lt;div&gt; 元素,没有任何语义含义。因此,XML 中的class 属性也完全没有语义意义。

CSS 中的类选择器不只是通过名为class 的属性来选择任何元素——其选择器将是属性选择器[class~="alpha"],而不是.alpha。类选择器在 XML 文档中匹配的内容取决于 XML 命名空间所考虑的类属性,它可能命名为 class,也可能不命名。 See the spec.

以下是 jQuery 将 XML 发送回页面时实际生成的内容:

<div class="alpha">will be found by CSS!</div>
<div id="result"><div xmlns="" class="alpha">won't be found by CSS!</div></div>

注意到空白的xmlns 属性了吗?这就是将第二个 div 元素变成某个完全未知的元素的原因,或者我应该说 不存在 XML 命名空间(顺便说一下,the xmlns attribute cannot be blank)。

所以,由于第二个 div 不再是 HTML 元素,CSS 中的类选择器将不会匹配它,因为它的 class 属性不再具有正确的语义以便匹配(因为没有为此元素定义 XML 命名空间)。

为什么 jQuery 的类选择器在这里起作用?

$(xml).find('div.alpha').each(function() {
  $(this).appendTo($('#result'));
});

这是因为 jQuery 将 XML 响应转换为 HTML 作为 DOM 对象,然后 在 DOM 对象上执行选择器,这是因为 jQuery 的类选择器只要求元素的 className。但是,实际附加的内容是作为 XML 附加的,而不是 HTML。

【讨论】:

  • 啊。很有意思。如果无法将响应更改为纯 HTML,您是否认为将数据类型设置为“xml html”可能会有所帮助?我现在没有任何东西可以轻松测试,但看起来它应该尝试将其解释为 HTML 而不是 XML,从而可以避免您描述的问题。
  • @Chris:试过了,没有运气。当我这样做时,jQuery 只是在 $(xml) 默默地失败。
  • 啊。耻辱。感谢您为我检查。 :)
  • @Chris:没问题。实际上,最好的选择是将其作为 HTML 发送。带有&lt;div&gt; 元素的XML 文档仅表示“这是一个带有名为&lt;div&gt; 的根元素的XML 文档”。它没有说明 HTML。
  • 我假设如果您在将 XML 文档加载到 jquery 之前将其 toString ,那么 toString 仍然会将 xmlns 内容放入其中吗?在某些方面看起来确实很愚蠢,处理这样的事情并不容易。但我认为将 HTML 转换为 XML 更错误...... :)
猜你喜欢
  • 2015-11-26
  • 2015-09-25
  • 1970-01-01
  • 1970-01-01
  • 2012-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多