Site icon Régis Enguehard

Javascript – Accéder au shadow root

Écran d'ordinateur avec du code informatique

Les shadow DOM sont conçus pour encapsuler les éléments et les styles d’un composant web, les rendant inaccessibles depuis l’extérieur pour plusieurs raisons importantes :

Mon objectif était de pouvoir modifier les styles d’une extension WordPress (un chatbot) nommée 3CX Free Live Chat, Calls & WhatsApp). Cette extension injecte un shadow DOM directement dans mon front. Il me fallait pouvoir injecter du styles supplémentaire afin de pouvoir en modifier l’apparence de l’extension.

Les premiers tests directement dans la console :

const shadowRoot = document.querySelector('call-us-selector').shadowRoot;

// Injecter des styles
const style = document.createElement('style');
style.textContent = `
  * {
    color: red;
  }
`;
shadowRoot.appendChild(style);

Ça fonctionne.

Reste à l’intégrer dans WordPress via un nouveau fichier JavaScript. Cela se passe dans le dossier du thème enfant dans le fichier functions.php :

function regJavaScript() {
    // Enregistre et ajoute le script
    wp_enqueue_script('regApp', get_stylesheet_directory_uri() . '/app.js', array(), '1.0.0', true);
}
add_action('wp_enqueue_scripts', 'regJavaScript');

On créer le fichier app.js dans le thème enfant. J’ai du ajouté une condition supplémentaire pour attendre que le DOM soit chargé…et également un timer pour attendre et vérifier que 3CX avait bien fini d’injecté son code.

// Ajoute les styles
function regModifie3CX() {
  const shadowRoot = document.querySelector('call-us-selector').shadowRoot.querySelector('call-us').shadowRoot;

  // Injecter des styles
  const style = document.createElement('style');
  style.textContent = `
    #wplc-chat-button {
      background-color: #f53603;
    }
    #wplc-chat-button svg rect {
      fill: #ffffff;
    }
    svg {
      fill: #f53603 !important;
    }
  `;
  shadowRoot.appendChild(style);
}


document.addEventListener('DOMContentLoaded', function() {
    const checkExist = setInterval(function() {
        const injectedElement = document.querySelector('call-us-selector'); // Remplacez par le sélecteur approprié
        if (injectedElement) {
            console.log('HTML injecté, exécution du script...');
            regModifie3CX();

            clearInterval(checkExist); // Arrête l'intervalle après l'exécution
        }
    }, 300); // Vérifie toutes les 300 ms
});
Quitter la version mobile