javascript - manipular - object svg fill
Cómo acceder a los elementos SVG con Javascript (3)
Estoy jugando con SVG y esperaba poder crear archivos SVG en Illustrator y acceder a elementos con Javascript.
Aquí está el archivo SVG que lanza Illustrator (también parece agregar una carga de basura al principio del archivo que he eliminado)
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="276.843px" height="233.242px" viewBox="0 0 276.843 233.242" enable-background="new 0 0 276.843 233.242"
xml:space="preserve">
<path id="delta" fill="#231F20" d="M34.074,86.094L0,185.354l44.444,38.519l80.741-0.74l29.63-25.186l-26.667-37.037
c0,0-34.815-5.926-37.778-6.667s-13.333-28.889-13.333-28.889l7.407-18.519l31.111-2.963l5.926-21.481l-12.593-38.519l-43.704-5.185
L34.074,86.094z"/>
<path id="cargo" fill="#DFB800" d="M68.148,32.761l43.704,4.445l14.815,42.963l-7.407,26.667l-33.333,2.963l-4.444,14.074
l54.074-1.481l22.222,36.296l25.926-3.704l25.926-54.074c0,0-19.259-47.408-21.481-47.408s-31.852-0.741-31.852-0.741
l-19.259-39.259L92.593,8.316L68.148,32.761z"/>
<polygon id="beta" fill="#35FF1F" points="86.722,128.316 134.593,124.613 158.296,163.872 190.889,155.724 214.593,100.909
194.593,52.02 227.186,49.057 246.444,92.02 238.297,140.909 216.074,172.761 197.556,188.316 179.778,169.798 164.963,174.983
163.481,197.946 156.815,197.946 134.593,159.428 94.593,151.279 "/>
<path class="monkey" id="alpha" fill="#FD00FF" d="M96.315,4.354l42.963,5.185l18.519,42.222l71.852-8.148l20.74,46.667l-5.926,52.593
l-24.444,34.074l-25.185,15.555l-14.074-19.259l-8.889,2.964l-1.481,22.222l-14.074,2.963l-25.186,22.963l-74.074,4.444
l101.481,4.444c0,0,96.297-17.777,109.63-71.852S282.24,53.983,250.389,20.65S96.315,4.354,96.315,4.354z"/>
</svg>
Como probablemente pueda ver, cada elemento tiene una ID, y esperaba poder acceder a elementos individuales con Javascript para poder cambiar el atributo de Rellenar y responder a eventos como hacer clic.
El HTML es pantano básico
<!DOCTYPE html>
<html>
<head>
<title>SVG Illustrator Test</title>
</head>
<body>
<object data="alpha.svg" type="image/svg+xml" id="alphasvg" width="100%" height="100%"></object>
</body>
</html>
Supongo que estas son dos preguntas realmente.
¿Es posible hacerlo de esta manera, en lugar de usar algo como Raphael o jQuery SVG?
Si es posible, ¿cuál es la técnica?
ACTUALIZAR
Por el momento, he recurrido al uso de Illustrator para crear el archivo SVG, y estoy usando Raphaël JS para crear rutas y simplemente copiar los datos de puntos del archivo SVG y pegarlos en la función path()
. Crear rutas complejas, como las que podrían necesitarse para un mapa, al codificar manualmente los datos de puntos, es (a mi entender) prohibitivamente complejo.
¿Es posible hacerlo de esta manera, en lugar de usar algo como Raphael o jQuery SVG?
Seguro.
Si es posible, ¿cuál es la técnica?
Este fragmento de código anotado funciona:
<!DOCTYPE html>
<html>
<head>
<title>SVG Illustrator Test</title>
</head>
<body>
<object data="alpha.svg" type="image/svg+xml"
id="alphasvg" width="100%" height="100%"></object>
<script>
var a = document.getElementById("alphasvg");
// It''s important to add an load event listener to the object,
// as it will load the svg doc asynchronously
a.addEventListener("load",function(){
// get the inner DOM of alpha.svg
var svgDoc = a.contentDocument;
// get the inner element by id
var delta = svgDoc.getElementById("delta");
// add behaviour
delta.addEventListener("mousedown",function(){
alert(''hello world!'')
}, false);
}, false);
</script>
</body>
</html>
Tenga en cuenta que una limitación de esta técnica es que está restringida por la misma política de origen, por lo que alpha.svg
debe alojarse en el mismo dominio que el archivo .html
, de lo contrario, el DOM interno del objeto no será accesible.
En caso de que utilice jQuery, debe esperar $(window).load
, ya que es posible que el documento SVG incrustado aún no se haya cargado en $(document).ready
$(window).load(function () {
//alert("Document loaded, including graphics and embedded documents (like SVG)");
var a = document.getElementById("alphasvg");
//get the inner DOM of alpha.svg
var svgDoc = a.contentDocument;
//get the inner element by id
var delta = svgDoc.getElementById("delta");
delta.addEventListener("mousedown", function(){ alert(''hello world!'')}, false);
});
Si está utilizando una etiqueta <img>
para el SVG, entonces no puede manipular su contenido (hasta donde yo sé).
Como muestra la respuesta aceptada, usar <object>
es una opción.
Lo necesitaba recientemente y usé gulp-inject
durante mi compilación gulp para inyectar el contenido de un archivo SVG directamente en el documento HTML como un elemento <svg>
, que luego es muy fácil de trabajar con el uso de selectores CSS y querySelector
/ getElementBy*
.