2
respostas

Tentando mudar ícone do botão que exibe placar

Olá pessoal!

Estou tentando associar uma mudança do ícone do botão que exibe/esconde o ranking à condição de visibilidade do ranking. A ideia seria no momento em que o placar está visível o ícone ser uma seta para cima (expand_less) e no momento em que o ranking não está visível ser uma seta para baixo (expand_more).

Esse é meu html referente ao botão:

<button id="botao-placar"class="btn-floating btn-large waves-effect waves-light blue botao-reiniciar">
                <i class="material-icons icone-placar"></i>
</button>

Porém, se eu utilizo a função de slideToggle, da seguinte forma:

$("#botao-placar").click(exibePlacar);
var iconePlacar = $(".icone-placar");
var placar = $(".placar");

function exibePlacar(){
    placar.stop().slideToggle(600);
    if (placar.is(':visible')){
        iconePlacar.text("expand_less");
    }
    else{
      iconePlacar.text("expand_more");
    }    
}

O efeito não ocorre. Ele entra apenas em um dos ifs e fica lá repetidamente, independente da condição do ranking (ao analisar o código no console ele mostra alteração entre display:none e display:block, porém ao debugar ficar só no display:block).

Porém, da seguinte forma a troca do ícone funciona:

function exibePlacar(){
    if (placar.css("display") == "none"){
        placar.css("display", "block" );
    }
    else {
        placar.css("display", "none");
    }
    if (placar.is(':visible')){
        iconePlacar.text("expand_less");
    }
    else{
      iconePlacar.text("expand_more");
    }    
}

Alguém consegue me dar uma luz sobre o por que não funcionar com .slideToggle?

2 respostas

Olá Lívia ,

O Javascript para evitar travamentos do navegador não funciona de forma 100% síncrona. Ou seja as vezes ele ignora chamadas de tempo para poder já executar a próxima função.

Veja nesse exemplo que eu criei https://codepen.io/anon/pen/WLrpaY

Eu mando ele esperar 20 segundos entre dois alert e ele simplesmente ignora isso e me mostra o segundo alert depois de 4 segundos.

Quando você usou placar.stop().slideToggle(600); Ele pode ter ignorado a chamada de tempo indo para a próxima função e lendo (placar.is(':visible')) antes de terminar a função anterior. Para ter certeza disso roda no modo debbug do seu navegador. Mas já passei e passo por algo parecido (inclusive amanhã vou abrir mão de um efeito parecido porque o jquery tá se perdendo no tempo).

Essa é uma das fraquezas do Javascript, por exemplo não dá para criar uma barra de progresso com temporizador porque ele não "aguenta esperar".

Espero ter ajudado!!!

Eu fiz da seguinte maneira, ele mostra o icone do placar, e ao passar o mouse em cima ele mostra a flecha pra cima ou para baixo dependendo se o placar está visível ou não.

placar.js:

$("#botao-placar").click(mostraPlacar);
$("#botao-placar").hover(mostraIconePlacar, escondeIconePlacar);


function inserePlacar(){
    var usuario = "Lucas";
    var numeroPalavras = $("#contador-palavras").text();
    var corpoTabela = $(".placar").find('tbody');

    var linha = criaLinha(usuario, numeroPalavras);
    linha.find('.botao-remover').click(removeLinha);

    corpoTabela.prepend(linha);
    $(".placar").slideDown(500);
    scrollPlacar();
}

function scrollPlacar() {
    var posicaoPlacar = $(".placar").offset().top;

    $("html").animate(
    {
        scrollTop: posicaoPlacar + "px"
    }, 1000);
}

function criaLinha(usuario, numeroPalavras){
    var linha = $("<tr>");
    var colunaUsuario = $("<td>").text(usuario);
    var colunaPalavras = $("<td>").text(numeroPalavras);
    var colunaRemover = $("<td>");

    var link = $("<a>").addClass('botao-remover').attr('href', '#');
    var icone = $("<i>").addClass('small').addClass('material-icons').text('delete');

    link.append(icone);
    colunaRemover.append(link);
    linha.append(colunaUsuario);
    linha.append(colunaPalavras);
    linha.append(colunaRemover);

    return linha;

}

function removeLinha(){
    event.preventDefault();
    var linha = $(this).parent().parent();
    linha.fadeOut(1000);
    setTimeout(function() {
        linha.remove();
    }, 1000);
}

function mostraPlacar(){
    $(".placar").stop().slideToggle(600);
    var posicaoPlacar = $(".placar").offset().top;

    scrollPlacar();
}

function mostraIconePlacar(){
    if ($(".placar").is(':visible')){
        $("#botao-placar").text("arrow_upward");
    }else{
        $("#botao-placar").text("arrow_downward");
    }
}

function escondeIconePlacar(){
    $("#botao-placar").text("assignment");
}

No principal.html deixa "assignment" como inicial:

<a class="btn-floating btn-large waves-effect waves-light green">
                     <i class="material-icons" id="botao-placar" disabled >assignment</i>
                </a>