Alternando uma imagem de fundo DIV com jQuery

207

Estou criando uma tabela de taxas de chamada de expansão / recolhimento para a empresa em que trabalho. Atualmente, tenho uma tabela com um botão abaixo para expandi-lo, o botão diz "Expandir". É funcional, exceto que eu preciso do botão para mudar para "Recolher" quando ele é clicado e, é claro, voltar para "Expandir" quando é clicado novamente. A escrita no botão é uma imagem de fundo.

Então, basicamente, tudo o que preciso é alterar a imagem de fundo de uma div quando ela é clicada, exceto como uma alternância.

zuk1
fonte
3
Por que uma imagem de fundo? Por que não texto ?
uınbɐɥs
1
Eu votei contra porque ele não aceitou a resposta daqui a alguns anos, espero que ele esteja bem no @ user1040899!
precisa saber é
@ user1040899 zuk1 Visto pela última vez Aug 9 '10 at 0:42no SO Talvez por isso, :(
M. Junaid Salaat

Respostas:

443
$('#divID').css("background-image", "url(/myimage.jpg)");  

Deve fazer o truque, basta conectá-lo em um evento de clique no elemento

$('#divID').click(function()
{
  // do my image switching logic here.
});
usuario
fonte
@fuccboi, como eu uso esse código para disparar uma marca de seleção svg animada quando um usuário seleciona uma opção. :)
norcal johnny
Boa answere, eu quero fazer ponto fora >> url () é parte da cadeia de caracteres << que é realmente confuso se você está vindo de uma língua typedef forte
clockw0rk
62

Pessoalmente, eu apenas usaria o código JavaScript para alternar entre 2 classes.

Faça com que o CSS esboce tudo o que você precisa na sua div menos a regra de segundo plano e adicione duas classes (por exemplo: expandida e recolhida) como regras, cada uma com a imagem de segundo plano correta (ou a posição de segundo plano se estiver usando um sprite).

CSS com imagens diferentes

.div {
    /* button size etc properties */
}

.expanded {background: url(img/x.gif) no-repeat left top;}
.collapsed {background: url(img/y.gif) no-repeat left top;}

Ou CSS com sprite de imagem

.div {
    background: url(img/sprite.gif) no-repeat left top;
    /* Other styles */
}

.expanded {background-position: left bottom;}

Então...

Código JavaScript com imagens

$(function){
    $('#button').click(function(){
        if($(this).hasClass('expanded'))
        {
            $(this).addClass('collapsed').removeClass('expanded');
        }
        else
        {
            $(this).addClass('expanded').removeClass('collapsed');
        }
    });
}

JavaScript com sprite

Nota: o toggleClass elegante não funciona no Internet Explorer 6, mas o método abaixo addClass/ removeClasstambém funcionará bem nessa situação

A solução mais elegante (infelizmente não é compatível com o Internet Explorer 6)

$(function){
        $('#button').click(function(){
            $(this).toggleClass('expanded');
        });
    }

$(function){
        $('#button').click(function(){
            if($(this).hasClass('expanded'))
            {
                $(this).removeClass('expanded');
            }
            else
            {
                $(this).addClass('expanded');
            }
        });
    }

Até onde eu sei, esse método funcionará nos navegadores, e eu me sentiria muito mais confortável jogando com CSS e classes do que com alterações de URL no script.

Kelly
fonte
"Nota: o toggleClass elegante não funciona no Internet Explorer 6"
Chaoley 25/07
43

Existem duas maneiras diferentes de alterar um CSS de imagem de plano de fundo com o jQuery.

  1. $('selector').css('backgroundImage','url(images/example.jpg)');
  2. $('selector').css({'background-image':'url(images/example.jpg)'});

Olhe atentamente para observar as diferenças. No segundo, você pode usar CSS convencional e encadear várias propriedades CSS juntas.

