如果我通过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输入。我做错了什么?
答案 0 :(得分:6)
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 <html>
元素,获取其文本,然后将该文本附加到#result
。这是修改后的success
回调:
success: function(xml) {
$(xml).find('html').each(function() {
var html = $(this).text();
$(html).appendTo($('#result'));
});
}
使用.appendTo()
字符串的html
调用将如下所示:
$('<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 <div>
元素不是HTML <div>
元素;它只是一个XML <div>
元素,没有任何语义含义。因此,XML中的class
属性根本没有语义含义。
CSS中的类选择器不仅仅通过名为class
的属性选择任何元素 - 其选择器将是属性选择器[class~="alpha"]
,而不是.alpha
。类选择器在XML文档中匹配的内容取决于XML命名空间认为的哪个类属性,该属性可能命名为class
,也可能不命名。{1}}。 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。