Inject HTML mit JavaScript nur top level element angezeigt?

1 Antwort

In diesem Fall klappt es so:

const node = document.querySelector("ytd-download-button-renderer");
const dolly = node.cloneNode(false);
node.parentNode.insertBefore(dolly, node);
dolly.innerHTML = node.innerHTML;
node.remove();

Statt die Kindelemente mit innerHTML zu holen, könnte man auch alle direkten Kinder des Originalknotens via appendChild an den Klon hängen.

for (const child of Array.from(node.childNodes)) {
  dolly.appendChild(child);
}

Auf diese Weise würde man die Event-Listener, die an diesen Elementen hängen, nicht verlieren.

PeterGriffing 
Fragesteller
 25.01.2022, 09:20

Werde ich probieren und melde mich dann nochmal. Wenn ich meinen jetzigen Code auf einer anderen Website ausführe, wird das Element wie gewünscht eingefügt mit allen Unterelementen, nur auf YT geht es nicht.

0
PeterGriffing 
Fragesteller
 25.01.2022, 18:30

Das hat begrenzt funktioniert. Die Unterelemente werden eingefügt, aber 2 Elemente darunter Fehlen das svg Element und der Text "Herunterladen" ist zwar in area-label enthalten, fehlt allerdings in yt-formatted-string. Muss ich da den textContent noch manuell setzen?

<ytd-download-button-renderer class="style-scope ytd-menu-renderer style-default size-default force-icon-button" use-keyboard-focused="" button-renderer="true" style-action-button="" is-icon-button="" loadeddl="true"><a class="yt-simple-endpoint style-scope ytd-download-button-renderer" tabindex="-1"><yt-icon-button id="button" class="style-scope ytd-download-button-renderer style-default size-default" touch-feedback=""><!--css-build:shady--><button id="button" class="style-scope yt-icon-button"><!--css-build:shady--><button id="button" class="style-scope yt-icon-button" aria-label="Herunterladen"><yt-icon class="style-scope ytd-download-button-renderer"><!--css-build:shady--></yt-icon></button><yt-interaction id="interaction" class="circular style-scope yt-icon-button"><!--css-build:shady--><div class="stroke style-scope yt-interaction"></div><div class="fill style-scope yt-interaction"></div></yt-interaction></button><yt-interaction id="interaction" class="circular style-scope yt-icon-button"><!--css-build:shady--><div class="stroke style-scope yt-interaction"></div><div class="fill style-scope yt-interaction"></div></yt-interaction></yt-icon-button><yt-formatted-string id="text" class="style-scope ytd-download-button-renderer style-default size-default">
<!--css-build:shady--></yt-formatted-string></a></ytd-download-button-renderer>
0
PeterGriffing 
Fragesteller
 25.01.2022, 19:53

Habe es jetzt mit folgendem Code hinbekommen, das Icon ist zwar nicht dort wo es original war aber es wird richtig angezeigt:

const node = document.querySelector("ytd-download-button-renderer");
  const dolly = node.cloneNode(false);
  dolly.removeAttribute("is-hidden");
  dolly.setAttribute("loadeddl", "true");
  node.removeAttribute("is-hidden");
  node.setAttribute("loadeddl", "true");
  node.parentNode.insertBefore(dolly, node);
  dolly.innerHTML = node.innerHTML;
  node.remove();
  dolly.setAttribute("loadeddl", "true");
  dolly.removeAttribute("is-hidden");
  dolly.querySelector("yt-formatted-string").textContent = "Herunterladen";
  dolly.querySelector(
    "yt-icon-button"
  ).innerHTML = `<svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope yt-icon" style="pointer-events: none; display: block; width: 100%; height: 100%; color:#ffffff"><g class="style-scope yt-icon"><path fill="#ffffff" d="M17 18V19H6V18H17ZM16.5 11.4L15.8 10.7L12 14.4V4H11V14.4L7.2 10.6L6.5 11.3L11.5 16.3L16.5 11.4Z" class="style-scope yt-icon"></path></g></svg>`;
  
  dolly.onclick = function () {
    downloadURL(currentURL);


    return false;
  };
1