Ecropolis
fonte
6
2. está incorreto inválido. Amarrando várias propriedades em conjunto é feito assim: $ ( 'selector') css ({ 'background-color': 'amarelo', 'background-image': 'url ()'}).
codecowboy
Se eu tentar 2., eu recebo um erro - Uncaught SyntaxError: Unexpected token:
geeky_monster
17

Se você usar um sprite CSS para as imagens de plano de fundo, poderá aumentar o deslocamento do plano de fundo +/- n pixels, dependendo de estar expandindo ou recolhendo. Não é uma alternância, mas é mais próxima do que ter que mudar os URLs da imagem de plano de fundo.

Dave Ward
fonte
2
Bônus: se você usar imagens separadas, apenas a que é exibida no carregamento será realmente carregada. Haverá um pequeno atraso ao alternar imagens antes do carregamento do segundo estado. Com um sprite, você tem apenas uma imagem e ela já estará lá.
Lasar
14

Aqui está como eu faço isso:

CSS

#button{
   background-image: url("initial_image.png");
}

#button.toggled{
  background-image:url("toggled_image.png");
}

JS

$('#button').click(function(){
  $('#my_content').toggle();
  $(this).toggleClass('toggled');
});
Loupax
fonte
você pode eventualmente usar o .toggleClass()recurso jQuery .
Paulo Bueno
Constatou-se sobre toggleClass dois dias depois que eu postei isso: P
Loupax
10

Uma maneira de fazer isso é colocar as duas imagens no HTML, dentro de um SPAN ou DIV, para ocultar o padrão com CSS ou JS no carregamento da página. Então você pode alternar no clique. Aqui está um exemplo semelhante que estou usando para colocar os ícones esquerdo / baixo em uma lista:

$(document).ready(function(){
    $(".button").click(function () {
        $(this).children(".arrow").toggle();
            return false;
    });
});

<a href="#" class="button">
    <span class="arrow">
        <img src="/images/icons/left.png" alt="+" />
    </span>
    <span class="arrow" style="display: none;">
        <img src="/images/down.png" alt="-" />
    </span>
</a>
alexp206
fonte
5

Isso funciona em todos os navegadores atuais no WinXP. Basicamente, basta verificar qual é a imagem atual do segundo plano. Se for imagem1, mostre a imagem2, caso contrário, mostre a imagem1.

O material jsapi apenas carrega o jQuery a partir do CDN do Google (mais fácil para testar um arquivo variado na área de trabalho).

A substituição é para compatibilidade entre navegadores (opera e, por exemplo, adicione aspas ao url e firefox, chrome e safari remove aspas).

<html>
    <head>
        <script src="http://www.google.com/jsapi"></script>
        <script>
          google.load("jquery", "1.2.6");
          google.setOnLoadCallback(function() {
            var original_image = 'url(http://stackoverflow.com/Content/img/wmd/link.png)';
            var second_image = 'url(http://stackoverflow.com/Content/img/wmd/code.png)';

            $('.mydiv').click(function() {
                if ($(this).css('background-image').replace(/"/g, '') == original_image) {
                    $(this).css('background-image', second_image);
                } else {
                    $(this).css('background-image', original_image);
                }

                return false;
            });
          });
        </script>

        <style>
            .mydiv {
                background-image: url('http://stackoverflow.com/Content/img/wmd/link.png');
                width: 100px;
                height: 100px;
            }
        </style>
    </head>
    <body>
        <div class="mydiv">&nbsp;</div>
    </body>
</html>
enobrev
fonte
1
apenas fiz isso por exemplo. Dessa forma, todo o trecho de código funciona por conta própria.
enobrev 31/10/08
20
Carregá-lo no Google é preferível para sites públicos. É provável que a CDN do Google seja mais rápida que o seu site, faça o download em paralelo com outra coisa no site, e quanto mais sites o usarem, maior será a probabilidade de uma cópia em cache do navegador do usuário.
Dave Ward
2
Se o Google cair e eu ainda estiver vivo; Avise-se me.
greenimpala
1
@ Nick Ir para jQuery.com, você vai encontrar as suas próprias utilizações do website<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
meagar
2
@ Nick A questão realmente deve ser, por que você não gostaria de carregar se fora do Google. :-)
John Parker
5

