2010-05-02 43 views
65

Tôi đang rối tung với SVG và tôi hy vọng tôi có thể tạo các tệp SVG trong Illustrator và truy cập các phần tử bằng Javascript.Cách truy cập các phần tử SVG bằng Javascript

Dưới đây là các tập tin SVG Illustrator đá ra (Nó cũng dường như để thêm một tải của rác đến đầu của tập tin mà tôi đã gỡ bỏ)

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" 
    width="276.843px" height="233.242px" viewBox="0 0 276.843 233.242" enable-background="new 0 0 276.843 233.242" 
    xml:space="preserve"> 
<path id="delta" fill="#231F20" d="M34.074,86.094L0,185.354l44.444,38.519l80.741-0.74l29.63-25.186l-26.667-37.037 
    c0,0-34.815-5.926-37.778-6.667s-13.333-28.889-13.333-28.889l7.407-18.519l31.111-2.963l5.926-21.481l-12.593-38.519l-43.704-5.185 
    L34.074,86.094z"/> 
<path id="cargo" fill="#DFB800" d="M68.148,32.761l43.704,4.445l14.815,42.963l-7.407,26.667l-33.333,2.963l-4.444,14.074 
    l54.074-1.481l22.222,36.296l25.926-3.704l25.926-54.074c0,0-19.259-47.408-21.481-47.408s-31.852-0.741-31.852-0.741 
    l-19.259-39.259L92.593,8.316L68.148,32.761z"/> 
<polygon id="beta" fill="#35FF1F" points="86.722,128.316 134.593,124.613 158.296,163.872 190.889,155.724 214.593,100.909 
    194.593,52.02 227.186,49.057 246.444,92.02 238.297,140.909 216.074,172.761 197.556,188.316 179.778,169.798 164.963,174.983 
    163.481,197.946 156.815,197.946 134.593,159.428 94.593,151.279 "/> 
<path class="monkey" id="alpha" fill="#FD00FF" d="M96.315,4.354l42.963,5.185l18.519,42.222l71.852-8.148l20.74,46.667l-5.926,52.593 
    l-24.444,34.074l-25.185,15.555l-14.074-19.259l-8.889,2.964l-1.481,22.222l-14.074,2.963l-25.186,22.963l-74.074,4.444 
    l101.481,4.444c0,0,96.297-17.777,109.63-71.852S282.24,53.983,250.389,20.65S96.315,4.354,96.315,4.354z"/> 
</svg> 

Như bạn có thể thấy, mỗi phần tử có một ID, và tôi đã hy vọng có thể truy cập các phần tử riêng lẻ bằng Javascript để tôi có thể thay đổi thuộc tính Fill và phản hồi các sự kiện như nhấp chuột.

HTML đang bog cơ bản

<!DOCTYPE html> 
<html> 
    <head> 
     <title>SVG Illustrator Test</title> 
    </head> 
    <body> 

     <object data="alpha.svg" type="image/svg+xml" id="alphasvg" width="100%" height="100%"></object> 

    </body> 
</html> 

Tôi đoán đây là hai câu hỏi thực sự.

  1. Có thể thực hiện theo cách này, trái với việc sử dụng thứ gì đó như Raphael hoặc jQuery SVG.

  2. Nếu có thể, kỹ thuật là gì?


CẬP NHẬT

Tại thời điểm này, tôi đã viện đến sử dụng Illustrator để tạo ra các tập tin SVG, và tôi đang sử dụng Raphaël JS để tạo đường dẫn và chỉ cần sao chép các dữ liệu điểm từ tệp SVG và dán nó vào hàm path(). Việc tạo các đường dẫn phức tạp như có thể cần thiết cho một bản đồ, bằng cách mã hóa dữ liệu điểm theo cách thủ công là (theo kiến ​​thức của tôi) cực kỳ phức tạp.

Trả lời

82

Có thể thực hiện theo cách này, trái ngược với việc sử dụng một cái gì đó như Raphael hoặc jQuery SVG?

Chắc chắn.

Nếu có thể, kỹ thuật là gì?

đoạn mã chú thích này hoạt động:

<!DOCTYPE html> 
<html> 
    <head> 
     <title>SVG Illustrator Test</title> 
    </head> 
    <body> 

     <object data="alpha.svg" type="image/svg+xml" 
     id="alphasvg" width="100%" height="100%"></object> 

     <script> 
      var a = document.getElementById("alphasvg"); 

      // It's important to add an load event listener to the object, 
      // as it will load the svg doc asynchronously 
      a.addEventListener("load",function(){ 

       // get the inner DOM of alpha.svg 
       var svgDoc = a.contentDocument; 
       // get the inner element by id 
       var delta = svgDoc.getElementById("delta"); 
       // add behaviour 
       delta.addEventListener("mousedown",function(){ 
         alert('hello world!') 
       }, false); 
      }, false); 
     </script> 
    </body> 
</html> 

Lưu ý rằng một hạn chế của kỹ thuật này là nó bị hạn chế bởi chính sách cùng nguồn gốc, vì vậy alpha.svg phải được lưu trữ trên cùng một tên miền như .html tệp, nếu không thì DOM bên trong của đối tượng sẽ không thể truy cập được.

+3

lưu ý về lưu ý của @ jbeard4: trong một số trình duyệt chính sách có nguồn gốc này dẫn đến nhu cầu sử dụng máy chủ (ngay cả khi bạn chỉ sử dụng html và js [serverside]) chính sách truy cập sẽ ngăn truy cập svg. – Michael

16

Trong trường hợp bạn sử dụng jQuery bạn cần phải chờ đợi cho $(window).load, bởi vì tài liệu SVG nhúng có thể không được chưa nạp tại $(document).ready

$(window).load(function() { 

    //alert("Document loaded, including graphics and embedded documents (like SVG)"); 
    var a = document.getElementById("alphasvg"); 

    //get the inner DOM of alpha.svg 
    var svgDoc = a.contentDocument; 

    //get the inner element by id 
    var delta = svgDoc.getElementById("delta"); 
    delta.addEventListener("mousedown", function(){ alert('hello world!')}, false); 
}); 
+3

Trong khi sử dụng mã này, câu trả lời khác này có thể là một phần bổ sung hữu ích: http://stackoverflow.com/a/5990945/1515819 –

+0

Đó là món quà vặt đã cứu mạng tôi. Cảm ơn bạn – Russ

+0

trong trường hợp jQuery bạn nên sử dụng '$ ('# alphasvg'). Load' thay vì' $ (cửa sổ) .load'. Điều này sẽ cho phép bạn thay đổi thuộc tính 'dữ liệu' khi đang bay – vkabachenko

1

Nếu bạn đang sử dụng một thẻ <img> cho SVG, thì bạn không thể thao tác nội dung của nó (theo như tôi biết).

Khi câu trả lời được chấp nhận hiển thị, sử dụng <object> là một tùy chọn.

tôi cần này thời gian gần đây và sử dụng gulp-inject trong ngụm build của tôi để tiêm các nội dung của một tập tin SVG trực tiếp vào tài liệu HTML như một yếu tố <svg>, mà sau đó rất dễ dàng để làm việc với việc sử dụng bộ chọn CSS và querySelector/getElementBy*.

Các vấn đề liên quan