Estoy tratando de hacer una extensión para Twitter y no puedo insertar el bloque div (algo así como btn) en esta sección. 
Manifiesto.json
{ "manifest_version": 3, "name": "Twitter Saver", "version": "0.0.1", "description": "Twitter Saver| Save tweets.", "permissions": ["tabs", "https://*.twitter.com/*"], "icons": { "128": "img/icon-app-128.png", "256": "img/icon-app-128@2x.png" }, "content_scripts": [ { "html": ["save-dropdown.html"], "js": ["js/jquery-3.6.0.min.js", "js/content.js"], "matches": ["https://*.twitter.com/*"] } ] }Contenido.js
$( "<div>",{ class: "css-1dbjc4n r-18u37iz r-1h0z5md", text: "HELLO WORLD" } ).appendTo(".css-1dbjc4n.r-1ta3fxp.r-18u37iz.r-1wtj0ep.r-1s2bzr4.r-1mdbhws");Investigué algunas cosas como MutationObserver pero aquí recibí un error porque el parámetro no es un nodo
let react_root = $("#react-root"); let callback = function(changeList, observer) => { console.log(changeList); } const observer = new MutationObserver(); observer.observe(callback, {childList: true});Twitter elimina las publicaciones anteriores al desplazarse hacia abajo agregando nuevas y agrega las anteriores eliminando las nuevas al desplazarse hacia arriba
Para Twitter, MutationObserver es el camino a seguir, y para saber cómo usarlo, prefiero esta guía de Mozilla .
Para que funcione correctamente, tenga en cuenta la sintaxis: aquí, al registrar MutationObserver, dice observar todo el cuerpo y los descendientes, y llamar a la función appendCustomNode cuando se produzca un cambio.
// Step 1. Create an observer instance linked to the callback function // const observer = new MutationObserver(callback); // Step 2. Start observing the target node for configured mutations // observer.observe(targetNode, config); const observer = new MutationObserver(appendCustomNode); observer.observe(document.body, {subtree: true, childList: true}); El siguiente paso es definir esta función appendCustomNode .
Al planificar cómo agregar nodos a las tarjetas, es necesario tener en cuenta que verá el mismo nodo posiblemente varias veces, lo que requiere tener una estrategia para agregar el elemento personalizado solo una vez. Elegir un valor lo suficientemente aleatorio y luego etiquetar todos los nodos vistos anteriormente con ese valor ayudará a lograr esto. Aquí hay un ejemplo:
const customTag = `tag-${Date.now()}` // your choice of a valid & unique value function appendCustomNode(){ // find all timeline cards, their tag name is article const cards = document.getElementsByTagName('article'); // check each card for (let n = 0; n < cards.length; n++) { const card = cards[n]; // check that cards is new / has not been seen before if (!card.hasAttribute(customTag)) { addButton(card); // mark the card as "processed" by adding the custom tag card.setAttribute(customTag, true); } } }Por último, implemente la lógica para agregar el botón que desea agregar a la tarjeta. Aquí, el atributo de la tarjeta representa el nodo DOM de un elemento de la línea de tiempo.
function addButton(card){ const myButton = document.createElement('div'); myButton.innerText = 'hello world'; // select the div of action buttons // or wherever you want to insert your custom node // SEE NOTE BELOW const target = card.querySelector('....?....') // append/prepend/insertAdjacentHTML the button here target.append(myButton); }Dejaré abierta esta última parte por algunas razones: al decidir cómo encontrar la fila de botones en la tarjeta, si se usan clases como selector, la implementación se rompe si las clases cambian, lo cual está fuera de su control. Esto siempre es un desafío al extender aplicaciones web de terceros. Sugiero tratar de encontrar un selector más confiable (es por eso que antes usé el artículo de nombre de etiqueta para seleccionar tarjetas). En segundo lugar, la estructura de botones/tarjetas cambia periódicamente, por lo que ese es otro punto a considerar: dónde desea insertar este nodo personalizado. Por último, este enfoque no requiere jQuery.