0

I am trying to develop a Chrome extension which replaces certain HTML in a list of elements that updates itself with time, but I can't find the right way to do it.

I have tried the following:

console.log("Getting nodes...")
var f = document.getElementsByClassName("myClassName")

function watch(data) {
    alert("Changed!!")
}

var observer = new MutationObserver(watch);
observer.observe(f.childList, {childList: true});

But I get the following error:

Uncaught TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'.

Am I missing something? Perhaps there's a better way? Any help will be much appreciated!

xvlaze
  • 837
  • 1
  • 10
  • 30
  • https://stackoverflow.com/questions/10693845/what-do-queryselectorall-and-getelementsby-methods-return – Teemu Sep 14 '22 at 12:35
  • `console.log(f.childList);` – epascarello Sep 14 '22 at 12:39
  • 1
    The `observe` method expects a single `Node` to be observed. `getElementsByClassName` returns an `HTMLCollection`, which is an array-like object with nodes. `HTMLCollection` does not have a `childList` property, so you're basically doing `observer.observe(undefined)` – Emiel Zuurbier Sep 14 '22 at 12:40
  • @EmielZuurbier Then is it impossible to observe if one element on this list is added? – xvlaze Sep 14 '22 at 13:29
  • Surely not. Mind sharing your HTML to see what it is you're trying select and observe? – Emiel Zuurbier Sep 14 '22 at 15:18
  • I don't have it here right now, but it's a list of elements of a social network posts which gets updated when the user scrolls down. The list adds elements correctly, but I can't find how to attach an observer to that list which reacts to changes in its size. – xvlaze Sep 15 '22 at 06:25

2 Answers2

0

Use a forEach on your list, and call observe for each node.

Array.from(elements).forEach(element => observer.observe(element, {childList: true}) )

The childList parameter is for children of each node, and not for a list of nodes.

Steven Spungin
  • 27,002
  • 5
  • 88
  • 78
0

Select your elements with Document.querySelectorAll() if possible. Unlinke getElementsByClassName, querySelectorAll returns a snapshot of elements instead of live list which makes your result more predictable.

Either way, loop over the elements and call observer.observe() for each element in your list.

const elements = document.querySelectorAll('.parent');

const observer = new MutationObserver(() => {
  alert('Changed!');
});

const options = {
  childList: true,
};

for (const element of elements) {
  observer.observe(element, options);
}
Emiel Zuurbier
  • 19,095
  • 3
  • 17
  • 32
  • That's a nice approach, but how would the elements list change its size and launch the event? What I'm looking for is to react when that live list changes. – xvlaze Sep 15 '22 at 06:22
  • The thing is, you can't observe the `HTMLCollection` in that way. You have to observe the parent element where all child elements are added to. – Emiel Zuurbier Sep 15 '22 at 07:34