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

Chrome扩展:如何处理ShopWare POS技师名称样式重置及事件监听?

问题背景

我正在为汽修POS系统ShopWare开发Chrome扩展,将工单页面转换为车间大屏调度看板,核心需求:

  • 移除页面冗余元素
  • 放大技师名称
  • 新工单添加闪烁动画,直至技师确认

遇到的问题:

  1. 注入的CSS中,闪烁动画(.in-transition)生效,但h4.section-title和i.muted的字体大小设置无效,只能通过JS代码修改样式
  2. 当工单分配给技师时,页面触发软重载(动态更新DOM而非刷新页面),已通过JS修改的样式会被重置;尝试绑定change、DOMContentLoaded事件均无法捕获样式重置的触发时机

附当前核心代码:

样式修改JS代码(enlarge-text.js)

const addStyleProp = () => {
  const className = "section-title";
  const styleObj = { "font-size": "40px" };
  elms = document.getElementsByClassName(className);

  for (let elm in elms) {
    let curr = elms[elm];

    if (typeof curr === "object") {
      try {
        Object.assign(curr.style, styleObj);
      } catch (error) {
        console.log(
          "Error attempting to change styling on the current node.",
          elm
        );
      }
    }
  }
};

addStyleProp();

扩展注入配置(background.js)

const scriptFiles = ["scripts/removeElements.js", "./scripts/enlarge-text.js"];

const cssFiles = ["./css/blink.css"];

chrome.runtime.onInstalled.addListener(() => {
  chrome.action.setBadgeText({
    text: "",
  });
});

const swRegex = new RegExp(".shop-ware.com");

chrome.action.onClicked.addListener(async (tab) => {
  //Check to see if we're on shopware. If not, bail. 
  if (!(tab.url.search(swRegex) > 0)) {
    return;
  }

  const state = await chrome.action.getBadgeText({ tabId: tab.id });
  //Already on. Notihng to do here!
  if (state === "ON") {
    return;
  }

  //set action badge to state
  await chrome.action.setBadgeText({
    tabId: tab.id,
    text: "ON",
  });

  await chrome.scripting.executeScript({
    files: scriptFiles,
    target: { tabId: tab.id },
  });

  /**Blink the  in-transition class and enlarge text*/
  await chrome.scripting.insertCSS({
    files: cssFiles,
    target: { tabId: tab.id },
  });
});
.in-transition{
    animation: blink-animation 1s steps(5, start) none infinite;
}

@keyframes blink-animation {
    to{
        visibility: hidden;
    }
}

h4.section-title {
    font-size: 40px;
}

i.muted {
    font-size: 40px;
}

解决方案

A. 让注入的CSS字体大小设置生效

问题根源是原页面CSS的选择器优先级高于我们注入的样式,解决方式:

  1. 提升选择器优先级:使用更具体的选择器,或添加!important强制覆盖
    修改blink.css中的字体样式规则:
/* 方式1:增加父元素选择器提升优先级,建议优先使用 */
body .work-order-section h4.section-title {
    font-size: 40px;
}

/* 方式2:使用!important(优先级最高,仅在方式1无效时使用) */
h4.section-title {
    font-size: 40px !important;
}

i.muted {
    font-size: 40px !important;
}

可通过Chrome开发者工具查看原页面的样式选择器,复制其结构并追加规则,确保优先级更高;避免滥用!important,防止后续样式维护困难。

  1. 确认CSS注入顺序:扩展中insertCSS在executeScript之后执行,确保注入的CSS在页面原有样式之后加载,覆盖效果更稳定。

B. 捕获样式重置的触发事件(应对软重载)

软重载本质是页面通过JS动态更新DOM,无法通过常规事件捕获,需使用MutationObserver监听DOM变化:

修改enlarge-text.js,替换单次执行的逻辑为持续监听:

const addStyleProp = () => {
  const className = "section-title";
  const styleObj = { "font-size": "40px" };
  // 使用for...of遍历HTMLCollection,避免遍历非元素属性
  for (const elm of document.getElementsByClassName(className)) {
    if (elm instanceof HTMLElement) {
      Object.assign(elm.style, styleObj);
    }
  }
};

// 初始化应用样式
addStyleProp();

// 创建DOM变化观察者
const observer = new MutationObserver((mutations) => {
  mutations.forEach(mutation => {
    // 检测到有新节点添加时,重新应用样式
    if (mutation.addedNodes.length > 0) {
      addStyleProp();
    }
  });
});

// 监听整个body的子节点变化(包含所有层级)
observer.observe(document.body, {
  childList: true,
  subtree: true
});

优化建议:

  • 若知道工单列表的具体容器(如类名为.work-order-container),可将监听目标改为该容器,减少不必要的性能消耗:
const targetContainer = document.querySelector('.work-order-container');
if (targetContainer) {
  observer.observe(targetContainer, {
    childList: true,
    subtree: true
  });
}

内容的提问来源于stack exchange,提问作者BJ Rutledge

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 09:15:22