Detecção de evento quando a propriedade css é alterada usando Jquery

91

Existe uma maneira de detectar se a propriedade css "display" de um elemento é alterada (para nenhum ou bloco ou bloco embutido ...)? se não, algum plugin? obrigado

HP.
fonte

Respostas:

93

Nota

Os eventos de mutação foram descontinuados desde que esta postagem foi escrita e podem não ser suportados por todos os navegadores. Em vez disso, use um observador de mutação .

Sim você pode. O módulo DOM L2 Events define eventos de mutação ; um deles - DOMAttrModified é o que você precisa. Concedido, eles não são amplamente implementados, mas são suportados pelo menos nos navegadores Gecko e Opera.

Experimente algo neste sentido:

document.documentElement.addEventListener('DOMAttrModified', function(e){
  if (e.attrName === 'style') {
    console.log('prevValue: ' + e.prevValue, 'newValue: ' + e.newValue);
  }
}, false);

document.documentElement.style.display = 'block';

Você também pode tentar utilizar o evento "propertychange" do IE como um substituto para DOMAttrModified. Deve permitir detectar stylemudanças de forma confiável.

kangax
fonte
Obrigado. Ele suportará o Firefox?
HP.
7
@Boldewyn: True, mas alterar o classatributo (ou qualquer outro atributo se os seletores de atributo estiverem presentes no CSS) de um ancestral do elemento também pode alterar o elemento, então você terá que lidar com todos os DOMAttrModifiedeventos no elemento raiz do documento para certifique-se de pegar tudo.
Tim Down
12
Esse evento está obsoleto no w3c. Deve ser de outra maneira.
ccsakuweb
8
Os eventos de mutação foram marcados como obsoletos na especificação de eventos DOM, pois o design da API é falho. Observadores de mutação são a substituição proposta. Aqui está o link [ developer.mozilla.org/en-US/docs/DOM/Mutation_events]
Anmol Saraf
1
Anmol - o link MDN para eventos de mutação deve ser: developer.mozilla.org/en-US/docs/Web/Guide/Events/…
groovecoder
19

Você pode usar o plugin Attrchange jQuery . A principal função do plugin é vincular uma função de ouvinte na mudança de atributo dos elementos HTML.

Amostra de código:

$("#myDiv").attrchange({
    trackValues: true, // set to true so that the event object is updated with old & new values
    callback: function(evnt) {
        if(evnt.attributeName == "display") { // which attribute you want to watch for changes
            if(evnt.newValue.search(/inline/i) == -1) {

                // your code to execute goes here...
            }
        }
    }
});
Muhammad Reda
fonte
Observe que para alguns plug-ins que modificam o CSS evnt.attributeName é 'estilo' e não 'exibição'.
jerrygarciuh
Funciona bem, mas é mais rápido do que usar a pesquisa regex e você não precisa do primeiro if (evnt.attributeName ...): if (evnt.newValue.indexOf ('display: inline-block')> -1) {. ..; retorno;}
Dan Randolph,
4

Você pode usar a cssfunção jQuery para testar as propriedades CSS, por exemplo. if ($('node').css('display') == 'block').

Colin está certo, que não há nenhum evento explícito que seja disparado quando uma propriedade CSS específica é alterada. Mas você pode ser capaz de inverter e disparar um evento que define a exibição e tudo mais.

Considere também o uso de classes CSS para obter o comportamento desejado. Freqüentemente, você pode adicionar uma classe a um elemento que o contém e usar CSS para afetar todos os elementos. Costumo colocar uma classe no elemento body para indicar que uma resposta AJAX está pendente. Então, posso usar seletores CSS para obter a exibição que desejo.

Não tenho certeza se é isso que você está procurando.

ndp
fonte
3

Para propriedades para as quais a transição css afetará, pode usar o evento transactionend, por exemplo, para z-index:

$(".observed-element").on("webkitTransitionEnd transitionend", function(e) {
  console.log("end", e);
  alert("z-index changed");
});

$(".changeButton").on("click", function() {
  console.log("click");
  document.querySelector(".observed-element").style.zIndex = (Math.random() * 1000) | 0;
});
.observed-element {
  transition: z-index 1ms;
  -webkit-transition: z-index 1ms;
}
div {
  width: 100px;
  height: 100px;
  border: 1px solid;
  position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="changeButton">change z-index</button>
<div class="observed-element"></div>

IgorL
fonte
-17

Você não pode. CSS não suporta "eventos". Atrevo-me a perguntar para que você precisa? Confira esse post aqui no SO. Não consigo pensar em uma razão pela qual você gostaria de conectar um evento a uma mudança de estilo. Estou assumindo aqui que a mudança de estilo é desencadeada em algum outro lugar por um pedaço de javascript. Por que não adicionar lógica extra lá?

Colin
fonte
1
Tenho vários eventos que podem fazer aparecer uma caixa ou não. E eu tenho outro elemento que meio que depende da aparência dessa caixa para fazer as coisas. Agora, não quero repetir o código e me conectar a todos os outros eventos que aparecem na caixa, embora essa seja uma maneira de fazer isso. Apenas redundância!
HP.
É redundante, talvez o uso de um sistema baseado em regras funcionasse? ou seja, alguma estrutura semelhante a JSON que define o que deve acontecer a algum controle quando outro controle muda? desta forma, você só precisaria criar 1 função que usa o objeto de regra e talvez o controle atual (id) como parâmetro?
Colin,
3
Por que isso foi rejeitado? Definir a classe para o pai de ambos os elementos e alterar o estilo é a única solução certa para isso.
Ilia G
11
Votar negativamente em "Não consigo pensar em uma razão pela qual você gostaria de conectar um evento a uma mudança de estilo" - se você não consegue pensar em uma razão, isso não significa que não há uma razão possível, e por "Por que não adicionar lógica extra lá? " - porque você nem sempre pode modificar os scripts.
Andrei Cojea
Para fornecer um exemplo, eu quero alterar a propriedade fill de um caminho SVG quando a propriedade color do elemento pai muda.
Andrei Cojea