You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome扩展中能否监听主JS变量?偏好使用Proxy实现

How to Listen to Page Global Variables in Chrome Extensions with Proxy (No Polling)

Hey there! The core issue you're hitting is Chrome's isolated worlds feature: content scripts run in their own separate context, so they can't directly access or modify the page's global variables (like your hp). That's why your setInterval loop feels like a hack—but we can fix this cleanly with Proxy, no polling required.

Here's a step-by-step solution that lets you listen to variable changes in real time:

1. Understand the Workflow

We need two parts to make this work:

  • A script injected into the page's main context (not the content script's isolated world) to set up the Proxy and watch the variable.
  • Communication between this injected script and your content script using custom browser events, since they can't share scope directly.

2. Implement the Proxy & Event Communication

Step 1: Inject the Proxy Script into the Page

First, we'll inject a script into the page's main world to wrap your hp variable in a Proxy. This Proxy will intercept any changes to the variable and fire a custom event that your content script can listen to.

Add this to your content script:

// Content Script: Inject the Proxy setup into the page's main context
function injectProxyScript() {
  const script = document.createElement('script');
  script.textContent = `
    (function() {
      // Wait for the global 'hp' variable to exist (in case it loads later)
      function setupHPProxy() {
        if (typeof window.hp === 'undefined') {
          setTimeout(setupHPProxy, 100);
          return;
        }

        // Proxy can only handle objects—wrap primitive values (numbers/strings) in an object
        const hpTarget = typeof window.hp === 'object' 
          ? window.hp 
          : { value: window.hp };

        // Replace the global 'hp' with our Proxy
        window.hp = new Proxy(hpTarget, {
          set: function(target, prop, newValue) {
            const oldValue = target[prop];
            // Update the actual value
            target[prop] = newValue;
            // Only fire an event if the value actually changed
            if (oldValue !== newValue) {
              window.dispatchEvent(new CustomEvent('hpUpdated', {
                detail: {
                  newValue: typeof hpTarget.value !== 'undefined' ? hpTarget.value : newValue,
                  property: prop
                }
              }));
            }
            return true;
          },
          // Optional: Intercept 'get' calls if you need to track reads
          get: function(target, prop) {
            return target[prop];
          }
        });

        // Send the initial value to the content script
        window.dispatchEvent(new CustomEvent('hpUpdated', {
          detail: {
            newValue: typeof hpTarget.value !== 'undefined' ? hpTarget.value : window.hp
          }
        }));
      }

      setupHPProxy();
    })();
  `;
  document.documentElement.appendChild(script);
  script.remove(); // Clean up the injected script tag
}

// Run the injection when the content script loads
injectProxyScript();

Step 2: Listen for Changes in the Content Script

Now, in your content script, add a listener for the custom hpUpdated event to get real-time updates:

// Content Script: Listen for updates from the page's Proxy
window.addEventListener('hpUpdated', (event) => {
  const { newValue } = event.detail;
  // Do whatever you need with the updated HP value
  console.log('HP just changed to:', newValue);
  // Your logic here (e.g., update UI, send to background script)
});

3. Key Notes

  • Primitive vs. Object Variables: Proxy can only wrap objects, so we automatically wrap primitive values (like numbers) in a { value: ... } object. The event will still pass the raw value to your content script, so you don't have to handle the wrapper there.
  • Timing: The script waits for window.hp to exist before setting up the Proxy, which handles cases where the variable is initialized after the page loads.
  • No Polling: This setup triggers updates only when the variable actually changes—no more setInterval loops wasting resources.

Why This Works

  • The injected script runs in the page's main context, so it has full access to global variables.
  • The Proxy intercepts all writes to hp and fires a custom event.
  • Your content script listens for this event, which crosses the isolated world boundary safely.

内容的提问来源于stack exchange,提问作者Tree Nguyen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 18:52:34