Migrando eventos de mutação e de mudança de propriedades para observadores de mutação

Observadores de Mutação no Internet Explorer 11 são uma substituição de rápido desempenho para todos os mesmos cenários com suporte em eventos de mutação, bem como uma alternativa para os cenários com suporte em eventos de mudança de propriedade.

Você pode migrar o código existente usando eventos de mutação e/ou eventos de mudança de propriedades para usar observadores de mutação.

Técnicas herdadas para o monitoramento de mutações DOM

Mutation events desempenham um papel essencial na plataforma da Web. Eles permitem que aplicativos Web monitorem de forma síncrona as mudanças dinâmicas em elementos no DOM (Document Object Model) de uma página da Web. Embora muito úteis, eventos de mutação também são conhecidos por causarem regressões no desempenho de aplicativos, principalmente devido à sua natureza síncrona e à arquitetura de eventos com base na qual eles funcionam.

Observação   definidoMutation events (as defined em Eventos DOM Nível 3 do W3C) foram preteridos em favor de observadores de mutação (W3C DOM4).

Eventos de mudança de propriedades fornecem um comportamento semelhante ao de eventos de mutação. Eles também provocam uma penalidade de desempenho devido ao sistema herdado de eventos de navegador que eles precisam usar para funcionar corretamente.

Observação  O evento onpropertychange apenas tem suporte com o attachEvent modelo de registro de eventos herdado exclusivo para IE, que foi preterido desde o Windows Internet Explorer 9 (e suspenso no IE11) em favor do modelo de eventos "addEventListener" padrão do W3C.

Identificando eventos de mutação

Os eventos de mutação, disponíveis pela primeira vez no Internet Explorer 9, podem ser facilmente identificados pelo nome, que é um parâmetro de cadeia de caracteres transmitido para as APIs de plataforma addEventListener ou removeEventListener:

  • DOMNodeInserted
  • DOMNodeRemoved
  • DOMSubtreeModified
  • DOMAttrModified
  • DOMCharacterDataModified

Observação  Dois eventos de mutação adicionais são definidos pelo padrão, mas não têm suporte no Internet Explorer: DOMNodeInsertedIntoDocument e DOMNodeRemovedFromDocument.

Veja a seguir um exemplo da possível aparência desses eventos no código JavaScript:


someElement.addEventListener("DOMAttrModified", function() {
  //...
}, false);

Os eventos de mutação DOMNodeInserted, DOMNodeRemoved e DOMSubtreeModified monitoram mudanças estruturais nos filhos de um elemento—elementos são adicionados aos filhos do elemento ou são removidos. O evento DOMSubtreeModified é para ambos: ele é disparado tanto para remoções quanto para adições. No entanto, ele não contém informações sobre por que foi disparado (não é possível diferenciar uma adição de uma remoção com base no evento isoladamente).

O evento de mutação DOMAttrModified registra mudanças na lista de atributos de um elemento. Esse único evento inclui informações relacionadas a inserções, remoções ou mudanças de atributos.

O evento de mutação DOMCharacterDataModified registra mudanças no conteúdo de texto de um elemento. O conteúdo de texto é agrupado em unidades lógicas chamadas de nós de texto, e apenas as modificações em um nó de texto existente irão disparar o evento DOMCharacterDataModified. Se novos nós de texto forem inseridos/criados, eles são indicados como eventos DOMNodeInserted.

Deve ser simples encontrar eventos de mutação no seu código, por exemplo, usando o recurso de pesquisa Localizar em arquivos... do seu editor favorito. Lembre-se de que variáveis são muitas vezes usadas no método addEventListener. Por isso, em primeiro lugar, faça uma pesquisa em busca do uso das cadeias de eventos de mutação ("DOMNodeInserted", "DOMNodeRemoved", etc.) e depois confira todas as ocorrências de addEventListener para ter certeza que você encontrou todas elas.

Identificando eventos de mudança de propriedades

Os eventos de mudança de propriedades podem ser identificados pelo nome do evento onpropertychange usado em conjunto com as APIs de registro de eventos herdadas attachEvent ou detachEvent exclusivas do IE. Pesquise todas as ocorrências de attachEvent e verifique o primeiro parâmetro de onpropertychange para encontrar esse tipo de uso em seu código.

