开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