0

I've created svg elements for titles. I dynamically create these elements with jQuery. I want to use this element in different places and I want them to be responsive. When I use $(window).resize function, browser gets stuck.

Here is my code:

function widgetTitle() {
    $(".title-svg").each(function(i, item) {
        item = $(item);
        $(".svgWidget", item).css("width", item.width() + 17);

        var a = item.outerWidth() + 17;
        var constantPoint1 = "0.83 0.56 15.83 22.56 ";
        var constantPoint2 = " 22.56 ";
        var constantPoint3 = " 50.56";

        var changePoint = a - 2;

        var points = constantPoint1 + changePoint + constantPoint2 + changePoint + constantPoint3;
        var viewBox = "0 0 " + a + " 50.56";

        $(".svgWidget polyline", item).attr("points", points);
        $(".svgWidget", item).attr("viewBox", viewBox);
    });
}

widgetTitle();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div style="width: 80%; position: relative;margin-bottom: 50px">
    <div class="title-svg" style="width: 100%;position: absolute;top: 10px;">
        <svg class="svgWidget" data-name="svgWidget" xmlns="http://www.w3.org/2000/svg">
    <linearGradient id="firstGradient" x="100%" y="100%">
     <stop offset="0" stop-color="yellow">
      <animate attributeName="stop-color" values="green;teal;purple;orange;red" dur="10s" from="0"
               to="100%" repeatCount="indefinite"/>
     </stop>
     <stop offset=100 stop-color="purple">
      <animate attributeName="stop-color"
               values="lightblue;blue;red;red;black;red;red;purple;lightblue" dur="10s" from="0%"
               to="100%" repeatCount="indefinite"/>
     </stop>
    </linearGradient>
    <g style="opacity: 0.38" stroke="url(#firstGradient)">
     <polyline style="fill: none;stroke-miterlimit: 10;stroke-width: 1px"/>
    </g>
   </svg>
    </div>
</div>
<div style="clear:both"></div>
<div style="width: 10%: position: relative;">
    <div class="title-svg" style="width: 100%;position: absolute;top: 10px;">
        <svg class="svgWidget" data-name="svgWidget" xmlns="http://www.w3.org/2000/svg">
    <linearGradient id="firstGradient" x="100%" y="100%">
     <stop offset="0" stop-color="yellow">
      <animate attributeName="stop-color" values="green;teal;purple;orange;red" dur="10s" from="0"
               to="100%" repeatCount="indefinite"/>
     </stop>
     <stop offset=100 stop-color="purple">
      <animate attributeName="stop-color"
               values="lightblue;blue;red;red;black;red;red;purple;lightblue" dur="10s" from="0%"
               to="100%" repeatCount="indefinite"/>
     </stop>
    </linearGradient>
    <g style="opacity: 0.38" stroke="url(#firstGradient)">
     <polyline style="fill: none;stroke-miterlimit: 10;stroke-width: 1px"/>
    </g>
   </svg>
    </div>
</div>

As you can see, it did not make my elements responsive.


SOLVED THE PROBLEM WITH THIS CODE:

function widgetTitle() {
    $(".title-svg").each(function(i, item) {
        item = $(item);
        //$(".svgWidget", item).css("width", item.width()+17);

        var a = item.outerWidth() - 2;
        var constantPoint1 = "0.83 0.56 15.83 22.56 ";
        var constantPoint2 = " 22.56 ";
        var constantPoint3 = " 50.56";

        var changePoint = a;

        var points = constantPoint1 + changePoint + constantPoint2 + changePoint + constantPoint3;
        var viewBox = "0 0 " + a + " 50.56";

        $(".svgWidget polyline", item).attr("points", points);
        $(".svgWidget", item).attr("viewbox", viewBox);
    });
}

$(window).on('resize', function() {
    widgetTitle();
});

widgetTitle();
Narendra Jadhav
  • 10,052
  • 15
  • 33
  • 44
  • I'm a little confused as to why you would try responsive using JQuery rather than managing this in CSS? Did that not work? – Dan Bennett Sep 20 '17 at 15:27
  • Because i want to use svg with animated background. – Çağrı Çolak Sep 22 '17 at 14:28
  • `attr("viewbox", viewBox)` should be `attr("viewBox", viewBox)` – Paul LeBeau Sep 24 '17 at 04:55
  • 1
    @PaulLeBeau, as noted in the answer, jQuery v2 converts `.attr("viewBox", viewBox)` to lowercase. To set a valid attribute, either use jQuery v3, or `.get(0).setAttribute("viewBox", viewBox)` must be used. – ccprog Sep 26 '17 at 14:54

