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
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© 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>
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.
// todo
demos

<!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>
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
©xgqfrms 2012-2021
原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!
未经授权禁止转载,违者必究!