How to show a default SVG Fill Color on jQuery mouseout / mouseleave?


Tags: jquery,css,svg

Problem :

I'm in troubles trying to animate SVG figures with jQuery.

What I need in CSS looks like this:

svg rect:hover {
  fill: blue;
  transition: .15s;
}

Need it in jQuery because I want the 'fill' to be a random color instead of 'blue'. My problem is how to remove the random color on mouseout/mouseleave and show the SVG rect default color. All I can do is to pick another color, purple in the example...

$("svg").find("rect").hover(function(){
  var hue = 'rgb(' + (Math.floor((256-199)*Math.random()) + 150) + ','
                   + (Math.floor((256-199)*Math.random()) + 150) + ','
                   + (Math.floor((256-199)*Math.random()) + 150) + ')';
  $(this).attr("fill", hue);
});
$("svg").find("rect").mouseout(function(){
  $(this).attr("fill", "purple");
});

What I got: http://codepen.io/pixelius/pen/NbyPzK



Solution :

Custom data-* attributes are officially supported in the current draft of SVG2:

RESOLUTION: "We will reserve "data-*" attributes to be used in SVG content.

Source: http://www.w3.org/2015/01/15-svg-minutes.html#item03

This means you can create an attribute data-fill for each rect and store the original fill color in data-fill during your mouseover event - and then retrieve the same value from data-fill during your mouseout event.

Working Example:

(N.B. I have used javascript because I am still only in the early stages of learning jQuery)

var r = (Math.floor((256-199) * Math.random()) + 150);
var g = (Math.floor((256-199) * Math.random()) + 150);
var b = (Math.floor((256-199) * Math.random()) + 150);
var hue = 'rgb('+ r + ', ' + g + ', ' + b + ')';

function fillRandom() {
    var originalFillColor = this.getAttribute('fill');
    this.setAttribute('data-fill', originalFillColor);
    this.setAttribute('fill', hue);
}

function fillOriginal() {
    var originalFillColor = this.getAttribute('data-fill');
    this.setAttribute('fill', originalFillColor);
}

var svgs = document.getElementsByTagName('svg');

for (var i = 0; i < svgs.length; i++) {
    var svg = svgs[i];
    var rects = svg.getElementsByTagName('rect');

    for (var j = 0; j < rects.length; j++) {
        var rect = rects[j];
        rect.addEventListener('mouseover',fillRandom,false);
        rect.addEventListener('mouseout',fillOriginal,false);
    }
}
body {
  background-color : #031F34;
  display: flex;
  justify-content: space-between;
  padding: 0 6rem;
}

a {
  cursor: pointer;
}

svg rect {
transition: all .3s linear;
}
<a>
      <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="38px" height="38px" viewbox="0 0 38 38" enable-background="new 0 0 38 38" xml:space="preserve">
        <rect fill="#01121E" width="12" height="12" />
        <rect y="13" fill="#01121E" width="12" height="12" />
        <rect y="26" fill="#01121E" width="12" height="12" />
        <rect x="13" fill="#2c845f" width="12" height="12" />
        <rect x="13" y="13" fill="#2c845f" width="12" height="12" />
        <rect x="13" y="26" fill="#2c845f" width="12" height="12" />
        <rect x="26" fill="#01121E" width="12" height="12" />
        <rect x="26" y="13" fill="#01121E" width="12" height="12" />
        <rect x="26" y="26" fill="#01121E" width="12" height="12" />
      </svg>
    </a>

<a>
      <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="64px" height="38px" viewbox="0 0 64 38" enable-background="new 0 0 64 38" xml:space="preserve">
        <rect fill="#2c845f" width="12" height="12" />
        <rect y="13" fill="#01121E" width="12" height="12" />
        <rect y="26" fill="#01121E" width="12" height="12" />
        <rect x="13" fill="#01121E" width="12" height="12" />
        <rect x="13" y="13" fill="#2c845f" width="12" height="12" />
        <rect x="13" y="26" fill="#01121E" width="12" height="12" />
        <rect x="26" fill="#01121E" width="12" height="12" />
        <rect x="26" y="13" fill="#01121E" width="12" height="12" />
        <rect x="26" y="26" fill="#2c845f" width="12" height="12" />
        <rect x="39" fill="#01121E" width="12" height="12" />
        <rect x="39" y="13" fill="#2c845f" width="12" height="12" />
        <rect x="39" y="26" fill="#01121E" width="12" height="12" />
        <rect x="52" fill="#2c845f" width="12" height="12" />
        <rect x="52" y="13" fill="#01121E" width="12" height="12" />
        <rect x="52" y="26" fill="#01121E" width="12" height="12" />
      </svg>
    </a>


    CSS Howto..

    How do I add an image directly below a text header?

    How to specify BOTH max-width % and px [closed]

    Using a lot of style sheets. Needing opinions on how to move forward efficiently

    How to center content vertically with unknown content and fixed layout

    How to scroll to particular element using CSS/JS

    How to make a jQuery step animation?

    How to make a smooth dashed border rotation animation like 'marching ants'

    How to use CSS property position:fixed with top:50px and height:100%?

    How to change CSS class of a HTML page element using ASP.NET?

    How to build simple image rotation effect like this one in exapmle?

    How to best format an HTML form like this where user can dynamically add subfields? (table? list? css3?)

    How do I customize an asp:Button class?

    How to get just the responsive grid from Bootstrap 3?

    How do I make an image act as a video overlay?

    How to use vertical menus in HTML and css?

    Codeigniter: how to access css files from different views?

    how to make div with one line of text and div with two the same height?

    How do I differentiate between IE versions 6 to 10 using IE CSS Hacks?

    How to create CSS dropdown

    How to scale SVG properly and responsively in HTML5?

    how can i trigger multiple hover actions/events?

    How to dynamically change CSS class of DIV tag?

    How can I make editable fields with button?

    How to increase spacing between dt tags

    How do I remove the padding between the content of the cell and the cell borders in a table? [duplicate]

    sunken border when background-color css specified - how to avoid?

    How to prevent blur from CSS transform?

    advice about how to vertically center content in fluid element

    CSS bottom bar isn't correctly shown with chrome

    How can I add a gradient overlay to an image that is set in a style attribute in css?