[javascript] Javascript로 SVG 요소에 액세스하는 방법

저는 SVG를 엉망으로 만들고 있으며 Illustrator에서 SVG 파일을 만들고 Javascript로 요소에 액세스 할 수 있기를 바랐습니다.

다음은 Illustrator에서 시작되는 SVG 파일입니다 (제거한 파일의 시작 부분에 정크 파일을 추가하는 것 같습니다).

<?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>

보시다시피 각 요소에는 ID가 있으며 Javascript로 개별 요소에 액세스하여 Fill 속성을 변경하고 클릭과 같은 이벤트에 응답 할 수 있기를 바랐습니다.

HTML은 기본입니다.

<!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>

나는 이것이 정말로 두 가지 질문이라고 생각합니다.

  1. Raphael 또는 jQuery SVG와 같은 것을 사용하는 것과는 반대로 이렇게 할 수 있습니까?

  2. 가능하다면 기술은 무엇입니까?


최신 정보

지금은 Illustrator를 사용하여 SVG 파일 을 만들고 Raphaël JS 를 사용하여 경로를 만들고 단순히 SVG 파일에서 포인트 데이터를 복사하여 path()함수에 붙여넣고 있습니다. 포인트 데이터를 수동으로 코딩하여지도에 필요할 수있는 복잡한 경로를 만드는 것은 (내가 아는 한) 엄청나게 복잡합니다.



답변

Raphael 또는 jQuery SVG와 같은 것을 사용하는 것과는 반대로 이런 식으로 할 수 있습니까?

명확히.

가능하다면 기술은 무엇입니까?

이 주석 코드 조각은 다음과 같이 작동합니다.

<!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>

이 기술의 한계는 동일 출처 정책에 의해 제한되므로 파일 alpha.svg과 동일한 도메인에서 호스팅되어야 .html합니다. 그렇지 않으면 객체의 내부 DOM에 액세스 할 수 없습니다.

이 HTML을 실행하기 위해 중요한 것은 IIS, Tomcat과 같은 웹 서버에 호스트 HTML 파일이 필요합니다.


답변

jQuery를 사용하는 경우 $(window).load에는 포함 된 SVG 문서가 아직로드되지 않았을 수 있으므로 기다려야합니다 .$(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);
});


답변

<img>SVG에 태그를 사용하는 경우 해당 내용을 조작 할 수 없습니다 (내가 아는 한).

수락 된 답변에서 알 수 있듯이 사용 <object>은 옵션입니다.

나는 최근에 이것을 필요 gulp-inject로했으며 SVG 파일의 내용을 HTML 문서에 <svg>요소 로 직접 삽입하기 위해 gulp 빌드 중에 사용 했습니다. 그러면 CSS 선택기 및 querySelector/ 를 사용하여 작업하기가 매우 쉽습니다 getElementBy*.


답변