0

I am developing a Chrome plugin and I am facing a challenge where a function I call uses a variable to get element by class name. The variable returns undefined as the function gets called before the particular element is loaded in the DOM.

Please see the code below -

(() => {
    let wfLeftControls;
    let currentProject = "";
    let dynButtons;

    const newProjectLoaded = async () => {
        const notesBtnExists = document.getElementsByClassName("notes-button")[0];

        if (!notesBtnExists) {
            const notesBtnElement = document.createElement("div");
            const notesBtnSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
            const notesBtnPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');

            notesBtnElement.className = "button " + "top " + "notes-button ";
            /* active class highlights that the menu is active */

            notesBtnSvg.setAttribute('viewBox', '0 0 45 45');
            notesBtnSvg.setAttribute('fill', '#ffffff');
            notesBtnSvg.classList.add('bem-Svg');
            notesBtnSvg.setAttribute('style', 'display: block; position: relative;');

            notesBtnPath.setAttribute('d', 'M9 39h30V20.25L27.75 9H9v30Zm0 3q-1.25 0-2.125-.875T6 39V9q0-1.25.875-2.125T9 6h20l13 13v20q0 1.25-.875 2.125T39 42Zm4.95-8.55h20.1v-3h-20.1Zm0-7.95h20.1v-3h-20.1Zm0-7.95h13.8v-3h-13.8ZM9 39V9v30Z');
            notesBtnPath.setAttribute('fill', '#fffff');

            notesBtnSvg.appendChild(notesBtnPath);
            notesBtnElement.appendChild(notesBtnSvg);
            notesBtnElement.addEventListener("click", NotesPanelEventHandler);
            /* to open or close notes panel when user clicks icon */

            setTimeout(() => {

                wfLeftControls = document.getElementsByClassName("left-sidebar-links")[0];

                wfLeftControls.appendChild(notesBtnElement);

            }, 5000);
        }
    };

    chrome.runtime.onMessage.addListener((obj, sender, response) => {
        const { type, projectID } = obj;

        if (type === "NEW") {
            currentProject = projectID;
            newProjectLoaded();
        }
    });

    window.onload = newProjectLoaded();

})();

So here, newProjectLoaded() is the function being called.

Since the code is exectued before the element "left-sidebar-links" is loaded, the variable wfLeftControls returns undefined

So I have set a 5 second timeout to fix this problem.

Can someone please help me with how to call this function newProjectLoaded(); after all DOM elements are loaded or left-sidebar-links is loaded?

Thanks in advance

1 Answers1

0

If you need to wait till DOM is ready (all elements has been added to page) use event "DOMContentLoaded".

You have been used event "load" whitch is fired after "DOMContentLoaded".

The problem is - you didn't set newProjectLoaded as event listener, you called your function and call result was setted as listener:

// change this
window.onload = newProjectLoaded(); // function was called -> return undefined -> undefined set as event handler

// to this
window.onload = newProjectLoaded; // function set as event handler
Mero
  • 630
  • 4
  • 12
  • It is still not fixed! The page I am trying to manipulate has a pre-loader animation. So once the page loads, the pre-loader div is replaced with the body div that we are looking for. But unfortunately the code gets executed before the div we are looking for gets populated.. It would be great if you can solve this.. – Hari Kshore Feb 06 '23 at 05:34
  • @HariKshore could you share link to this page? – Mero Feb 07 '23 at 02:16