Tengo muchos SVG generados dinámicamente dentro de mi documento HTML. Contienen (entre otros elementos) algunos elementos <text> , más o menos así:
<svg> // bunch of other elements <text x="50" y="25" text-anchor="middle" dominant-baseline="central" class="myclass">info 1</text> <text x="50" y="75" text-anchor="middle" dominant-baseline="central" class="myclass">info 2</text> // more other elements </svg> ¿Hay algo como un atributo de id o name que pueda usar para estos dos fragmentos de texto, de modo que pueda cambiarlos dinámicamente más adelante? Se supone que la id es única en todo el documento, y tengo muchos de estos SVG. El name parece significar algo diferente en SVG (a diferencia de los formularios HTML) y, en cualquier caso, podría estar obsoleto. Dudo en usar class , ya que esto realmente no se trata de estilo y no quiero conflictos extraños con otros estilos que puedan estar presentes en el documento. (No tengo control sobre el documento en el que se usa mi código, o sus hojas de estilo). Tampoco quiero tener que buscar en todo el documento el elemento que estoy buscando, ya que ya tendré un puntero a su padre. Idealmente, haría algo como esto:
mySVG.getChildByType("type1").innerHTML = "here's new text"; (Con la advertencia de que cada SVG similar tiene uno de estos "type1 "tipo 1", que se puede agarrar y manipular).
Gracias.
No estoy seguro de por qué crees que la id es inutilizable. Dices que estás generando dinámicamente los SVG. Supongo que eso significa en tiempo de ejecución. Así que solo genera una id al mismo tiempo. Ponle un prefijo, si es necesario, para que puedas estar seguro de que será único.
textElement.setAttribute("id", "my-prefix-" + nextTextElemIndex);Tampoco hay nada que le impida agregar su propio atributo personalizado. Luego diseñe los elementos usando selectores de atributos .
circle[foo="middle"] { fill: green; } <svg viewBox="0 0 300 100"> <circle cx="50" cy="50" r="50" fill="red" foo="left"/> <circle cx="150" cy="50" r="50" fill="red" foo="middle"/> <circle cx="250" cy="50" r="50" fill="red" foo="right"/> </svg>No está exactamente claro lo que quieres; ¿Parece que quieres una forma de obtener los elementos de texto dentro de un SVG específico?
En ese caso, utilice algo como lo siguiente:
document.querySelectorAll("svg > text")[0].textContent = "I am the new string";Ahora querySelectorAll() solo usa selectores de CSS, por lo que puede reemplazar svg allí con un .class, #id, o simplemente usar el selector de CSS que desee.
Puede usar nombres de clase bastante detallados para evitar estilos anulados accidentalmente heredados de un css global.
Por ejemplo, un esquema de nombres similar a BEM como se usa comúnmente en scripts/libs como controles deslizantes de imágenes, reproductores multimedia, asistentes de mapas.
Si sus elementos de texto svg se compilan dinámicamente, puede ejecutar una función que agregue ID/propiedades de clase basadas en índices:
const parentSvgs = document.querySelectorAll('.mySvg'); setAutoIds(parentSvgs); function setAutoIds(parents) { parents.forEach(function(parent, p) { let parentIdentifier = 'mySvg__parent--' + p; parent.id = parentIdentifier; parent.classList.add(parentIdentifier); let children = parent.querySelectorAll('.mySvg__text'); children.forEach(function(child, c) { let childIdentifier = `mySvg__text--${p}-${c}`; child.id = childIdentifier; child.classList.add(childIdentifier); child.classList.add(`mySvg__text--${c}`); }) }) } //auto content example setIndexedContent(parentSvgs); function setIndexedContent(parents) { parents.forEach(function(parent, p) { let children = parent.querySelectorAll('.mySvg__text'); children.forEach(function(child, c) { child.textContent = `svg nr.${p+1} info nr.${c+1}`; }); }); } // single text element selected by ID or class document.getElementById('mySvg__text--1-3').textContent = 'unique text by ID'; document.getElementById('mySvg__text--1-2').textContent = 'unique text by Class'; .mySvg { display: inline-block; width: 20vw; border: 1px dotted #ccc; } .mySvg__text { font-size: 10px; } .mySvg__text--0 { fill: orange } .mySvg__text--1 { fill: green } .mySvg__text--2 { fill: red } <svg class="mySvg" viewBox="0 0 100 100"> <text x="50" y="25" text-anchor="middle" dominant-baseline="central" class="mySvg__text">info</text> <text x="50" y="50" text-anchor="middle" dominant-baseline="central" class="mySvg__text">info</text> <text x="50" y="75" text-anchor="middle" dominant-baseline="central" class="mySvg__text">info</text> </svg> <svg class="mySvg" viewBox="0 0 100 100"> <text x="50" y="10" text-anchor="middle" dominant-baseline="central" class="mySvg__text">info</text> <text x="50" y="20" text-anchor="middle" dominant-baseline="central" class="mySvg__text">info</text> <text x="50" y="30" text-anchor="middle" dominant-baseline="central" class="mySvg__text">info</text> <text x="50" y="40" text-anchor="middle" dominant-baseline="central" class="mySvg__text">info</text> </svg>De esta manera, podría aplicar estilos CSS compartidos pero también seleccionar elementos individuales de acuerdo con su índice global.