O meu é animado:

$(this).animate({
    opacity: 0
}, 100, function() {
    // Callback
    $(this).css("background-image", "url(" + new_img + ")").promise().done(function(){
        // Callback of the callback :)
        $(this).animate({
            opacity: 1
        }, 600)
    });    
});
yPhil
fonte
4

Eu fiz o meu usando expressões regulares, pois queria preservar um caminho relativo e não usar a função addClass. Eu só queria fazê-lo complicado, lol.

$(".travelinfo-btn").click(
            function() {
                $("html, body").animate({scrollTop: $(this).offset().top}, 200);
                var bgImg = $(this).css('background-image')
                var bgPath = bgImg.substr(0, bgImg.lastIndexOf('/')+1)
                if(bgImg.match(/collapse/)) {
                    $(this).stop().css('background-image', bgImg.replace(/collapse/,'expand'));
                    $(this).next(".travelinfo-item").stop().slideToggle(400);
                } else {
                    $(this).stop().css('background-image', bgImg.replace(/expand/,'collapse'));
                    $(this).next(".travelinfo-item").stop().slideToggle(400);
                }
            }
        );
user2220104
fonte
3

Postagem antiga, mas isso permitirá que você use um sprite de imagem e ajuste a repetição e o posicionamento usando a abreviação da propriedade css (plano de fundo, repetição, parte superior esquerda).

$.each($('.smallPreview'), function(i){
  var $this = $(this);

  $this.mouseenter(function(){
    $this.css('background', 'url(Assets/imgs/imgBckg-Small_Over.png) no-repeat 0 0');
  });

  $this.mouseleave(function(){
    $this.css('background', 'url(Assets/imgs/imgBckg-Small.png) no-repeat 0 0');
  });

});
bphillips
fonte
2

Encontrei uma solução em um fórum, Toggle Background Img .

Sebastian Wolf
fonte
Bem-vindo ao Stack Overflow, Sebastian. Esta pergunta foi feita há mais de um ano e já tem várias respostas aceitáveis.
Rjh 24/03
2

Sprites CSS funcionam melhor. Tentei mudar de classe e manipular a propriedade 'background-image' com jQuery, nenhuma funcionou. Eu acho que é porque os navegadores (pelo menos o Chrome estável mais recente) não podem "recarregar" uma imagem já carregada.

Bônus: os Sprites CSS são mais rápidos para baixar e mais rápidos para exibir. Menos solicitações de HTTP significam um carregamento mais rápido da página. Reduzir o número de HTTP é a melhor maneira de melhorar o desempenho do front end, por isso recomendo seguir esse caminho o tempo todo.

DjebbZ
fonte
2

Esta é uma resposta bastante simples que altera o plano de fundo do site com uma lista de itens

function randomToN(maxVal) {
    var randVal = Math.random() * maxVal;
    return typeof 0 == 'undefined' ? Math.round(randVal) : randVal.toFixed(0);
};
var list = [ "IMG0.EXT", "IMG2.EXT","IMG3.EXT" ], // Images
    ram = list[parseFloat(randomToN(list.length))], // Random 1 to n
    img = ram == undefined || ram == null ? list[0] : ram; // Detect null
$("div#ID").css("backgroundImage", "url(" + img + ")"); // push de background

fonte
Simples? Poderia ser muito mais simples. Por que aleatório?
uınbɐɥs
Porque o usuário é mais fácil de ver o que muda o plano de fundo e muda :). Desculpe pelo meu inglês
0

Eu também sempre uso um carimbo de data e hora para impedir que os navegadores armazenem em cache a imagem. Por exemplo, se o usuário estiver girando seu avatar, ele geralmente será armazenado em cache e parecerá não mudar.

var d = new Date();
var t = d.getTime();

$('#avatar').css("background-image", "url(" + iPath + "?" + t + ")");
AdamVanBuskirk
fonte