I have below tags inside a SVG:
<g>
<use x="10" y="14" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:actuate="onRequest" id="PL-1-02" xlink:show="replace" xlink:href="#sfseat" />
</g>
<rect x="43" y="18" width="25" style="fill:rgb(192,192,192); stroke:none;" rx="2" ry="2" height="30" />
<text x="18" y="35" style="stroke:rgb(0,0,0); stroke-width:0.5;">
02
</text>
When I click on the text tag then I have to change the color of svg. Please suggest how can I get g element on click text tag in javascript.
Interestingly, this can be solved without any Javascript. SMIL animations have the ability to be triggered by events. You can use a simple <set fill="freeze">
tag as a child of the rectangle to change the value of an attribute or CSS property permanently. The element to be clicked needs to have an id
attribute, and then you can add a begin="myId.click"
to the <set>
:
<svg viewBox="0 15 100 50"> <rect x="43" y="18" width="25" rx="2" ry="2" height="30" style="fill:rgb(192,192,192); stroke:none;"> <set attributeName="fill" to="rgb(192,0,0)" begin="trigger02.click" fill="freeze" /> </rect> <text id="trigger02" x="18" y="35" style="stroke:rgb(0,0,0); stroke-width:0.5;cursor:pointer"> 02 </text> </svg>
As suggested in Radical Edward's answer you could edit the fill attribute of the SVG (or, probably better, the rect
) element – you'll probably get cleaner results and better portability by separating the styles though.
Add a style element and define your styles separately:
<svg>
<style>
rect {
stroke: none;
fill: rgb(192,192,192);
}
rect.active {
fill: rgb(255, 20, 20);
}
</style>
<!-- The rest of your SVG -->
<!-- The rect element with the inline style removed -->
<rect
x="43"
y="18" width="25"
rx="2"
ry="2"
height="30"
/>
</svg>
In order to indentify the text element and the rect, we'll give both of them a unique ID:
<rect
id="rect1"
x="43"
y="18"
width="25"
rx="2"
ry="2"
height="30"
/>
<text
id="text1"
x="18"
y="35"
style="stroke:rgb(0,0,0); stroke-width:0.5;"
>
Then we'll add an event listener on the text element:
var textElement = document.querySelector('#text1');
var rect = document.querySelector('#rect1');
textElement.addEventListener('click', function() {
rect.classList.add('active');
});
The above will work down to IE11, if you're targeting modern browsers only or using a transpiler like Babel you can use a more modern ES6+ syntax with const
and arrow functions; for older browsers (IE10 and below) you'll need to polyfill or use other workarounds, see the chapter "Legacy Internet Explorer and attachEvent" on MDN .
fill
attribute's valueInstead of using a style element, you could also hard-code the rect's fill attribute and then modify it:
<rect fill="rgb(195,195,195)" ... />
textElement.addEventListener('click', function() {
rect.setAttribute('fill', 'rgb(255,20,100)');
});
If you don't have access to the contents of the svg and mutliple SVGs you should at least wrap it in an identifiable container (ie with an ID or unique classname) to make sure you're working on the right one – if that's possible
<div class="clickable-svg-container">
<svg .../>
</div>
You'll then have to find the elements you want to watch and/or modify by first selecting your containers (or all the svgs on the page) and then searching inside that:
var containers = document.querySelectorAll('.clickable-svg-container');
// Alternative: Pick all the SVG elements from the current document
// var svgs = document.querySelectorAll('svg');
// Now loop over your selected elements:
containers.forEach(function(container, index) {
var rect = container.querySelector('rect');
var text = container.querySelector('text');
var group = container.querySelector('g');
// now you can set up your event listener as seen above
text.addEventListener(...);
});
Now you can use the rest of the above guide to react to click events. Note that you can still (a) declare the styles for the active class globally (eg in the HTML's <head />
and use the classname to style the modified element or (b) modify the fill
attribute directly on each element.
Read more on the MDN Web Docs for:
let totalUseTags=svg.getElementsByTagName('use');
for(let i=0;i<totalUseTags.length;i++){
let useParentElement=totalUseTags[i];
let textElement=this.getSiblingTextElementOfUseTag(totalUseTags[i].parentElement.nextElementSibling);
useParentElement.parentElement.appendChild(textElement)
}
getSiblingTextElementOfUseTag(g){
let i=1;
while (g) {
if(g.nodeName=='text'){
return g;
}
g = g.nextElementSibling;
i++;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.