jQuery class selector for SVG in XHTML
The following code works (in console you can see two log messages as th开发者_开发问答e elements detected) if the file is named as *.html, but the elements are not selected if I name to *.xhtml. Why do these behave differently? The issue is only when the class name is included in the selector, so $("#cvs rect")
works in both case,
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE HTML><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Test</title>
<meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
</head><body>
<svg id="cvs" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 100" version="1.1" baseProfile="full">
<rect class="drag resize" x="50" y="30" width="50" height="30" />
<rect class="drag resize" x="5" y="5" width="90" height="50" />
</svg>
<script>
$(document).ready(function() {
$("#cvs rect.resize").each(function() {
console.log("selected");
});
});
</script>
</body></html>
This looks to be a ~bug in jQuery or Sizzle. Here's a pared-down test case showing the problem:
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />
<title>Create SVG Elements HTML</title>
</head><body>
<svg xmlns="http://www.w3.org/2000/svg">
<circle r="200" class="face" fill="red" />
</svg>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
<script type="text/javascript"><![CDATA[
console.log( document.getElementsByClassName('face').length ); // 1
console.log( document.querySelectorAll('circle.face').length ); // 1
console.log( $('circle').length ); // 1
console.log( $('.face').length ); // 0
console.log( $('circle.face').length ); // 0
console.log( $('circle[class~="face"]').length ); // 1
]]></script>
</body></html>
Results are consistent across Chrome v11, Firefox v4, Safari v5, and IE9.
The problem appears to be that jQuery is not properly querying class
attributes on elements within another namespace. Using the "attribute contains word" selector ~=
you can use jQuery to find these elements.
Edit: The root cause of this is likely documented in this answer; summarized, the problem is that SVG DOM specifies that the class
attribute (as with many other) is not a static value accessible via className
, but rather an SVGAnimatedString
which has .baseVal
and .animVal
properties needed to fetch the actual string value of the class.
<rect>
elements are not self-closing, these lines need closing:-
<rect> </rect>
I don't think *.xhtml is a valid extension; XHTML is usually used within a standard .htm or .html file anyway, just specify it in your doctype.
http://www.webheadstart.org/xhtml/faq/index.html
精彩评论