xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

How to get the SVG document content inside an object tag in JavaScript All In One

How to get the SVG document content inside an object tag in JavaScript All In One

object tag & SVG document

 <object id="svgObject" class="atac-svg-tranlator" data="./texts.svg" type="image/svg+xml" width="400" height="300"></object>
const svgObject = document.getElementById('svgObject');
const svgDoc = svgObject.contentDocument.querySelector("svg")

solution 1

Outside the SVG create an absolute position div as a tooltip container, and add the mouse event listener on SVG texts dynamic set its content to the tooltip.

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <text x="0" y="15" fill="red" id="red1">I love SVG</text>
  <text x="10" y="25" fill="green" id="green2">I love SVG 2</text>
</svg>

PS: The ./texts.svg file must be run on a server without CORS issues.

<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <meta name="author" content="xgqfrms">
    <meta name="generator" content="VS code">
    <script src="https://unpkg.com/@popperjs/core@2"></script>
    <script src="https://unpkg.com/tippy.js@6"></script>
    <style lang="css">
      #tip {
        position: absolute;
        top: 0;
        left: 0;
        background: #000;
        color: #0f0;
      }
      #svgObject {
        margin-top: 100px;
        margin-left: 100px;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div id="tip">
        <span id="hack"></span>
      </div>
      <object id="svgObject" class="atac-svg-tranlator" data="./texts.svg" type="image/svg+xml" width="400" height="300"></object>
    </div>
    <footer>
      <p>copyright&copy; xgqfrms 2023</p>
    </footer>
    <script>
      window.addEventListener("load", (event) => {
        const body = document.body;
        const tip = document.getElementById('tip');
        const svgObject = document.getElementById('svgObject');
        const svgDoc = svgObject.contentDocument.querySelector("svg")
        if (svgDoc) {
          const textElements = svgDoc.querySelectorAll('text');
          textElements.forEach(function(textElement) {
            const text = textElement.textContent
            textElement.addEventListener('mouseleave', (event) => {
              tip.innerHTML = `<span id="hack"></span>`
              tip.setAttribute(`style`, `top: 0px; left: 0px;`)
            })
            textElement.addEventListener('mouseenter', (event) => {
              const y = event.screenY - event.clientY - 80
              const x = event.screenX - event.clientX + 18
              tip.innerHTML = `<span id="hack">${text}</span>`
              tip.setAttribute(`style`, `top: ${y}px; left: ${x}px;`)
              // title property not work ❌
              textElement.setAttribute('title', text);
              textElement.setAttribute('style', `cursor: pointer;`);
            })
            textElement.addEventListener('click', (event) => {
              console.log(`click`, event)
            })
            // tippy(textElement, {
            //   content: text,
            //   placement: 'top',
            // });
            // Bug reproduction steps, the mouse hovers over the svg text
            // ❌ core@2:5 Uncaught TypeError: Cannot read properties of null (reading 'body')
            // https://atomiks.github.io/tippyjs/
            // https://github.com/atomiks/tippyjs/issues/1137
          });
        } else {
          console.log('SVG document not loaded');
        }
      });
    </script>
  </body>
</html>

image

solution 2

Add the mouse event listener on SVG texts, then dynamic create an SVG <Title> tag, and insert it into SVG with text content.

Text in a <title> element is not rendered as part of the graphic, but browsers usually display it as a tooltip.

<!DOCTYPE html>
<html lang="zh-Hans">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <meta name="author" content="xgqfrms">
  <meta name="generator" content="VS code">
  <script src="https://unpkg.com/@popperjs/core@2"></script>
  <script src="https://unpkg.com/tippy.js@6"></script>
  <style lang="css">
    #svgObject {
      margin-top: 100px;
      margin-left: 100px;
    }
  </style>
