2016-12-23 18 views
8

Tôi đang cố gắng tải một tệp svg bên ngoài và sau đó viết thêm các phần tử SVG trên đầu trang của nó. Khi tôi làm, tôi nhận được lỗi "Không thể thực hiện 'appendChild' trên 'Node': Chỉ có một phần tử trên tài liệu được cho phép." khi tôi kiểm tra trong Chrome.Không thể thực hiện 'appendChild' trên 'Nút': Chỉ có một phần tử trên tài liệu được phép

Đây là HTML:

<html> 
    <head> 
    <link rel="stylesheet" type="text/css" href="css/index.css"> 
    <title>Hello World</title> 
    </head> 
    <body> 
     <svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="mySvg"> 
     <circle cx="40" cy="30" r="15" fill="#FF00FF" 
      stroke="#000000" stroke-width="2" /> 
     </svg> 
     <object data="img/drawing.svg" type="image/svg+xml" 
     align="center" id="svgDrw" height="80vh"></object> 
    <script type="text/javascript" src="js/problem.js"></script> 
    </body> 
</html> 

Dưới đây là problem.js:

var svgXtraDoc; 
var d = document.getElementById("svgDrw"); 

d.addEventListener("load",function(){ 

    // get the inner DOM 
    svgXtraDoc = d.contentDocument; 
    // get the inner element by id 
    svgRect1 = svgXtraDoc.getElementById("MyRect1"); 
    svgRect2 = svgXtraDoc.getElementById("MyRect2"); 
}, false); 


function addRect() { 
    var svgRect = document.createElementNS("http://www.w3.org/2000/svg", 
    "rect"); 
    svgRect.setAttribute("x", 100); 
    svgRect.setAttribute("y", 100); 
    svgRect.setAttribute("width", 100); 
    svgRect.setAttribute("height", 100); 
    svgRect.style.fill = "red"; 
    // mySvg.appendChild(svgRect); 
    svgXtraDoc.appendChild(svgRect); 
} 

document.getElementById("mySvg").addEventListener("click", addRect); 

... và đây là drawing.svg, tước một số các cruft Inkscapy:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<!-- Created with Inkscape (http://www.inkscape.org/) --> 

<svg 
    xmlns:dc="http://purl.org/dc/elements/1.1/" 
    xmlns:cc="http://creativecommons.org/ns#" 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:svg="http://www.w3.org/2000/svg" 
    xmlns="http://www.w3.org/2000/svg" 
    width="29.02857mm" 
    height="37.092064mm" 
    viewBox="0 0 102.85714 131.42857" 
    id="svg2" 
    version="1.1"> 
    <g 
    id="layer1" 
    transform="translate(-205.71428,-218.07649)"> 
    <rect 
     style="stroke:none;fill-opacity:1;fill:#5eb056" 
     id="MyRect1" 
     width="102.85714" 
     height="131.42857" 
     x="205.71428" 
     y="218.07649" /> 
    <rect 
     style="fill:#000000;stroke:none;fill-opacity:1" 
     id="MyRect2" 
     width="42.857143" 
     height="65.714287" 
     x="231.42857" 
     y="252.3622" /> 
    </g> 
</svg> 

Lỗi phát sinh khi bạn nhấp vào vòng tròn: hình chữ nhật sẽ xuất hiện trong hình vẽ hai chữ nhật được nhập không xuất hiện và thông báo lỗi "Không thể thực thi 'appendChild' trên 'Nút': Chỉ có một phần tử trên tài liệu được phép". được hiển thị trong bảng điều khiển.

Nếu tôi thay đổi điều này để hình chữ nhật được thêm vào svg chứa vòng tròn, tức là bằng cách bỏ ghi chú dòng "// mySvg.appendChild (svgRect);", thì hình chữ nhật xuất hiện thành công.

Tôi cũng biết rằng tệp vẽ đang tải thành công, vì trong mã khác (không bao gồm ở đây vì lý do ngắn gọn) tôi có thể thay đổi màu của hình chữ nhật trong tệp đó. Vì vậy, có vẻ như tôi có thể truy cập các phần tử hiện có trong tệp nhưng không thêm phần tử.

Có điều gì đó về SVG được tải bên ngoài so với SVG nội tuyến mà tôi không tính đến không?

Một điều cuối cùng - đây là ứng dụng Cordova vì vậy tôi muốn giữ cho nó nhỏ, vì vậy các giải pháp JavaScript tinh khiết được ưu tiên. Tôi sẽ sử dụng JQuery hoặc SnapSVG nếu tôi có nhưng có vẻ như nhu cầu của tôi là đủ đơn giản rằng nó sẽ có thể làm điều này mà không có thư viện bên ngoài.

+0

Tôi vừa mới làm việc một cách xung quanh vấn đề của tôi - tôi muốn thêm vòng tròn cho biết vị trí sự kiện, vì vậy tôi chỉ có thể đặt chúng trong tệp gốc với đột quỵ và điền vào không và sau đó hiển thị chúng vào thời điểm thích hợp, thay vì tạo và thêm chúng khi sự kiện diễn ra. Tôi vẫn muốn được trả lời câu hỏi như được hỏi. –

Trả lời

10

Có sự khác biệt giữa nút gốc của tài liệu và phần tử tài liệu. Những gì bạn muốn là phần tử tài liệu <svg>, nhưng .contentDocument sẽ đưa bạn nút gốc.

Nút gốc là cấp độ phân cấp cao hơn nữa. Điều này có nghĩa là phần tử tài liệu <svg> nằm bên trong nút gốc và nút gốc chỉ có thể có phần tử con <svg> này.

Để có được các yếu tố tài liệu, thực hiện điều này:

svgXtraDoc = d.contentDocument.documentElement; 
+0

Hoạt động hoàn hảo, cảm ơn rất nhiều! –

+0

Cảm ơn bạn rất nhiều! – jojojohn

1

Trong trường hợp của tôi, DOM đã phàn nàn vì tôi đã cố gắng để thêm một đứa trẻ trong tài liệu tự:

document.appendChild(myElement); 

Tôi đã giải quyết vấn đề này bằng cách tham chiếu đến thẻ body:

document.body.appendChild(logger); 
Các vấn đề liên quan