Pergunta

Preciso de um mecanismo eficiente para detectar alterações no DOM. Preferencialmente transfrondester, mas se houver algum meio eficiente que seja não Navegador cruzado, posso implementá-los com um método de navegador cruzado à prova de falhas.

Em particular, preciso detectar alterações que afetariam o texto em uma página, para que quaisquer elementos novos, removidos ou modificados ou alterações no texto interno (InnerHTML) sejam necessários.

Não tenho controle sobre as alterações que estão sendo feitas (elas podem ser devidas ao JavaScript de terceiros inclui, etc.), por isso não pode ser abordado a partir desse ângulo - preciso "monitorar" as alterações de alguma forma.

Atualmente, implementei um método "Quick'n'dirty" que verifica body.innerHTML.length nos intervalos. É claro que isso não detectará mudanças que resultam no mesmo comprimento que está sendo retornado, mas neste caso é "bom o suficiente" - as chances de isso acontecer são extremamente pequenas e, neste projeto, não detectar uma mudança não resultará em dados perdidos.

O problema com body.innerHTML.length é caro. Pode levar entre 1 e 5 milissegundos em um velozes O navegador, e isso pode atingir muito as coisas - também estou lidando com um grande número de iframes e tudo se soma. Tenho certeza de que a despesa de fazer isso é porque o texto innerhtml não é armazenado estaticamente por navegadores e precisa ser calculado a partir do DOM toda vez que for lido.

Os tipos de respostas que procuro são qualquer coisa, desde o "preciso" (por exemplo, evento) até o "bom o suficiente" - talvez algo como "Quick'n'dirty" como o método INNERHTML.Length, mas que executa mais rapidamente.

Editar: eu também deveria ressaltar que, embora seja "bom" detectar o elemento preciso que foi modificado, não é uma necessidade absoluta - apenas o fato de ter havido algum A mudança seria boa o suficiente. Espero que isso amplie as respostas das pessoas. Vou investigar eventos de mutação, mas ainda preciso de um retorno para o apoio do IE, então qualquer idéias loucas, criativas e fora do quadrado seria muito bem-vinda.

Foi útil?

Solução

http://www.quirksmode.org/js/events/domtree.html

O JQuery agora suporta uma maneira de anexar eventos aos elementos existentes e futuros correspondentes a um seletor: http://docs.jquery.com/events/live#typefn

Outro achado interessante - http://james.padolsey.com/javascript/monitoring-dom-properties/

Outras dicas

Para atualizar isso, o padrão DOM4 acaba com os eventos de mutação e os substitui por observadores de mutação: https://developer.mozilla.org/en-us/docs/web/api/muationObserver

Eventos de mutação são a recomendação do W3 do que você está procurando ..

Não tenho certeza se eles são suportados por toda parte .. (ou seja, provavelmente não os apoiará ..)

Você pode tentar usar os eventos DomNodeInserted e Domnoderemoved. Adendando ao Quirksmode, eles meio que trabalham na maioria dos navegadores, com a notável exceção do IE ...

http://www.quirksmode.org/dom/events/index.html

Eu escrevi recentemente um plugin que faz exatamente isso - jQuery.initialize

Você o usa da mesma maneira que .each função

$(".some-element").initialize( function(){
    $(this).css("color", "blue"); 
});

A diferença de .each é - é preciso seu seletor, neste caso .some-element E aguarde novos elementos com este seletor no futuro, se esse elemento for adicionado, ele também será inicializado.

No nosso caso, inicialize a função, basta alterar a cor do elemento para azul. Portanto, se adicionaremos um novo elemento (não importa se o Ajax ou mesmo o inspetor F12 ou qualquer coisa) como:

$("<div/>").addClass('some-element').appendTo("body"); //new element will have blue color!

O plug -in iniciará instantaneamente. O plug -in também garante que um elemento seja inicializado apenas uma vez. Então, se você adicionar elemento, então .deatch() Do corpo e adicione novamente, não será inicializado novamente.

$("<div/>").addClass('some-element').appendTo("body").detach()
    .appendTo(".some-container");
//initialized only once

O plugin é baseado em MutationObserver - ele funcionará no IE9 e 10 com dependências, conforme detalhado no ReadMe Page.

JQuery Muttate também faz isso, por padrão, ele suporta como height, width, scrollHeight etc ... mas também pode ser estendido com um pouco de código extra para adicionar novos eventos, como ver se o texto mudou etc ...

http://www.jqui.net/jquery-projects/jquery-mutate-fficial/

Espero que ajude

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top