Related
I have a div tab that contains some text and an svg icon like so
Once I click that tab then it expands like so
Once expanded I want the svg icon to change to something else. So far my code isn't throwing me any errors but also isn't working as expected either. I currently have a function that should change the icon to icon-cancel.svg after the element is clicked nothing changes. Here is what I have.
<!DOCTYPE html>
<html lang="en">
<head>
<style type="text/css">
body {
font-family: 'Roboto Condensed', sans-serif;
}
#side-chat {
position: absolute;
right: 100%;
bottom:50%;
z-index:9999999999999 !important;
width: 150px;
margin-right: -59px;
transform: rotate(-90deg);
display:flex;
justify-content: center;
align-items: center;
color: #ffffff;
border-radius: 10px;
background: rgba(30, 175, 230, 0.5);
text-decoration: none;
padding: 15px;
font-size: 25px;
line-height: 20px;
text-align: center;
}
#olark-box-wrapper {
position: absolute;
z-index:99999999999999 !important;
top: 400px;
right: -300px;
-webkit-transition-duration: 0.3s;
-moz-transition-duration: 0.3s;
-o-transition-duration: 0.3s;
transition-duration: 0.3s;
}
#olark-box-wrapper.chatbox-open {
right: 0
}
#olark-box-wrapper.chatbox-closed {
right: -300px;
}
#habla_window_div {
margin: 0 !important;
}
#side-chat img{
margin-right: 10px;
}
#side-chat:hover,
#side-chat:active {
background: #22a7e5;
}
</style>
</head>
<body>
<div id="olark-box-wrapper">
<!-- Olark chat tab -->
<a id="side-chat" href="javascript:void(0);" onclick="changeClass(); changeImage();">
<img src="icon-chat.svg">
Chat
</a>
<!-- Empty Olark chat box container -->
<div id="olark-box-container"></div>
</div>
<!-- begin olark code -->
<script type="text/javascript" async> ;(function(o,l,a,r,k,y){if(o.olark)return; r="script";y=l.createElement(r);r=l.getElementsByTagName(r)[0]; y.async=1;y.src="//"+a;r.parentNode.insertBefore(y,r); y=o.olark=function(){k.s.push(arguments);k.t.push(+new Date)}; y.extend=function(i,j){y("extend",i,j)}; y.identify=function(i){y("identify",k.i=i)}; y.configure=function(i,j){y("configure",i,j);k.c[i]=j}; k=y._={s:[],t:[+new Date],c:{},l:a}; })(window,document,"static.olark.com/jsclient/loader.js");
/* custom configuration goes here (www.olark.com/documentation) */
//olark.configure('system.hb_detached', true);
olark.configure('box.inline', true);
olark.identify('xxxx-xxx-xx-xxxx');</script>
<!-- end olark code -->
<script type='text/javascript'>
// Javacript function to toggle the class of the chat box wrapper
function changeClass()
{
// Get the HTML object containing the Olark chat box
var olark_wrapper = document.getElementById("olark-box-wrapper");
// If the chat box is already open, close id
if ( olark_wrapper.className.match(/(?:^|\s)chatbox-open(?!\S)/) ) {
olark_wrapper.className = "chatbox-closed";
}
// Otherwise add open the Olark chat box
else {
olark_wrapper.className = "chatbox-open";
}
}
function changeImage(){
document.getElementById('side-chat').src = "icon-cancel.svg";
</script>
</body>
</html>
Your "side-chat" element is the <a> tag which does not have a src.
Try changing getElementById to querySelector to get the image inside instead.
function changeImage(){
document.querySelector('#side-chat img').src = "icon-cancel.svg";
}
after opening the code inside the svg file
path
Copy everything between the svg codes. Then add an onclick event. I think your problem will be solved if you add a click event like svg.innerHTML = what you copied when clicked. Since svg files consist of vectors, the path codes in them determine the icon. When it changes, the icon will also change. I hope I could help.
var svg = document.querySelector('.svg');
svg.addEventListener('click',()=>{
svg.innerHTML=`
<path d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"></path>
`
})
.svg
{
width: 30px;
cursor: pointer;
}
<h2>Click svg</h2>
<svg aria-hidden="true" class="svg" focusable="false" data-prefix="fas" data-icon="bars" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"></path></svg>
In your function you are changing the src of an <a> tag. But you want to change it from the <img> tag. So your selector is wrong.
document.getElementById('side-chat') - outputs the <a> tag
Just add an id to the <img> tag and select this id.
Then you can
document.getElementById('imgId').src = "other img path"
Inside your changeImg() function.
I'm trying to trigger my svg animation when I hover over <span>.
I had to use <span> over my object tag to enable my <a> to work but then I was not able to activate my :hover for my svg.
I've tried all ways to use JavaScript to trigger but am still unable to do it.
Any idea if it is possible or not?
HTML:
<div class="links">
<a href="http://www.facebook.com" title="facebook" class="facebook">
<span id="fbI"><object class="icon" id="faceb" type="image/svg+xml" data="images/fb.svg">
<img src="images/fb.svg" alt="ssRight"/>
</object></span>
</a>
</div>
CSS:
.links a
{
position: relative;
z-index: 1;
}
.links a span
{
display: block;
border-bottom: 3px solid white;
}
.links a object
{
display: inline;
position: relative;
z-index: -1;
}
JavaScript:
$('span#fbI').hover(function(e) {
$('#faceb').trigger('mouseover');
})
OBJECT TAG SVG CODES:
<svg id="Layer_2" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 79.45 79.45">
<defs>
<style>
.cls-1 {
fill: #878484;
}
.cls-2 {
fill: #fff;
}
svg:hover #bg
{
fill: #205599;
}
</style>
</defs>
<title>fb</title>
<g>
<circle id="bg" class="cls-1" cx="39.73" cy="39.73" r="39.73"/>
<path id="fb" class="cls-2" d="M-897.51- 494c0,3.22,0,6.43,0,9.65a1,1,0,0,1- 1.2,1.19c-2.27-.05-4.54,0- 6.81,0a0.89,0.89,0,0,1-1.09-1.09c0-6.43,0-12.86,0-19.3,0-1.17,0-1.16-1.16-1.1- 0.85,0-1.7,0-2.55,0a0.58,0.58,0,0,1-.67-0.69c0-2,0-4,0-6.05a0.64,0.64,0,0,1,.8-0.75c0.88,0,1.77,0,2.65,0a0.76,0.76,0,0,0,1-.94,39.91,39.91,0,0,1,.11-5.85,7.72,7.72,0,0,1,7.65-7.07c2.3-.06,4.6-0.07,6.9-0.14a0.79,0.79,0,0,1,1,1c0,1.86,0,3.72,0,5.58a0.66,0.66,0,0,1-.81.81c-1,0-2.08,0-3.12,0-1.83,0-2.54.72-2.76,2.52-0.13,1.07,0,2.14-.08,3.21a0.66,0.66,0,0,0,.82.82c1.64,0,3.28,0,4.92,0,0.7,0,1,.18.87,0.92-0.23,2-.41,3.95-0.57,5.92a0.7,0.7,0,0,1-.83.76c-1.39,0-2.78,0-4.16,0-0.67,0-.94.11-0.91,0.86,0.06,1.64,0,3.28,0,4.92s0,3.22,0,4.82h0Z" transform="translate(940.65 544.4)"/>
</g>
</svg>
[the highlighted box is the span box, as u can see in my codes, once i display:block; it would cover over my object tag and thus being unable to trigger my hover over for it.][1]
Hi there your desired hover function can be achieved by the following.
$( "span#fbI" ).hover(function() {
$('#fbI').css('background','purple')
});
Here is the jsfiddle for that. I dont know what effect u want so i just turned it purple.
https://jsfiddle.net/qansvs0n/4/
Is it possible to have a responsive path using SnapSVG?
I have built the following experiment on CodePen, any i want my path to be responsive.
I'm building my path using the following code on line 9 of my pen:
var myPathC = snapC.path("M62.9 14.9c-25-7.74-56.6 4.8-60...
However it is this path that i wish to be responsive or re-drawn when the browser window is resized. Anyone know if this is possible and/or have any ideas on how to approach it?
Give the container a viewBox attribute e.g.
<svg id="svgC" width="100%" height="100%" viewBox="0 0 600 400"></svg>
and it will resize with the window.
I've created a working svg that is responsive following the viewport suggestion.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.shapeDemo {
min-height: 200px;
width: 100%;
}
svg .purpleCircle {
fill: darkmagenta;
stroke: black;
stroke-width:5;
}
svg .greenRectangle {
fill: green;
stroke: black;
stroke-width: 5;
}
svg .redRectangle {
fill: red;
stroke: black;
stroke-width: 5;
}
</style>
</head>
<body>
<p>Responsive SVG sandbox</p>
<svg class="shapeDemo" viewBox="0 0 600 400">
<circle cx="75%" cy="10%" r="2.5%" class="purpleCircle"/>
<circle cx="25%" cy="10%" r="1%" class="purpleCircle"/>
<circle cx="50%" cy="22%" r="5%" class="purpleCircle"/>
<rect x="20%" y="30%" width="10%" height="5%" class="redRectangle" />
<rect x="45%" y="55%" width="10%" height="5%" rx="10" ry="10"
class="greenRectangle" />
<ellipse cx="80%" cy="70%" rx="10%" ry="5%" />
<polygon points="100,0 50,50 150,50"/>
</svg>
</body>
</html>
I have embedded an svg file into an html file and can view it in all browsers and platforms. I now want to make specific paths within the svg clickable. I have used an onclick event to perform this function, however, I have only been able to get a javascript alert box to popup when the path is clicked. Instead of the default javascript alert, I need a custom popup which I can then include unique custom text and a hyperlink url for each of the paths. Therefore, each path would have its own text and hyperlink.
Does anyone know the best/easiest way to accomplish this?
Excerpts from my code below:
<script>
function notify(evt){alert(evt.target.id)}
</script>
<style>
path:hover {
fill: #456353; opacity: .5
}
</style>
<svg version="1.1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
x="0px" y="0px" width="771.429px" height="986.584px" viewBox="0 0 771.429 986.584" enable-background="new 0 0 771.429 986.584"
xml:space="preserve">
<g id="Base_map" display="none">
<g id="ahf8dJ.tif" display="inline">
<path onclick="top.notify(evt)" id="Plot1" fill="#BDD5CC" stroke="#939598" stroke-miterlimit="10" d="M585.308,538.849l68.457,19.287l-0.662,6.611
l14.383,3.473l3.637,6.115l-7.439,24.797l52.404,22.814l3.307-4.795c0,0-6.613-1.322-12.729-4.793
c-6.117-3.473-11.076-11.076-16.037-19.176c-4.959-8.102-11.406-24.303-13.885-30.748c-2.48-6.447-9.313-8.322-15.484-11.518
s-6.725-4.848-8.816-8.928c-2.094-4.076-5.182-0.77-9.479,2.756c-4.299,3.527-14.658,0.332-18.734-0.66
c-4.078-0.992-13.006-3.197-19.838-3.748c-6.622-0.534-11.512-2.177-18.828-4.151L585.308,538.849z" />
<path onclick="top.notify(evt)" id="Plot2" fill="#BDD5CC" stroke="#939598" stroke-miterlimit="10" d="M668.644,531.851
c1.652,5.621,2.645,10.084,3.305,12.729c0.662,2.645,0.662,5.125-1.652,5.291s-7.439-1.984-10.912-5.455
c-3.471-3.473-4.133-5.457-3.305-13.061c0.826-7.604,0.992-13.061,4.133-13.887s5.125,3.141,5.951,5.951
S668.644,531.851,668.644,531.851z"/>
<path onclick="top.notify(evt)" id="Plot3" fill="#BDD5CC" stroke="#939598" stroke-miterlimit="10" d="M520.358,495.1c9.752,1.487,25.291,6.499,32.4,8.152
c7.107,1.653,20.168-1.323,27.938-3.637c7.77-2.314,9.424-0.496,12.068,1.653c2.645,2.148,6.281,6.446,9.918,11.241
s1.322,7.604-0.496,11.572c-1.818,3.967,0.992,3.967,4.959,6.117c3.969,2.148,4.959-1.324,7.439-4.133
c2.48-2.811,6.117-2.48,9.754-0.662s6.447,7.936,9.422,12.068c2.977,4.133,4.133,3.471,11.242-0.166s9.422-15.539,9.422-20.168
s1.158-8.1,3.141-9.092c1.984-0.991,1.984-2.976,1.158-6.944c-0.014-0.066-0.315-1.538-0.332-1.612l-2.634,2.961
c-5.442,5.389-9.572,2.361-9.572,2.361c-3.515-1.625-5.985-2.104-5.985-2.104c-2.828-0.583-2.688-3.301-2.688-3.301
c-1.438-4.905-4.737-1.592-4.737-1.592c-5.55,6.503-23.852-2.333-23.852-2.333c-8.073,14.763-13.349,2.333-13.349,2.333
c-3.5-8.372-13.794-5.053-13.794-5.053c-29.848,9.112-39.272,4.207-39.272,4.207l-19.986-5.606L520.358,495.1z"/>
<path onclick="top.notify(evt)" id="Plot4" fill="#BDD5CC" stroke="#939598" stroke-miterlimit="10" d="M626.487,533.173c3.307,4.465,4.299,6.943,1.322,6.777
c-2.975-0.164-16.695-1.982-25.953-3.637c-9.258-1.652-18.846-4.959-29.426-7.439c-10.58-2.479-15.209-4.297-17.523-5.289
s-4.463-3.141,0.496-3.803c4.959-0.66,14.879,0.662,18.35,1.984s16.035,5.125,19.672,6.447s12.398,5.291,15.705,5.125
s6.117-2.148,7.439-3.803c1.322-1.652,5.125-2.977,6.281-1.322C624.009,529.867,626.487,533.173,626.487,533.173z"/>
Add a custom attribute to each of your paths to store the URL you want to open:
<path d="M10,60 L50,10 90,60" data-url="http://www.google.com/" />
Then access this URL in your event handler:
var url = evt.target.getAttribute('data-url');
Then open a popup window with that URL:
window.open(url);
So the complete script becomes:
function notify(evt){
var url = evt.target.getAttribute('data-url');
window.open(url);
}
If I am right in that your need is for something like alert("xxx") which can contain any HTML...
There's 3 parts: a style, a div and a function to show the popup
<style>
#popupInfo
{
visibility: hidden;
position: absolute;
top: 100px;
left: 100px;
width: auto;
height:auto;
margin-left: 5px;
z-index: 5;
background-color: #ffffff;
padding: 0px;
border: 1px solid #a0a0a0;
border-radius: 10px;
box-shadow: 1px 3px 2px rgba(20,20,20,0.3);
}
#closeButton
{
position: absolute;
width: 32px;
height: 32px;
background: transparent url(X_light.gif);
right: 5px;
top: 5px;
}
#closeButton:hover
{
background: url(X_dark.gif);
z-index: 99;
}
</style>
<body>
<div id="popupInfo"">
<div id="closeButton" onclick="document.getElementById('popupInfo').style.visibility = 'hidden';"></div>
<table style="width:100%;">
<tr style="height:32px;"><td ></td></tr>
<tr><td id="popupInfoText"></td></tr>
</table>
</div>
...
<script type="text/javascript">
function popupInfo(newtext, width, height){
var popStyle= document.getElementById("popupInfo").style
if( width ) popStyle.width=width.toString()+'px';
if( height ) popStyle.height=height.toString()+'px';
document.getElementById("popupInfoText").innerHTML = newtext;
popStyle.visibility = 'visible';
}
</script>
The "X_light.gif" and "X_dark.gif" are 32x32pixel grey X's on transparent used as the Close button.
A call to e.g. popupInfo("<H1>Alert!</H1>This is a message!"); will show the message.
To get an html document from a file you could do it several ways, if they are fixed files then you could:
popupInfo("<IFRAME src='message.html'></IFRAME>");
where message.html is like:
<H1>Hello there!</H1>
<p>This is a test message</p>
The result being:
...a nice image that I can't post as a guest :(
Enjoy!
TonyWilk
I have a series of svg rectangles (using D3.js) and I want to display a message on mouseover, the message should be surrounded by a box that acts as background. They should both be perfectly aligned to each other and to the rectangle (on top and centered). What is the best way to do this?
I tried adding an svg text using the "x", "y", "width" and "height" attributes, and then prepending an svg rect. The problem is that the reference point for the text is in the middle (since I want it centered aligned I used text-anchor: middle), but for the rectangle it's the top left coordinate, plus I wanted a bit of margin around the text which makes it kind of a pain.
The other option was using an html div, which would be nice, because I can add the text and padding directly but I don't know how to get the absolute coordinates for each rectangle. Is there a way to do this?
Can you use simply the SVG <title> element and the default browser rendering it conveys? (Note: this is not the same as the title attribute you can use on div/img/spans in html, it needs to be a child element named title)
rect {
width: 100%;
height: 100%;
fill: #69c;
stroke: #069;
stroke-width: 5px;
opacity: 0.5
}
<p>Mouseover the rect to see the tooltip on supporting browsers.</p>
<svg xmlns="http://www.w3.org/2000/svg">
<rect>
<title>Hello, World!</title>
</rect>
</svg>
Alternatively, if you really want to show HTML in your SVG, you can embed HTML directly:
rect {
width: 100%;
height: 100%;
fill: #69c;
stroke: #069;
stroke-width: 5px;
opacity: 0.5
}
foreignObject {
width: 100%;
}
svg div {
text-align: center;
line-height: 150px;
}
<svg xmlns="http://www.w3.org/2000/svg">
<rect/>
<foreignObject>
<body xmlns="http://www.w3.org/1999/xhtml">
<div>
Hello, <b>World</b>!
</div>
</body>
</foreignObject>
</svg>
…but then you'd need JS to turn the display on and off. As shown above, one way to make the label appear at the right spot is to wrap the rect and HTML in the same <g> that positions them both together.
To use JS to find where an SVG element is on screen, you can use getBoundingClientRect(), e.g. http://phrogz.net/svg/html_location_in_svg_in_html.xhtml
The only good way I found was to use Javascript to move a tooltip <div> around. Obviously this only works if you have SVG inside an HTML document - not standalone. And it requires Javascript.
function showTooltip(evt, text) {
let tooltip = document.getElementById("tooltip");
tooltip.innerHTML = text;
tooltip.style.display = "block";
tooltip.style.left = evt.pageX + 10 + 'px';
tooltip.style.top = evt.pageY + 10 + 'px';
}
function hideTooltip() {
var tooltip = document.getElementById("tooltip");
tooltip.style.display = "none";
}
#tooltip {
background: cornsilk;
border: 1px solid black;
border-radius: 5px;
padding: 5px;
}
<div id="tooltip" display="none" style="position: absolute; display: none;"></div>
<svg>
<rect width="100" height="50" style="fill: blue;" onmousemove="showTooltip(evt, 'This is blue');" onmouseout="hideTooltip();" >
</rect>
</svg>
You can use the title element as Phrogz indicated. There are also some good tooltips like jQuery's Tipsy http://onehackoranother.com/projects/jquery/tipsy/ (which can be used to replace all title elements), Bob Monteverde's nvd3 or even the Twitter's tooltip from their Bootstrap http://twitter.github.com/bootstrap/
On svg, the right way to write the title
<svg>
<title id="unique-id">Checkout</title>
</svg>
check here for more details https://css-tricks.com/svg-title-vs-html-title-attribute/
I came up with something using HTML + CSS only. Hope it works for you
.mzhrttltp {
position: relative;
display: inline-block;
}
.mzhrttltp .hrttltptxt {
visibility: hidden;
width: 120px;
background-color: #040505;
font-size:13px;color:#fff;font-family:IranYekanWeb;
text-align: center;
border-radius: 3px;
padding: 4px 0;
position: absolute;
z-index: 1;
top: 105%;
left: 50%;
margin-left: -60px;
}
.mzhrttltp .hrttltptxt::after {
content: "";
position: absolute;
bottom: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: transparent transparent #040505 transparent;
}
.mzhrttltp:hover .hrttltptxt {
visibility: visible;
}
<div class="mzhrttltp"><svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 24 24" fill="none" stroke="#e2062c" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-heart"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><div class="hrttltptxt">علاقهمندیها</div></div>
I always go with the generic css title with my setup. I'm just building analytics for my blog admin page. I don't need anything fancy. Here's some code...
let comps = g.selectAll('.myClass')
.data(data)
.enter()
.append('rect')
...styling...
...transitions...
...whatever...
g.selectAll('.myClass')
.append('svg:title')
.text((d, i) => d.name + '-' + i);
And a screenshot of chrome...
I use heroicons for the project I am working on. (This is JSX format) I will handle the tooltip issue with this code.
<svg className="h-6 w-6">
<title>{reasons.join(" ")}</title>
<QuestionMarkCircleIcon className={style} />
</svg>