0

I am trying to detect the presence of an element on the page (#navDropDowns) in Javascript to determine if a user is logged in. The element is not present on load but is later added by Salesforce's own JS events. My script is also loaded into the page via Salesforce's JS routines.

I've been trying to use setInterval and keep checking the page. Surprisingly, it always fails (reporting 'logged out'. However, when I run it direct in the browser console, it reports 'logged in'.

(function wpSalesforce() {

    setInterval( function(){
        if ( document.getElementById('navDropDowns') !== null ) {
            console.log('logged in')
            document.body.className += ' ' + 'logged-in';
        } else {
            console.log('logged out')
        }
    }, 1000 );

})();

I've tried various versions of this including variable assignment but am getting nowhere. As it works in the browser console, it is as if setInterval is using an old version of the DOM.

I'm unable to use jQuery for this and it needs to be pure JS.

Space
  • 2,022
  • 1
  • 19
  • 29

1 Answers1

1

You can put a mutation observer on parent node of navDropDowns.

// Select the node that will be observed for mutations
const targetNode = document.getElementById('some-id');

// Options for the observer (which mutations to observe)
const config = { attributes: true, childList: true, subtree: true };

// Callback function to execute when mutations are observed
const callback = function(mutationsList, observer) {
    for(let mutation of mutationsList) {
        if (mutation.type === 'childList') {
            console.log('A child node has been added or removed.');
        }
        else if (mutation.type === 'attributes') {
            console.log('The ' + mutation.attributeName + ' attribute was modified.');
        }
    }
};

// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);

// Start observing the target node for configured mutations
observer.observe(targetNode, config);

// Later, you can stop observing
observer.disconnect();
easeccy
  • 4,248
  • 1
  • 21
  • 37
  • Thanks, this works in the console (as does setInterval) but not when included on the Salesforce page. SF seems to build the whole page in JS and the timing everything gets pulled in seemed to mess up any JS I try to use. – Space Aug 29 '19 at 10:22
  • I tried `const targetNode = document.body;` and an ID via `getElementById`. – Space Aug 30 '19 at 16:02
  • Have you tried to attach it to the body and change some elements by yourself to test if it gets triggered? I'm not sure but your problem might be this https://stackoverflow.com/questions/37110926/why-cant-observe-document-write-on-document-body-using-mutationobserver-api – easeccy Aug 31 '19 at 18:30
  • It seems like the element you attach observer on gets changed so you can't get the events anymore. I also recommend you to find some other ways to dedect users current state. – easeccy Aug 31 '19 at 18:33
  • 1
    Also try to attach observer to the `document`. That might work. – easeccy Aug 31 '19 at 18:38
  • Many thanks for your suggestions. They are spot on but I can't get it working in Salesforce, I think it is a fundamental problem with their platform. I'm sure one of the solutions you suggested will work if the Salesforce developer can change how the scripts are included on the page. My access is limited on this one. – Space Sep 02 '19 at 15:59