2016-04-21 19 views
2

Ich habe eine Chrome-Erweiterung, und ich möchte warten, bis ein Element geladen wird, bevor Sie Inhalte in die Seite injizieren.Chrome-Erweiterung: Warten auf Element zu laden (async js)

Ich versuche, eine Taste zu injizieren:

myButton = document.createElement('button'); 
myButton.class = 'mybutton'; 
document.querySelector('.element_id').appendChild(myButton) 

ich dieses Skript an der Spitze meines Inhalt haben. Früher funktionierte es gut, aber dann hörte es auf zu arbeiten. Der Fehler, der angezeigt wurde, war:

Uncaught TypeError: Cannot read property 'appendChild' of null

Um .element_id für das Element mit Klasse-ID zu warten, zu laden, habe ich versucht, einen MutationObserver

var observer = new MutationObserver(function(mutations) { 
    mutations.forEach(function(mutation) { 
     if (!mutation.addedNodes) return 

     for (var i = 0; i < mutation.addedNodes.length; i++) { 
      if (mutation.addedNodes[i].parentNode == document.querySelector('#outer-container')) { 

       myButton = document.createElement('button'); 
       myButton.class = 'mybutton'; 
       document.querySelector('.element_id').appendChild(myButton) 
     } 
      var node = mutation.addedNodes[i] 
     } 
    }) 
}) 

observer.observe(document.body, { 
    childList: true 
    , subtree: true 
    , attributes: false 
    , characterData: false 
}) 

zu verwenden, wenn ich die Mutation Beobachter verwendet, Die Seite würde ein externes div-Element namens outer-container laden, und es gab keine Möglichkeit für mich, die Klasse .element_id direkt zu vergleichen. Die Klasse .element_id ist eine Anzahl von Schichten in das äußere div geschachtelt.

ABER, das obige funktionierte nicht, und ich erhielt immer noch den Null-Eigenschaft Fehler.

Gibt es eine bessere Möglichkeit zu warten, dass ein Element geladen wird (welches async geladen ist), bevor es injiziert wird?

Antwort

0

Vergessen Sie nicht, die Eigenschaften childList und subtree hinzuzufügen, wenn Sie Änderungen beobachten.

+0

Entschuldigung, ich habe vergessen, die Eigenschaften aufzunehmen. Ich hatte 'childList', aber es scheitert immer noch :( – confused

+0

@confused, können Sie bitte meinen Code versuchen? Ich habe überprüft und ich glaube, es sollte funktionieren. –

+0

@HaibaraAi Siehe meine Antwort. – Xan

1

Bei einer Einfügung in DOM kann das betreffende Element tiefer im hinzugefügten Knoten enthalten sein.

Zum Beispiel kann dies in den DOM eingefügt:

<div class="container"> 
    <div class="element_id">...</div> 
    ... 
</div> 

In diesem Fall kann die hinzugefügte Knotenliste enthält nur die .container Knoten.

Die Mutation wird nicht alle hinzugefügten Elemente auflisten, es liegt in Ihrer Verantwortung, rekursiv in das hinzugefügte Fragment zu graben, das durch die hinzugefügten Knoten schaut.

Die Verwendung von mutation-summary library kann Ihnen helfen, solche Kopfschmerzen zu vermeiden.

var observer = new MutationSummary({ 
    rootNode: document.body, 
    callback: function(summaries) { 
    summaries.forEach(function(summary) { 
     summary.added.forEach(function(idElement) { 
     /* ... */ 
     idElement.appendChild(myButton); 
     }); 
    }); 
    }, 
    queries: [{element: ".element_id"}] 
}); 

Wenn Sie eine Bibliothek nicht verwenden möchten, können Sie versuchen, querySelector oder querySelectorAll auf addedNodes[i] aufrufen.