</head>
<body>
  <div class="container">
    <object id="svgObject" class="atac-svg-tranlator" data="./texts.svg" type="image/svg+xml" width="400" height="300"></object>
  </div>
  <footer>
    <p>copyright&copy; xgqfrms 2023</p>
  </footer>
  <script>
    window.addEventListener("load", (event) => {
      const body = document.body;
      const svgObject = document.getElementById('svgObject');
      const svgDoc = svgObject.contentDocument.querySelector("svg")
      if (svgDoc) {
        const textElements = svgDoc.querySelectorAll('text');
        textElements.forEach(function(textElement) {
          const text = textElement.textContent
          textElement.setAttribute('style', `cursor: pointer;`);
          textElement.addEventListener('mouseenter', (event) => {
            if(!textElement.children.length) {
              textElement.insertAdjacentHTML(`beforeend`, `<title>${text}</title>`)
            }
          })
          // tippy(textElement, {
          //   content: text,
          //   placement: 'top',
          // });
          // Bug reproduction steps, the mouse hovers over the svg text
          // ❌ core@2:5 Uncaught TypeError: Cannot read properties of null (reading 'body')
          // https://atomiks.github.io/tippyjs/
          // https://github.com/atomiks/tippyjs/issues/1137
        });
      } else {
        console.log('SVG document not loaded');
      }
    });
  </script>
</body>
</html>

image

demos

image

<!DOCTYPE html>
<html lang="en-us">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <!-- <script src="https://d3js.org/d3.v4.js"></script> -->
    <!-- <link rel="stylesheet" href="https://unpkg.com/tippy.js@6/animations/scale.css"/> -->
    <script src="https://unpkg.com/@popperjs/core@2"></script>
    <script src="https://unpkg.com/tippy.js@6"></script>
    <style lang="css">
      #tip {
        /* position: fixed; */
        position: absolute;
        top: 0;
        left: 0;
        background: #000;
        color: #0f0;
      }
    </style>

  </head>
  <body>
    <div class="container">
      <section>
        <button id="myButton">My button</button><br>
        <a href="" title="link 😂" alt="link">link</a> <br>
        <span title="span 😂" alt="span" id="span">span</span><br>
        <input title="button 😂" type="button" value="btn" />
        <div title="😂 div">div</div>
      </section>
      <div id="tip">
        <span id="hack"></span>
      </div>
      <section>
        <svg xmlns="http://www.w3.org/2000/svg" version="1.1" title="svg 😂">
          <text x="0" y="15" fill="pink" id="pink" title="text 😂">I love SVG<title>Tooltip 2</title></text>
        </svg>
      </section>
     <object id="svgObject" class="atac-svg-tranlator" data="./shit.svg" type="image/svg+xml" width="400" height="300"></object>
     <!-- <object id="svgObject" class="atac-svg-tranlator" data="./texts.svg" type="image/svg+xml" width="400" height="300"></object> -->
     <object id="svgObject" class="atac-svg-tranlator" data="https://cdn.xgqfrms.xyz/svg/texts.svg" type="image/svg+xml" width="400" height="300"></object>
     <!-- <object id="svgObject" class="atac-svg-tranlator" data="https://cdn.xgqfrms.xyz/svg/seat.svg" type="image/svg+xml" width="400" height="300"></object> -->
     <!-- <object id="svgObject" class="atac-svg-tranlator" data="./text3.svg" type="image/svg+xml" width="400" height="300"></object> -->
     <!-- <object id="svgObject" class="atac-svg-tranlator" data="https://www.runoob.com/try/demo_source/text3.svg" type="image/svg+xml" width="400" height="300"></object> -->
     <!-- <object id="svgObject" class="atac-svg-tranlator" data="https://cdn.xgqfrms.xyz/icons/html5.svg" type="image/svg+xml" width="400" height="300"></object> -->
     <!-- <object id="svgObject" class="atac-svg-tranlator" data="https://cdn.xgqfrms.xyz/icons/vscode-dev.svg" type="image/svg+xml" width="400" height="300"></object> -->
     <!-- <object id="svgObject" class="atac-svg-tranlator" data="./src/assets/images/test.svg" type="image/svg+xml" width="400" height="300"></object> -->
    </div>
        <!-- <script id="" src="dist/app.js"></script> -->
        <!-- <script>

