1

I want to monitor a dynamically changing value on a web page with a Chrome extension (only for my own use) and play a notification sound and display an alert when that value changes. This page is not necessarily in the active tab.

I have the following code so far, the only thing I need to do is to trigger the background.js when the value changes. My question is how to do that.

manifest.json

{
    "manifest_version": 2,
    "name": "Example Website Notifications",
    "description": "Displays notifications on Example Website.",
    "version": "1.0",

    "background": {
        "scripts": ["background.js"],
        "persistent": false
    },

    "content_scripts": [{
        "matches": ["https://www.example.com/*"],
        "js": ["jquery.js", "content.js"]
    }]
}

content.js

var value = $('#element').html();

window.setInterval(function() {
    var newValue = $('#element').html();
    if (newValue != value) {
        /* Run code in background.js */
        value = newValue;
    }
}, 5000);

I am checking the value in intervals of 5s. If there is a way to "know" when the value change happens, instead of checking every 5s, I am also open to that.

background.js

var sound = new Audio('sound.mp3').play();
alert('Value Changed');

The reason I have alert() in addition to the sound notification is so that the browser window icon will blink in the task bar, in case I miss hearing the sound alert.

When I tested background.js to see if the audio plays, the alert is displayed first, then the audio is played after clicking OK on the alert, even though the line to play the audio file comes before. Any ideas why that happens?

yenren
  • 450
  • 9
  • 20
  • 2
    [Audio](https://developer.mozilla.org/en-US/docs/Web/API/HTMLAudioElement) is *asynchronous*. – Namaskar Sep 20 '17 at 12:18
  • @SvenTheSurfer Does that mean that I can't play an audio file before the text alert is displayed? That I will need to choose either one and can't use both at the same time? – yenren Sep 20 '17 at 12:26
  • 1
    Please don't radically change your questions (this invalidates current answers!) - if you have a follow-up question, just ask a new one with a link to this one. – Xan Sep 20 '17 at 13:12

1 Answers1

2

To communicate an event to a background page, you can use Messaging.

Example (slightly overengineered to be extensible):

// content.js
chrome.runtime.sendMessage({type: "alertUser"});

// background.js
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
  switch(message.type) {
    case "alertUser":
      /* play sound, draw attention */
      break;
  }
});

Note, you don't have to use the horrifying alert for the purpose of drawing attention. There's windows API for that:

// Assuming you have `sender` from the messaging API

// This will make the window blink/draw attention in the taskbar or equivalent
chrome.windows.update(sender.tab.windowId, {drawAttention: true});
// Optionally, switch to the tab inside the window as well
chrome.tabs.update(sender.tab.id, {active: true});

alert should be considered harmful: it suspends JS execution until dismissed, which explains the effect (delayed playback) that you experience. It should be avoided.

Another "organic" method of visually notifying a user would be to use toast-style notifications with notification API. It's far less ambiguous than the browser icon flashing.

If there is a way to "know" when the value change happens, instead of checking every 5s, I am also open to that.

Yes; primarily, with a tool called Mutation Observers. See this canonical question on the topic.

Xan
  • 74,770
  • 16
  • 179
  • 206
  • Thank you for the example codes and suggestions. I had also checked Messaging documentation page (and many other pages/tutorials) before coming here, but still can't attach the dots. – yenren Sep 20 '17 at 13:02
  • @Envayo Any particular problem with grasping it? – Xan Sep 20 '17 at 13:04
  • I thought of editing my question to show my updated code based on your code samples. I don't know how to explain without showing my updated code, but in simple words, my updated code still doesn't do what I want it to do. I guess it will be better to ask on a forum, where I can post my updated code for further questions. Thanks for your help. – yenren Sep 20 '17 at 13:17
  • I'd love to help; but once you apply my changes, you have a different question. You should not be afraid of making a new one! – Xan Sep 20 '17 at 13:18
  • Thanks for the note about the Mutation Observers, I will check that and the related question. – yenren Sep 20 '17 at 14:01