React chrome 扩展,滚动上的活动选项卡检测元素不起作用

问题描述 投票:0回答:1

滚动上的活动选项卡元素在 React chrome 扩展中不起作用。 下面是我的代码,用于检测滚动时活动选项卡的文档元素。但它没有按预期工作。

我希望在滚动发生时安慰“滚动到结束”(当滚动结束时......即使发生小滚动)。

滚动上的活动选项卡元素在 React chrome 扩展中不起作用。 下面是我的代码,用于检测滚动时活动选项卡的文档元素。但它没有按预期工作。 应用程序.tsx

import React, { useEffect } from 'react';
import './App.css';
import { useRecoilState } from 'recoil';
import messagesState from './states/messages';
function App() {
  const [htmlContent, setHtmlContent] = useRecoilState<any>(messagesState);


  useEffect(() => {
    const handleMessage = (event: any) => {
      if (event.data && event.data.type === 'scrollEnd') {
        console.log('Scrolled to end');
      }
    };
    window.addEventListener('message', handleMessage);
    return () => {
      window.removeEventListener('message', handleMessage);
    };
  }, []);
  return (
    <div className="App">
     
    </div>
  );
}

export default App;

背景.js

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === 'scrollEnd') {
    chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
      const activeTab = tabs[0];
      chrome.scripting.executeScript({
        target: { tabId: activeTab.id },
        func: () => {
          window.postMessage({ type: 'scrollEnd' }, '*');
        },
      });
    });
  }
});

contentScript.js

let scrollTimeout;
const targetDiv = document.querySelector('.c-scrollbar__hider');

function sendScrollEndMessage() {
  chrome.runtime.sendMessage({ type: 'scrollEnd' });
}

targetDiv.addEventListener('scroll', () => {
  clearTimeout(scrollTimeout);
  scrollTimeout = setTimeout(sendScrollEndMessage, 300);
});

manifest.json

{
  "manifest_version": 3,
  "name": "ASDF",
  "version": "1.0",
  "description": "ASDF",
  "host_permissions": ["<all_urls>"],
  "icons": {
    "16": "images/slack-logo.png",
    "32": "images/slack-logo.png",
    "180": "images/slack-logo.png",
    "192": "images/slack-logo.png",
    "512": "images/slack-logo.png"
  },
  "offline_enabled": true,
  "permissions": ["storage", "activeTab", "contextMenus", "tabs", "scripting"],
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["contentScript.js"]
    }
  ],
  "action": {
    "default_popup": "index.html"
  }
}

我希望在滚动发生时安慰“滚动到结束”(当滚动结束时......即使发生小滚动)。

javascript reactjs google-chrome-extension
1个回答
0
投票

window.postMessage 在这里不起作用,因为弹出窗口是一个不同的窗口,与选项卡无关。

  1. 请使用

    chrome
    消息传递

  2. 删除

    content_scripts
    并使用编程注入来代替仅在显示弹出窗口时使用的内容,因为此声明不必要地在每个选项卡中运行内容脚本,浪费 CPU 和内存。

  3. 从manifest.json和后台脚本中删除

    background
    ,你不需要它。

  4. 不需要在useEffect中取消注册监听器,因为当弹出窗口关闭时,整个JS环境都被破坏了。

useEffect(() => {
  const handleMessage = msg => {
    console.log(msg);
    // right-click inside the popup and select "inspect" in the menu to see the console
  };
  chrome.windows.getCurrent(async wnd => {
    const [tab] = await chrome.tabs.query({active: true, windowId: wnd.id});
    chrome.runtime.onConnect.addListener(port => {
      if (port.sender.tab?.id === tab.id) {
        port.onMessage.addListener(handleMessage);
      }
    });
    chrome.scripting.executeScript({
      target: {tabId: tab.id},
      files: ['contentScript.js'],
    });
  });
}, []);

// contentScript.js

if (window.ACTIVE !== 1) {
  window.ACTIVE = 1;
  let scrollTimeout;
  const port = chrome.runtime.connect({name: 'scroll'});
  const el = document.querySelector('.c-scrollbar__hider');
  el.addEventListener('scroll', onscroll);
  port.onDisconnect.addListener(shutdown);
  function shutdown() {
    el.removeEventListener('scroll', onscroll);
    delete window.ACTIVE;
  }
  function sendScrollEndMessage() {
    if (!chrome.runtime.id) return shutdown(); // extension was reloaded
    port.postMessage({ type: 'scrollEnd' });
  }
  function onscroll() {
    clearTimeout(scrollTimeout);
    scrollTimeout = setTimeout(sendScrollEndMessage, 300);
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.