2012-06-11 42 views
13

Estoy tratando de modificar una etiqueta svg con javascript para hacer que se pueda cambiar el tamaño, pero mis cambios no tienen ningún efecto. La razón por la que tengo que hacer esto es porque esta etiqueta es renderizada por una biblioteca que no puedo modificar, y por lo tanto parece que mi única opción es modificar el svg con javascript.Modificar los atributos svg con javascript no tiene efecto

Sé que la etiqueta que produce este script es correcta, ya que puedo copiar la etiqueta a un nuevo documento html y funcionará (lo he incluido en el código de muestra), así que parece que necesito un poco forma de forzar el svg para reconocer que ha sido cambiado (u otra forma de modificar el svg).

Aquí es una página HTML que muestra mi problema:

<html> 
    <head> 
     <script src="http://code.jquery.com/jquery.min.js"></script> 
     <script type="text/javascript"> 
     $(document).ready(function() { 
      var svg = $('#testsvg').find('svg')[0]; 

      var w = svg.getAttribute('width').replace('px', ''); 
      var h = svg.getAttribute('height').replace('px', ''); 

      svg.removeAttribute('width'); 
      svg.removeAttribute('height'); 

      svg.setAttribute('viewbox', '0 0 ' + w + ' ' + h); 
      svg.setAttribute('preserveaspectratio', 'xminymin meet') 

      $(svg) 
       .css('width', '100%') 
       .css('height', '100%') 
       .css('background-color', 'white'); 
     }); 
     </script> 
    </head> 
    <body style="background-color: #333;"> 
     <div style="width: 80%; height: 40%;"> 
      <svg id="resultsvg" xmlns="http://www.w3.org/2000/svg" version="1.1" style="width: 100%; height: 100%; background-color: white; " viewbox="0 0 100 100" preserveaspectratio="xminymin meet"> 
       <circle cx="50" cy="50" r="40" stroke="black" stroke-width="2" fill="red"></circle> 
      </svg> 
     </div> 
     <div id="testsvg" style="width: 80%; height: 40%;"> 
      <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100px" height="100px"> 
       <circle cx="50" cy="50" r="40" stroke="black" stroke-width="2" fill="red" /> 
      </svg> 
     </div> 
    </body> 
</html> 

Respuesta

23

SVG entre mayúsculas y minúsculas por lo

svg.setAttribute('viewbox', '0 0 ' + w + ' ' + h); 
svg.setAttribute('preserveaspectratio', 'xminymin meet') 

debe escribirse ancho

svg.setAttribute('viewBox', '0 0 ' + w + ' ' + h); 
svg.setAttribute('preserveAspectRatio', 'xMinYMin meet') 

y la altura sobre el elemento <svg> son atributos y no estilos (a diferencia de html) por lo que debe usar setAttribute('width', '100%') en lugar de .css('width', '100%')

+16

para compañeros googlers: también tenga en cuenta el '[0]' después de 'find ('svg')' para obtener el elemento DOM del elemento jQuery. Esto es importante para permitir el uso de 'setAttribute()'. el método jQuery 'attr()' no se puede usar porque el DOM de SVG es diferente del DOM de HTML (consulte http://keith-wood.name/svg.html#dom) – Offirmo

+0

Esto solo es cierto si no están usando JQuery SVG (posiblemente). Dice justo en el enlace. El SVG DOM es diferente al HTML DOM para el que se diseñó jQuery. Por lo tanto, las funciones de jQuery que funcionan con clases no funcionan en los nodos SVG. Para solucionar este problema, puede usar la extensión jQuery SVG DOM. Agregue la extensión en la sección principal de su página. No veo por qué esto no podría usarse para ningún problema de SVG, pero podría estar demasiado integrado con JquerySVG, pero quién sabe lo que haría una pequeña edición :) – XaolingBao

6

jQuery convertir el nombre del atributo a minúscula; Por ejemplo, en lugar de establecer un atributo viewBox, establecerá viewbox. Desafortunadamente, los nombres de los atributos del elemento SVG (un dialecto XML) distinguen entre mayúsculas y minúsculas.

Si desea utilizar jQuery constantemente, podría utilizar $.attrHooks para manejar los atributos mayúsculas y minúsculas:

['preserveAspectRatio', 'viewBox'].forEach(function(k) { 
    // jQuery converts the attribute name to lowercase before 
    // looking for the hook. 
    $.attrHooks[k.toLowerCase()] = { 
    set: function(el, value) { 
     if (value) { 
     el.setAttribute(k, value); 
     } else { 
     el.removeAttribute(k, value); 
     } 
     return true; 
    }, 
    get: function(el) { 
     return el.getAttribute(k); 
    }, 
    }; 
}); 

$(document).ready(function() { 
    var svg = $('#testsvg'); 
    var w = svg.attr('width').replace('px', ''); 
    var h = svg.attr('height').replace('px', ''); 

    svg.attr({ 
    width: '100%', 
    height: '100%', 
    viewBox: [0, 0, w, h].join(' '), 
    preserveAspectRatio: 'xMidYMid meet' 
    }) 
}); 

Tenga en cuenta que el.attr('viewBox', null) habría fallado; su recolector de gancho no será llamado. En su lugar, debe usar el.removeAttr('viewBox') o el.attr('viewBox', false).

Para otro atributo como trazo, los pondría en una hoja de estilo.

svg { 
    background-color: white; 
} 
circle { 
    fill: red; 
    stroke: black; 
    stroke-width: 1px; 
} 

Si es necesario agregar la clase/palanca para cambiar el estilo de una serie de elementos específicos, es necesario utilizar jQuery jQuery o 1.12+ 2.2+.

Cuestiones relacionadas