DOMContentLoaded not working in Safari App Extension

I am trying to run JavaScript only after the page has loaded, and according to here, I should use DOMContentLoaded. However, it does not seem to work.

This is my content.js file:
Code Block
function runOnStart() {
    document.addEventListener('DOMContentLoaded', function(e) {
        document.body.style.background = "rgb(20, 20, 20)";
        document.html.style.background = "rgb(20, 20, 20)";
      
        var divElements = document.body.getElementsByTagName('div');
        for(var i = 0; i < divElements.length; i++) {
            let elem = divElements[i];
            elem.style.background = "rgba(255, 255, 255, 0.05)";
        }
    });
}
runOnStart();


If I take the code outside of the event listener, it runs fine, but a lot of the elements haven't loaded in yet so it doesn't work as it should.

The function is definitely running, but the event listener simply doesn't work. I appreciate any help you can give!
  • Please make safari abosolute

Add a Comment

Accepted Reply

This sounds like a bug. Can you send us a bug report via Feedback Assistant?

Replies

This sounds like a bug. Can you send us a bug report via Feedback Assistant?
What version of Xcode and Safari are you using?

I can confirm that in Xcode 11.0 and Safari 13.0.1 that your content scripts "works" and I am not experiencing the the issue you describe. However, I have not tested in newer versions of Safari or Xcode.

What is document.html? Are you trying to target the html element?

You should probably use document.documentElement - that line of your code is throwing an error.
Hey everyone! I have figured out a work-around to the issue. It appears that a lot of the time, the DOMContentLoaded event would fire before the event listener got called.

This workaround worked for me:
Code Block
function runOnStart() {
// Run your code here
}
if(document.readyState !== 'loading') {
    runOnStart();
}
else {
    document.addEventListener('DOMContentLoaded', function () {
        runOnStart()
    });
}


It checks to see if DOMContentLoaded has already been fired (hence the document is no longer loading), and if so, run the code. If it has not been fired yet, then the listener is initialized.

@JakeShort your solution helped me! I couldn't figure out why my JS events were not triggering ONLY on iOS. Even on the iOS Simulator it was working, but only on my iPhone things were not working.

Thank you!!

I can confirm this still is an issue, and the docs are inaccurate: https://developer.apple.com/documentation/safariservices/safari_app_extensions/injecting_a_script_into_a_webpage