3
respostas

Alteração

Olá,

Estou trabalhando em um projeto pessoal em cima do curso e ao ver os vídeos, resolvi tentar fazer uma manipulação de DOM da seguinte forma, possuo ícones png que chamo por classe, através do CSS e gostaria que ao chamar a classe no HTML, ao invés de carregar o CSS com o svg inline, que carregue pelo Javascript, através do sprite svg, que fiz com todo os ícones que preciso para o site! Tentei o seguinte código:

  var i = document.querySelectorAll("i");
        for(var i=0;i<=i.length;i++) {
            if(i[i].className == "ico-") { 
            i[i].textContent = "<svg class='icon'><use xlink:href='icons/icons.svg#icon-"+nome+"'/></svg>"; 
        }
    }

Mas parei por aí, não consigo mais pensar em nada que o faça funcionar, rsrs...

Meu código atual está assim: HTML:

<div class="row">
        <div class="col-12">
            <h3>Sprite SVG - Teste</h3>
        </div>

        <div>
            <i class="ico-italic"></i>
    </div>
</div>

E o CSS:

.ico-italic {
    background-image:url(../icon/custom/italic.svg);
}

Alguém consegue me ajudar numa forma de não precisar trocar todo o HTML, só chamando pelo JS pela mesma tag e classe que já utilizo.

Grata!!!

Att. Priscila

3 respostas

Olá, Priscila!

Alguns detalhes no seu código:

Nomes de variáveis

var i = document.querySelectorAll("i");
        for(var i=0;i<=i.length;i++) {
             if(i[i].className == "ico-") {

A variável que armazena o retorno do querySelectorAll está com o mesmo nome da que armazena o índice do for. Ambas estão tem o nome i.

O JavaScript vai ficar meio perdido!

Modificando a primeira ocorrência para lista, teremos:

var lista = document.querySelectorAll("i");
        for(var i=0;i<=lista.length;i++) {
            if(lista[i].className == "ico-") { 
            lista[i].textContent = "<svg class='icon'><use xlink:href='icons/icons.svg#icon-"+nome+"'/></svg>"; 
        }
    }

A condição de parada do for

Os indíces da lista retornada por querySelectorAll começam com 0. Então, o último elemento é o tamanho da lista - 1.

Por isso, a condição de parada (a parte do meio do for), não tem o =.

Ficaria assim:

        for(var i=0;i<lista.length;i++) {

className

O className de <i> irá retornar "ico-italic".

Comparar com == com o valor "ico-" vai dar false.

Podemos comparar com o valor "ico-italic":

            if(lista[i].className == "ico-italic") {

Se você quiser ver se o texto começa com algum trecho, a partir do EcmaScript 6, você pode usar o startsWith:

            if(lista[i].className.startsWith("ico-italic")) {

textContent vs. innerHTML

O textContext vai colocar o texto que você enviar para ele na página. Se você colocar um <svg>...</svg>, ele vai mostrar exatamente isso.

Uma maneira de fazermos com que o navegador trate o texto <svg>...</svg> como um SVG mesmo, é usar o innerHTML.

lista[i].innerHTML = "<svg class='icon'><use xlink:href='icons/icons.svg#icon-"+nome+"'/></svg>";

Juntando tudo

var lista = document.querySelectorAll('i');
        for(var i=0;i<=lista.length;i++) {
            if(lista[i].className.startsWith('ico-')) { 
            lista[i].innerHTML = '<svg height="100" width="100"><circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red"/></svg>'; 
        }
    }

Teste nesse link:

https://jsfiddle.net/alexandreaquiles/fumfc2j2/

Me ajudou muito, mas no caso, esses ícones estão em um sprite, para colocar em uma váriavel, que virá do html. Poderia fazer assim:

var lista = document.querySelectorAll('i');
        for(var i=0;i<=lista.length;i++) {
            if(lista[i].className.startsWith('ico-')) { 
            lista[i].innerHTML = '<svg><use xlink:href="icons/icons.svg#'+item.classList+'" /></svg>'; 
        }
    }

Mas faltaria declarar a variável 'item' em algum lugar correto?

Obrigada Alexandre!

Isso! Antes de fazer o for, você teria que obter esse item de algum lugar!