O evento de mudança de propriedade é disparado quando ocorrem mudanças nas propriedades de um elemento DOM. O evento não é ativado e foi preterido desde o Internet Explorer 9 em favor do modelo de evento "addEventListener" padrão do W3C. O evento inclui o nome da propriedade que foi modificada no getter do evento propertyName. Infelizmente, para expedir um evento de mudança de propriedades, também são calculados vários outros atributos de evento, alguns dos quais responsáveis por forçar o recálculo do mecanismo de layout, causando um custo de desempenho substancial para qualquer aplicativo que esteja utilizando esses eventos.

Unlike with mutation events, o evento de mudança de propriedades não é claramente mapeado para observadores de mutação. No entanto, será possível substituir o uso de eventos de mudança de propriedades por observadores de mutação quando os nomes das propriedades de interesse estiverem refletidos em atributos HTML. Por exemplo, a id, que reflete o atributo id e style.color, que se reflete no atributo style serializado e className, que corresponde ao atributo class.

Observação  Para propriedades que não são refletidas em atributos HTML (como value em elementos input), você pode usar o recurso ECMAScript 5 (JavaScript) denominado defineProperty. Este documento não descreve como migrar eventos de mudança de propriedades usando a API Object.defineProperty JavaScript .

Como observadores de mutação diferem

Observadores de mutação não são baseados no modelo de evento da plataforma da Web. Esta é uma importante diferença que permite uma expedição muito mais rápida e sem a necessidade de propagar um evento através da hierarquia de elementos DOM.

Além disso, os observadores de mutação foram projetados para gravar várias alterações antes de notificarem o seu observador. Eles agrupam registros de mutação em lote com o objetivo de evitar inundações de eventos no seu aplicativo. Por outro lado, eventos de mutação são síncronos e interrompem a execução do código normal para notificar seu aplicativo sobre mutações. Apesar do modelo de notificação atrasado empregado por observadores mutação, o observador do seu aplicativo ainda tem a garantia de receber (e tem a chance de processar) todos os registros de mutação antes do próximo redesenho.

Ambas as mudanças afetam como o seu aplicativo deve ser adaptado para dar suporte a observadores de mutação.

Registro de observadores de mutação

Observadores de mutação devem ser primeiramente criados antes de serem registrados em um determinado elemento. Para criar um observador de mutação, use o operador new JavaScript e especifique um método de retorno de chamada:


var mutationObserver = new MutationObserver(callback);

O retorno de chamada fornecido ao construtor de observadores de mutação será diferente do retorno de chamada que você provavelmente está usando para os seus eventos de mutação atuais. Isto será explicado com mais detalhes a seguir.

Depois de criar o observador, você agora o instrui a observar um elemento específico. Em geral, este será o mesmo elemento no qual você estava registrando o evento de mutação:


mutationObserver.observe(someElement, options);

Se você não salvar uma referência a ele, a instância do observador de mutação será preservada na memória pela plataforma da Web desde que ela esteja observando pelo menos um elemento. Se você não salvar uma referência ao observador, ainda será possível fazer uma referência a ele a partir do seu retorno de chamada (será o objeto this no escopo do retorno de chamada, bem como o segundo parâmetro para a função de retorno de chamada).

O parâmetro options é um objeto JavaScript simples com propriedades que você deve fornecer para descrever exatamente quais tipos de mutações deseja observar. As opções de propriedades correspondem às três categorias de mutações observadas anteriormente:

  • childList
  • attributes
  • characterData

A opção childList com um valor de true significa observar mudanças nos elementos filho deste elemento (tanto remoções quanto adições). Essa opção inclui nós de texto que são adicionados ou removidos como filhos deste elemento.

A opção attribute com um valor de true significa observar mudanças nos atributos deste elemento (remoções, adições e mudanças).

A opção characterData com um valor de true significa observar mudanças nos nós de texto deste elemento (mudanças nos valores dos nós de texto, exceto quando esses nós são totalmente removidos ou recém-adicionados).