1 Answers1

1
  1. Do not set an absolute width for the svg elements. If you need something different than 100%, use relative units like % or vw.

  2. With jQuery, you have a problem: it is a HTML framework that does not support XML syntax for SVG prior to version 3. While you try to set the viewBox attribute, jQuery converts that to viewbox in lowercase, which does not work since SVG is case-sensitive. Either use the pure js syntax instead, or use jQuery in version 3 or later.

  3. There is syntax error in the outer div for the second svg

function widgetTitle() {
 $(".title-svg").each(function(i, item) {
  item = $(item);
  // only need this for values other than 100%
  // $(".svgWidget", item).css("width", "100%");

  var a = item.outerWidth() + 17;
  var constantPoint1 = "0.83 0.56 15.83 22.56 ";
  var constantPoint2 = " 22.56 ";
  var constantPoint3 = " 50.56";

  var changePoint = a-2;

  var points = constantPoint1 + changePoint + constantPoint2 + changePoint + constantPoint3;
  var viewBox = "0 0 " + a + " 50.56";

  $(".svgWidget polyline", item).attr("points", points);
  $(".svgWidget", item).get(0).setAttribute("viewBox", viewBox);
 });
}

widgetTitle();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div style="width: 80%; position: relative;margin-bottom: 50px">
    <div class="title-svg" style="width: 100%;position: absolute;top: 10px;">
   <svg class="svgWidget" data-name="svgWidget" xmlns="http://www.w3.org/2000/svg">
    <linearGradient id="firstGradient" x="100%" y="100%">
     <stop offset="0" stop-color="yellow">
      <animate attributeName="stop-color" values="green;teal;purple;orange;red" dur="10s" from="0"
               to="100%" repeatCount="indefinite"/>
     </stop>
     <stop offset=100 stop-color="purple">
      <animate attributeName="stop-color"
               values="lightblue;blue;red;red;black;red;red;purple;lightblue" dur="10s" from="0%"
               to="100%" repeatCount="indefinite"/>
     </stop>
    </linearGradient>
    <g style="opacity: 0.38" stroke="url(#firstGradient)">
     <polyline style="fill: none;stroke-miterlimit: 10;stroke-width: 1px"/>
    </g>
   </svg>
  </div>
</div>
<div style="clear:both"></div>
<div style="width: 10%; position: relative;">
    <div class="title-svg" style="width: 100%;position: absolute;top: 10px;">
   <svg class="svgWidget" data-name="svgWidget" xmlns="http://www.w3.org/2000/svg">
    <linearGradient id="firstGradient" x="100%" y="100%">
     <stop offset="0" stop-color="yellow">
      <animate attributeName="stop-color" values="green;teal;purple;orange;red" dur="10s" from="0"
               to="100%" repeatCount="indefinite"/>
     </stop>
     <stop offset=100 stop-color="purple">
      <animate attributeName="stop-color"
               values="lightblue;blue;red;red;black;red;red;purple;lightblue" dur="10s" from="0%"
               to="100%" repeatCount="indefinite"/>
     </stop>
    </linearGradient>
    <g style="opacity: 0.38" stroke="url(#firstGradient)">
     <polyline style="fill: none;stroke-miterlimit: 10;stroke-width: 1px"/>
    </g>
   </svg>
  </div>
</div>

What I can't tell you is whether your vertical positioning is what you intended. The .title-svg divs are absolutely positioned, so the outer divs have a height of zero. As a consequence the <div style="clear:both"></div> has no effect.

ccprog
  • 20,308
  • 4
  • 27
  • 44
  • Thank you for the answer. I will consider the recommendations. I think you misunderstand what I want to do. I just want SVG to be responsive. I want to run the function for all elements, not just one element https://image.prntscr.com/image/b3AJcRt3RvGPpTOjNmaFmg.png – Çağrı Çolak Sep 21 '17 at 08:23
  • That would mean to re-run function `widgetTitle()` on every resize, wouldn't it? (Do not forget to throttle or [debounce](https://stackoverflow.com/questions/599288/cross-browser-window-resize-event-javascript-jquery#36695070).) – ccprog Sep 21 '17 at 13:35