How to avoid shadow-root in MathJax? - javascript

I want to access the SVG code created by MathJax via javascript. Apparently, MathJax put the SVG <path> under shadow-root, which is not directly accessible by javascript. Here is a picture of the elements given by Chrome
If I get the <svg> element by any javascript method, the <path> children will not be included.

You cannot avoid shadow-root. It is not put there by MathJax renderer. It is because of the use tag.
From MDN:
The <use> element takes nodes from within the SVG document, and duplicates them somewhere else.
So MathJax creates svg pathes and gives them ids and reuses them. Say the letter a is rendered into svg, and MathJax stores it in the svg with an id and use it when the letter a is needed to be rendered.
Below example from MDN speaks better.
<svg width="80" height="80" xmlns="http://www.w3.org/2000/svg">
<style>
.classA {
fill: red;
}
</style>
<defs>
<g id="Port">
<circle style="fill: inherit;" r="10"/>
</g>
</defs>
<text y="15">black</text>
<use x="50" y="10" href="#Port" />
<text y="35">red</text>
<use x="50" y="30" href="#Port" class="classA"/>
<text y="55">blue</text>
<use x="50" y="50" href="#Port" style="fill: blue;"/>
</svg>

Related

Is it possible to modify <text> inside <use> SVG

I have this model
<svg id=cardModel viewBox="0 0 100 200">
<rect x="0" y="0" width="100" height="200" fill="transparent" stroke="black"></rect>
<text id="text" x="25" y="125" font-size=100>change me</text>
</svg>
and I want to change the text from
<use href="#cardModel"></use>
I tryed using getElementById but as expected the <use> have no child.
Here's a jsFiddle: https://jsfiddle.net/e6gh07fa/316/
(seems like we can't use namespace in SO scripts)
I know I could use Node.cloneNode() but I want to know if there is another way

Replace svg element with icon

Replace Circle Elements with Icons
I am trying to make my SVG circle elements look like shopping carts. Is there a way to completely replace the definition of a circle element in svg so that it renders a certain icon ?
I'd like
<circle cx="280px" cy="411px" r="4.976112128"></circle>
to look like
<i class="fa fa-shopping-cart"></i>
If not, is there a simpler way to display an icon whenever the circle element is called ?
Thank you very much !
You can try styling the <circle> element with CSS's background-image property:
circle {
background-image: url(http://www.example.com/bck.png);
}
You can define your own elements and call those instead of circles. This way you can still use circles if needed elsewhere.
If you are not looking to use CSS you can use "defs" and "use".
<?xml version="1.0" encoding="utf-8"?>
<!-- from this website http://tutorials.jenkov.com/svg/svg-and-css.html -->
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<defs>
<g id="shopcart">
<image x="499.5" y="242.4" height="40" width="40" id="cart" preserveAspectRatio="none" xlink:href="c:\temp\cart.png" opacity="1" style="pointer-events: none"/>
</g>
</defs>
<use xlink:href="#shopcart" x="10" y="50" transform="translate(150,50)" />
<use xlink:href="#shopcart" x="100" y="250" />
<use xlink:href="#shopcart" x="200" y="250" />
<use xlink:href="#shopcart" x="300" y="250" />
</svg>

SVG Hover State with Multiple Elements

Good afternoon everyone,
I'm defining an SVG on my page with the following defs.
<svg width="0" height="0">
<defs>
<g id="stroke-hexagon">
<polygon fill="#002663" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="12" points="57.8,185 5.8,95 57.8,5 161.8,5 213.8,95 161.8,185 "/>
</g>
<g id="hexagon">
<polygon fill="#006890" points="52,180 0,90 52,0 156,0 208,90 156,180 "/>
</g>
</defs>
</svg>
...and implementing it later in the HTML using this:
<svg width="208px" height="180px" viewBox="0 0 208 180" >
<use xlink:href="#hexagon"></use>
<text class="faicon" x="50%" y="70px" fill="white" font-size="80px" text-anchor="middle">&#xf040</text>
<text text-anchor="middle" x="50%" y="70%" fill="white">Logo Here</text>
</svg>
Works totally fine. I am also able to style the polygon's fill with simple CSS. Looks like this:
#hexagon:hover polygon {
fill:#990000;
}
The hover effect fails, however, whenever the mouse leaves the polygon and instead hovers over either of the 'text' elements within the svg. Is there a way to define a CSS rule that prevents this behavior. Or, would it be better (easier) to change the attribute using JS / jQuery?
Thanks!
Your texts are rendered on top of your polygon and are therefore intercepting mouse events. You should set up a css rule like
text {
pointer-events: none;
}
This will prevent the text from becoming a target of mouse events which should give you the desired hover effect for the polygon.

clip path selection Chrome vs. Firefox

The below selector will not find <clipPath> elements inside <defs> on Chrome (38):
d3.selectAll('defs clipPath')
(This is D3.js code but I suspect underlying querySelectorAll issue)
It works fine on Firefox. Is there a different selector syntax to use that will work on both browsers?
In the example below on Firefox you will see the whole text because the clip path is removed. But on Chrome it will be cut off after 85 pixels because the clip path is not removed.
d3.selectAll('defs clipPath').remove();
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg height="200" width="400">
<defs>
<clipPath id="clip1">
<rect id='tt' x="0" y="0" width="85" height="15"></rect>
</clipPath>
</defs>
<text clip-path="url(#clip1)" x="0" y="15">This text should all be visible once we remove the clip-path</text>
</svg>
As Lars pointed out, this was a webkit bug, and now in Blink it still exists as Issue 237435: querySelectorAll unable to find SVG camelCase elements in HTML
So until it's fixed, using a class selector is probably the best workaround.
d3.selectAll('defs .clippy').remove();
d3.selectAll('defs .clippy').remove();
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg height="200" width="400">
<defs>
<clipPath id="clip1" class='clippy'>
<rect id='tt' x="0" y="0" width="85" height="15"></rect>
</clipPath>
</defs>
<text clip-path="url(#clip1)" x="0" y="15">This text should all be visible once we remove the clip-path</text>
</svg>

visibility is not working for svg g tag

I'm using svg in my application and i using g tag to group the all elements. The first g tag contain more than g tag's, all g tag have their own different visibility style. If i set visibility hidden to the parent g tag it will affect the other g tag elements. I need to hide all the g tag elements by setting visibility to the parent but child elements visibility style should not change.
Here the sample svg
<svg height: "200" width="200">
<g style="visibility:hidden">
<g style="visibility:visible">
<circle cx="100" cy="100" fill="green" r="15" />
</g>
</g>
</svg>
Here is the working Sample.
How can set visibility to the parent g tag without changing it child elements visibility?
Try to use opacity:0 instead of visibility:hidden.
Also, you should look at this example http://svg-whiz.com/svg/HideShow.svg
Hard to understand quite what you are after as the others have said.
I had deleted this answer, as it feels I'm missing your point, but thought it may still help http://jsfiddle.net/rnZss/5/ , it will still display the rect, but hide the circle, so I have left the answer for the moment. What else do you want to happen ?
<svg height:"200" width="200">
<g style="visibility:hidden">
<g style="visibility:hidden">
<circle style="visibility: hidden"cx="100" cy="100" fill="green" r="15"/>
<rect style="visibility: visible" x="50" y="50" width="50" height="50"/>
</g>
</g>
</svg>

Categories

Resources