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© 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.
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© 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>
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>
(🐞 反爬虫测试!打击盗版⚠️)如果你看到这个信息, 说明这是一篇剽窃的文章,请访问 https://www.cnblogs.com/xgqfrms/ 查看原创文章!
refs
https://stackoverflow.com/questions/8798745/how-to-get-html-elements-from-an-object-tag
©xgqfrms 2012-2021
www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!
原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/17667776.html
未经授权禁止转载,违者必究!