如何在关闭侧面板之前运行代码?

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

我正在使用react、vite、typescript 构建一个浏览器扩展。该扩展程序具有侧面板和全屏选项卡。 仅在全屏选项卡上,我需要创建一个仅在侧面板关闭时才出现的按钮/图标。因此,当我打开侧面板时,它会隐藏该按钮,当我关闭侧面板时,它会显示该按钮。我找到了一种使用此代码检查侧面板是否关闭或打开的方法。

const contexts: chrome.runtime.ExtensionContext[] = await chrome.runtime.getContexts({ contextTypes: ["SIDE_PANEL"] });

如果

contexts.length > 0
表示侧面板打开,否则表示侧面板关闭。我在
useEffect
钩子中添加了这个逻辑,并且效果很好。问题是我需要在每次侧面板打开或关闭时再次运行此代码,以便它可以检查侧面板状态并在需要时显示/隐藏它。我尝试使用焦点和模糊事件,但不幸的是它在 Chrome 浏览器中不起作用,尽管它在 Edge 中起作用。我想到了一个想法,我可以使用
chrome.runtime.sendMessage
来触发代码并再次运行函数。在我的主要组件
index.tsx
中的
useEffect
中,我可以发送消息,它将触发代码并隐藏按钮。但是,当侧面板关闭时,我需要发送相同的消息。我尝试在
useEffect
返回函数中执行此操作,但它对我不起作用。 侧面板关闭时有什么方法可以
sendMessage
吗?或者也许有更好的选择来实现显示和隐藏图标的逻辑? 按钮组件的完整代码如下

import { useEffect, useState } from "react";
import { logosHooks } from "@/hooks/logos-hooks";
import { cn } from "@/lib/utils";

const SidePanelTrigger = () => {
  const logo = logosHooks.useLogoIcon();
  const [show, setShow] = useState(false);

  useEffect(() => {
    const checkPanelState = async() => {
      const contexts: chrome.runtime.ExtensionContext[] = await chrome.runtime.getContexts({ contextTypes: ["SIDE_PANEL"] });
      setShow(contexts.length !== 0);
    }

    checkPanelState();
  }, []);

  const handleOpenSidepanel = () => {
    chrome.runtime.sendMessage({ action: "openSidePanel" });
  }
  
  return (
    <button 
      className={cn(
        "flex fixed top-[200px] z-10 -right-[10px] bg-primary rounded-l-sm justify-center items-center transition-all duration-300 hover:right-0 p-3 shadow-lg cursor-pointer",
        show && "hidden"
      )}
      onClick={handleOpenSidepanel}
    >
      Button
    </button>
  );
};

export default SidePanelTrigger;
javascript reactjs google-chrome-extension browser
1个回答
0
投票

我稍微改变了代码并设法解决了这个问题。

对我有用的解决方案是使用

ResizeObserver
。每次侧面板打开或关闭时,它都会更改活动选项卡的宽度。我附加了
checkPanelState
函数,该函数使用
ResizeObserver
检查侧面板是否关闭或打开以调整大小事件。我还添加了去抖动来优化代码。 该组件的完整代码如下

import { useEffect, useState } from "react";
import { logosHooks } from "@/hooks/logos-hooks";
import { cn, debounce } from "@/lib/utils";

const SidePanelTrigger = () => {
  const logo = logosHooks.useLogoIcon();
  const [show, setShow] = useState(false);

  useEffect(() => {
    const checkPanelState = async() => {
      // @ts-ignore
      const contexts: chrome.runtime.ExtensionContext[] = await chrome.runtime.getContexts({ contextTypes: ["SIDE_PANEL"] });
      setShow(contexts.length === 0);
    }

    const debouncedCheck = debounce(checkPanelState, 50);
    const resizeObserver = new ResizeObserver(debouncedCheck);

    resizeObserver.observe(document.body);

    return () => resizeObserver.disconnect();
  }, []);

  const handleOpenSidepanel = () => {
    setShow(false)
    chrome.runtime.sendMessage({ action: "openSidePanel" });
  }
  
  return (
    <button 
      className={cn(
        "hidden fixed top-[200px] z-10 -right-[10px] bg-primary rounded-l-sm justify-center items-center transition-all duration-300 hover:right-0 p-3 shadow-lg cursor-pointer",
        show && "flex"
      )}
      onClick={handleOpenSidepanel}
    >
      Button
    </button>
  );
};

export default SidePanelTrigger;
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.