const svgObject = document.getElementById('svgObject');

svgObject.addEventListener('load', function() {
  const svgDoc = svgObject.contentDocument;
  window.svgDoc = svgDoc
  console.log(`svgObject.contentDocument`, svgObject.contentDocument)
  console.log(`svgObject.innerHTML`, svgObject.innerHTML)
  if (svgDoc) {
    const textElements = svgDoc.querySelectorAll('text');
    console.log(`textElements`, textElements)
    // textElements.forEach(function(textElement) {
    //   // Create Tippy tooltip for each text element
    //   tippy(textElement, {
    //     content: textElement.textContent,
    //     appendTo: svgDoc.documentElement,
    //     placement: 'top',
    //   });
    // });
  } else {
    console.log('SVG document not loaded');
  }
});
        </script> -->

        <script>


          // window.addEventListener ✅
          // window.addEventListener("load", (event) => {
          document.addEventListener('DOMContentLoaded', function() {
            tippy('#myButton', {
              content: 'My tooltip!',
            });
            /* tippy('#span', {
              content: 'span tooltip!',
            });
            console.log("page is fully loaded");
            const body = document.body;
            const tip = document.getElementById('tip'); */
            // window.obj = {
            //   text: '❌'
            // }
            // tippy('#tip', {
            //   content: window.obj.text,
            //   // appendTo: tip,
            // });
   /*          const svgObject = document.getElementById('svgObject');
            console.log('✅ onload')

            console.log(`svgObject.contentDocument`, svgObject.contentDocument)
            console.log(`svgObject.innerHTML`, svgObject.innerHTML)
            console.log(`children`, svgObject.contentDocument.children)
            console.log(`body`, svgObject.contentDocument.body)
            console.log(`svg`, svgObject.contentDocument.querySelector("svg"))
            const svgDoc = svgObject.contentDocument.querySelector("svg") */
            const svgObject = document.getElementById('svgObject');
            console.log(`svgObject.innerHTML`, svgObject.innerHTML)
            console.log(`children`, svgObject.contentDocument.children)
            console.log(`body`, svgObject.contentDocument.body)
            console.log(`svg`, svgObject.contentDocument.querySelector("svg"))
            const svgDoc = svgObject.contentDocument.querySelector("svg")

            svgObject.addEventListener('load', function() {
              const svgDoc = svgObject.contentDocument; // Get the SVG document from the object element
              console.log(`❌ svgDoc`, svgDoc)
              if (svgDoc) {
                // Find and initialize tooltips for text elements within the SVG
                const textElements = svgDoc.querySelectorAll('text');
                textElements.forEach(function(textElement) {
                  // Create Tippy tooltip for each text element
                  tippy(textElement, {
                    content: textElement.textContent,
                    appendTo: svgDoc.documentElement,
                    placement: 'top',

                  });
                });
              } else {
                console.log('SVG document not loaded');
              }
            });
/*             window.svgDoc = svgDoc
            if (svgDoc) {
              const textElements = svgDoc.querySelectorAll('text');
              console.log(`textElements`, textElements)
              textElements.forEach(function(textElement) {
                // Create Tippy tooltip for each text element
                const text = textElement.textContent
                console.log(`textElement.textContent`, text);
                console.log(`textElement.innerHTML`, textElement.innerHTML);
                // textElement.addEventListener('mouseover', () => {
                //   console.log(`hover ✅`, textElement.id)
                // })
                textElement.addEventListener('mouseleave', (event) => {
                  console.log(`mouseleave 👻`)
                  // clear
                  // tip.innerHTML = `<mark>👻</mark>`
                  tip.innerHTML = `<span id="hack"></span>`
                  tip.setAttribute(`style`, `top: 0px; left: 0px;`)
                  // tippy('#hack', {
                  //   content: '',
                  // });
                })
                textElement.addEventListener('mouseenter', (event) => {
                  // console.log(`event =`, event)
                  const y = event.screenY - event.clientY - 80
                  const x = event.screenX - event.clientX + 18
                  console.log(`x, y, event =`, x, y, `\n`, event)
                  // screenX: 58, screenY: 368, clientX: 50, clientY: 0
                  // offsetX:51 offsetY: 1 pageX:50 pageY:0
                  console.log(`mouseenter ✅`, textElement.id)
                  // textElement.title = text;
                  textElement.setAttribute('title', text);
                  // tip.innerHTML = `<mark>${text}</mark>`
                  tip.innerHTML = `<span id="hack">${text}</span>`
                  tip.setAttribute(`style`, `top: ${y}px; left: ${x}px;`)
                  // window.obj.text = text;
                  // tippy('#tip', {
                  //   content: text,
                  //   // appendTo: tip,
                  // });
                  // tip.setAttribute(`left`, event.pageX)
                  // tip.setAttribute(`top`, event.pageY)
                  // textElement.innerHTML = "✅";
                  // tippy(textElement, {
                  // // tippy(`#${textElement.id}`, {
                  //   content: text,
                  //   // appendTo: svgDoc.documentElement,
                  //   appendTo: svgDoc,
                  //   // appendTo: svgObject,
                  //   // appendTo: textElement,
                  //   // appendT: textElements,
                  //   placement: 'top',
                  //   // arrow: true,
                  //   // animation: 'fade',
                  // });
                })
                textElement.addEventListener('focus', () => {
                  console.log(`focus ✅`, textElement.id)
                })
                // ❓ tooltips, https://atomiks.github.io/tippyjs/
                //
                // tippy(textElement, {
                // // tippy(`#${textElement.id}`, {
                //   content: text,
                //   // appendTo: svgDoc.documentElement,
                //   // appendTo: svgDoc,
                //   // appendTo: svgObject,
                //   // appendTo: textElement,
                //   placement: 'top',
                //   // arrow: true,
                //   // animation: 'fade',
                // });
                // bug 复现步骤,鼠标悬停在 svg 文字上方
                // ❌ core@2:5 Uncaught TypeError: Cannot read properties of null (reading 'body')
              });
            } else {
              console.log('SVG document not loaded');
            }
 */
            // svgObject.addEventListener('onload', function() {
            // svgObject.addEventListener('load', function() {
            //   console.log('\n❌')
            //   const svgDoc = svgObject.contentDocument;
            //   window.svgDoc = svgDoc
            //   console.log(`svgObject.contentDocument`, svgObject.contentDocument)
            //   console.log(`svgObject.innerHTML`, svgObject.innerHTML)
            //   console.log(`svg`, svgObject.contentDocument.children)
            //   console.log(`svg`, svgObject.contentDocument.body)
            //   console.log(`svg`, svgObject.contentDocument.querySelector("svg"))
            //   if (svgDoc) {
            //     const textElements = svgDoc.querySelectorAll('text');
            //     console.log(`textElements`, textElements)
            //     // textElements.forEach(function(textElement) {
            //     //   // Create Tippy tooltip for each text element
            //     //   tippy(textElement, {
            //     //     content: textElement.textContent,
            //     //     appendTo: svgDoc.documentElement,
            //     //     placement: 'top',
            //     //   });
            //     // });
            //   } else {
            //     console.log('SVG document not loaded');
            //   }
            // });
          });
                </script>
  </body>
</html>

(🐞 反爬虫测试!打击盗版⚠️)如果你看到这个信息, 说明这是一篇剽窃的文章,请访问 https://www.cnblogs.com/xgqfrms/ 查看原创文章!

refs

https://stackoverflow.com/questions/77005977/tippy-js-when-svg-is-embedded-in-an-html-object#77005977

https://stackoverflow.com/questions/8798745/how-to-get-html-elements-from-an-object-tag

https://stackoverflow.com/questions/21703318/is-it-possible-to-enhance-the-default-appearance-of-svg-title-tooltip



©xgqfrms 2012-2021

www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!


posted @ 2023-08-31 18:03  xgqfrms  阅读(29)  评论(12编辑  收藏  举报