Development Tip

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

yourdevel 2020. 10. 14. 21:18
반응형

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로 개별 요소에 액세스 할 수 있기를 바랐습니다.

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에 액세스 할 수 없습니다.


In case you use jQuery you need to wait for $(window).load, because the embedded SVG document might not be yet loaded at $(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);
});

If you are using an <img> tag for the SVG, then you cannot manipulate its contents (as far as I know).

As the accepted answer shows, using <object> is an option.

I needed this recently and used gulp-inject during my gulp build to inject the contents of an SVG file directly into the HTML document as an <svg> element, which is then very easy to work with using CSS selectors and querySelector/getElementBy*.

참고URL : https://stackoverflow.com/questions/2753732/how-to-access-svg-elements-with-javascript

반응형