Uma quarta opção subtree também é importante. As três opções anteriores (por padrão) só observam seu elemento de destino de forma isolada, sem levar em consideração seus descendentes (sua subárvore). Para monitorar o elemento especificado e todos os seus descendentes, defina a propriedade subtree como true. Como eventos de mutação têm as característica de propagação no DOM, o uso da opção subtree é necessário para manter a paridade com os eventos de mutação registrados em elementos ancestrais.

A tabela a seguir descreve quais opções de observadores de mutação correspondem a quais nomes de eventos de mutação:

Evento de mutação Opções de observadores de mutação Observações
DOMNodeInserted { childList: true, subtree: true } O retorno de chamada deve ignorar manualmente registros de remoção de nó
DOMNodeRemoved { childList: true, subtree: true } O retorno de chamada deve ignorar manualmente registros de adição de nó
DOMSubtreeModified { childList: true, subtree: true } Agora, o retorno de chamada pode diferenciar entre nós adicionados e removidos
DOMAttrModified { attributes: true, subtree: true }
DOMCharacterDataModified { characterData: true, subtree: true }

 

Observação  Com observadores de mutação, também é possível combinar várias opções para observar childLists, atributos e characterData ao mesmo tempo.

Por fim, há várias opções para salvar os valores anteriores de atributos e mudanças de dados de caracteres, bem como para restringir o escopo de quais atributos é importante observar:

  • As opções attributeOldValue e characterDataOldValue com um valor de true salvam o valor anterior quando ocorrem mudanças em attributes ou em characterData.
  • A opção attributeFilter com uma matriz de cadeias de nomes de atributos limita a observação aos atributos especificados. Essa opção só é relevante quando a opção attributes está definida como true.

Com essas informações, qualquer código que era anteriormente registado para um evento de mutação pode ser substituído por um código que se regista para um observador de mutação:


// Watch for all changes to the body element's children
document.body.addEventListener("DOMNodeInserted", nodeAddedCallback, false);
document.body.addEventListener("DOMNodeRemoved", nodeRemovedCallback, false);


Passa a ser:


// Watch for all changes to the body element's children
new MutationObserver(nodesAddedAndRemovedCallback).observe(document.body, 
  { childList: true, subtree: true });


Retornos de chamada de observadores de mutação

A função de retorno de chamada de observador de mutação é invocada com dois parâmetros:

  • Uma lista de registros
  • Uma referência ao objeto de observador de mutação que está invocando o retorno de chamada

Tenha cautela se você estiver reutilizando retornos de chamada de eventos de mutação para observadores de mutação. Quando uma mutação relevante acontece, MutationObserver grava as informações de mudança solicitadas em um objeto MutationRecord e invoca a função de retorno de chamada, mas não até que todos os scripts dentro do escopo atual tenham sido executados. É possível que mais de uma mutação (cada uma representado por um único MutationRecord) ocorra desde a última ocasião em que o retorno de chamada foi invocado.

O parâmetro records é uma matriz JavaScript formada por objetos MutationRecord. Cada objeto na matriz representa uma mutação que ocorreu em um ou mais elementos que estão sendo observados.

Um registro tem as seguintes propriedades:

Propriedade MutationRecord Descrição

type

O tipo de mutação que esse registro registrou. Valores possíveis: attributes, characterData, childList.

target

O elemento no qual a mutação foi registrada. Semelhante a event.target ou a event.srcElement.

addedNodes, removedNodes

Uma matriz de nós que foram adicionados ou removidos como parte dessa mutação. Apenas é relevante quando type é childList. Essas matrizes podem estar vazias.

previousSibling, nextSibling

Os irmãos anteriores e seguintes do nó adicionado ou removido. Apenas são relevantes quando type é childList. Esses valores podem ser null.

attributeName, attributeNamespace

O nome e o namespace do atributo que foi adicionado, removido ou modificado. O valor será null se o tipo de registro não for attributes.

oldValue

O valor anterior de attribute ou characterData. Esse valor poderá ser null se as opções do observador de mutação não incluírem os sinalizadores attributeOldValue ou characterDataOldValue, ou se type for childList.

 

 

 

Mostrar:
© 2014 Microsoft