Estou trabalhando em uma extensão no Chrome e me pergunto: qual é a melhor maneira de descobrir quando um elemento surge? Usando javascript simples, com um intervalo que verifica até a existência de um elemento, ou o jQuery tem alguma maneira fácil de fazer isso?
237
MutationObserver
>DOM Mutation Events
>setTimeout
.setTimeout
é compatível, simples de implementar, simples de manter e possui sobrecarga insignificante.setTimeout
+jQuery
é menos do que ideal na minha opinião, por duas razões: 1.) jQuery inchar 2.) você está desnecessariamente consultando manualmente o DOM quanto a elementos, eventos superam essa velocidade com facilidade, 3.) sempre será mais lento que qualquer nativo implementação. Se você precisar fazer algo com base na presença de um elemento razoavelmente rápido, especialmente se a experiência perfeita do usuário for sua meta, ela será inferior.Respostas:
DOMNodeInserted
está sendo preterido, junto com os outros eventos de mutação do DOM, devido a problemas de desempenho - a abordagem recomendada é usar um MutationObserver para monitorar o DOM. No entanto, ele é suportado apenas em navegadores mais novos, portanto, você deve voltarDOMNodeInserted
quandoMutationObserver
não estiver disponível.fonte
if (mutation.addedNodes.length)
poisif (mutation.addedNodes)
ainda retornaria verdadeiro, mesmo que seja uma matriz vazia. (2) Você não pode fazer issomutation.addedNodes.forEach()
porque addedNodes é um nodeList e não pode iterar por meio de um nodeList com forEach. Para uma solução para isso, consulte toddmotto.com/ditch-the-array-foreach-call-nodelist-hackEu estava tendo o mesmo problema, então fui em frente e escrevi um plugin para ele.
$(selector).waitUntilExists(function);
Código:
fonte
window.setInterval
). Eu não sei se aMutationObserver
resposta funciona pesquisando também ... #;
no início da função (;(function ($, window) {
)?Aqui está uma função JavaScript principal para aguardar a exibição de um elemento.
Parâmetros:
selector
: Esta função procura o elemento $ {selector}time
: Esta função verifica se esse elemento existe a cada $ {time} milissegundos.Como exemplo, defina
selector="#div1"
etime=5000
procure a tag HTML cujaid="div1"
cada 5000 milissegundos.fonte
querySelector
? developer.mozilla.org/pt-BR/docs/Web/API/Document/querySelectorVocê pode ouvir
DOMNodeInserted
ouDOMSubtreeModified
eventos que o fogo sempre que um novo elemento é adicionado ao DOM.Há também o plug- in LiveQuery jQuery que detectaria quando um novo elemento fosse criado:
fonte
Eu usei essa abordagem para aguardar a exibição de um elemento para que eu possa executar as outras funções depois disso.
Digamos que a
doTheRestOfTheStuff(parameters)
função só deve ser chamada depois que o elemento com IDthe_Element_ID
aparecer ou o carregamento terminar, podemos usar,fonte
Você pode fazer
Observe que isso só funcionará se o elemento estiver presente no DOM ao ser solicitado pelo servidor. Se o elemento estiver sendo adicionado dinamicamente via JavaScript, ele não funcionará e você pode precisar procurar as outras respostas.
fonte
.ready()
função funciona para quase qualquer coisa (se não alguma coisa), não apenasdocument
. Ele simplesmente não funciona com elementos criados dinamicamente, mesmo.live()
.$(document).ready()
, e não o elemento que você acha que será aplicado também. É assim que esse ouvinte especial funciona. ExemploAcho que ainda não há resposta aqui com um exemplo de trabalho fácil e legível. Use MutationObserver
interface
para detectar alterações no DOM, assim:fonte
Basta adicionar o seletor desejado. Depois que o elemento é encontrado, você pode acessar a função de retorno de chamada.
fonte
Para uma abordagem simples usando jQuery, achei que funcionou bem:
Aqui, simplesmente verificamos a cada 500ms para ver se o elemento está carregado, quando está, podemos usá-lo.
Isso é especialmente útil para adicionar manipuladores de clique a elementos que foram adicionados dinamicamente ao documento.
fonte
E a biblioteca insertionQuery ?
insertionQuery usa retornos de chamada de Animação CSS anexados ao (s) seletor (es) especificado (s) para executar um retorno de chamada quando um elemento é criado. Esse método permite que os retornos de chamada sejam executados sempre que um elemento é criado, não apenas na primeira vez.
No github:
fonte
Aqui está uma função que atua como um invólucro fino em torno do MutationObserver. O único requisito é que o navegador suporte MutationObserver; não há dependência no JQuery. Execute o snippet abaixo para ver um exemplo de trabalho.
fonte
Aqui está uma solução que promete retorno em Javascript baunilha (sem retornos de chamada confusos). Por padrão, ele verifica a cada 200ms.
fonte
Aqui está uma função Javascript pura que permite aguardar qualquer coisa. Defina o intervalo mais longo para consumir menos recursos da CPU.
Para chamar isso, por exemplo, no jQuery, use algo como:
fonte
Uma solução que retorna
Promise
e permite usar um tempo limite (IE 11+ compatível).Para um único elemento (digite Elemento):
Para vários elementos (tipo NodeList):
Exemplos:
Funciona para uma lista de elementos e um único elemento.
fonte
element instanceof HTMLElement
? Pode alguma vez ser outra coisa senãonull
ouHTMLElement
?Element
(fixo). Acabei de fazer a verificação porque quero ter certeza de que a variávelelement
tem a propriedadeinnerHTML
conforme a documentação do Element MDN . Sinta-se livre para removê-lo, se você não se importa!Um exemplo mais limpo usando MutationObserver:
fonte
Esta é uma solução simples para aqueles que estão acostumados a promessas e não querem usar libs ou timers de terceiros.
Eu tenho usado em meus projetos há um tempo
Para usá-lo:
ou com assíncrono / espera
fonte
async
/await
também. Você também pode obter mais desempenho com issomutations.addedNodes.find(node => node.matchesSelector("..."))
Se você deseja que ele pare de cuidar de um tempo (tempo limite), o jQuery a seguir funcionará. O tempo limite será excedido após 10 segundos. Eu precisava usar esse código em vez de JS puro, porque precisava selecionar uma entrada por nome e estava tendo problemas para implementar algumas das outras soluções.
fonte
Eu costumo usar esse snippet para o Gerenciador de tags:
fonte
se você tiver alterações assíncronas do dom, essa função verificará (com limite de tempo em segundos) os elementos DOM, não será pesado para o DOM e seus baseados em Promessa :)
fonte