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

Chrome扩展无法提取网页元素更新userCompletedQuestions数组问题

问题:Chrome扩展无法正确提取并更新已完成题目数组

我正在开发一款Google Chrome扩展,需要提取网页中类似<a href="/problems/non-overlapping-intervals/">435. Non-overlapping Intervals</a>的元素文本,存入userCompletedQuestions数组,用来和jobrequirementQn数组做匹配,但始终无法更新这个数组。想请教下,通过检查网页元素存储内容的方式有没有问题?

相关代码

document.addEventListener('DOMContentLoaded', function () {
    // Function to extract completed questions from the webpage
    const extractCompletedQuestions = () => {
        // Select all anchor elements that match the pattern
        const questionLinks = document.querySelectorAll('a[href*="/problems/"]');

        // Array to store the extracted question topics
        let questionTopics = [];

        // Iterate over each link and extract the text
        questionLinks.forEach(link => {
            const questionText = link.textContent.trim();
            questionTopics.push(questionText);
        });

        // Store the question topics in chrome storage
        chrome.storage.local.set({ 'userCompletedQuestions': questionTopics }, function () {
            console.log('Completed questions saved:', questionTopics);
        });
    };

    // Function to initialize the pie chart
    const createChart = (data) => {
        const ctx = document.getElementById('pieChart').getContext('2d');
        return new Chart(ctx, {
            type: 'pie',
            data: data,
            options: {}
        });
    };

    const updateChartData = (chart, data) => {
        chart.data.datasets[0].data = data;
        chart.update();
    };

    // Initialize data
    const data = {
        labels: ['Completed', 'Remaining'],
        datasets: [{
            data: [0, 100], // Initial data
            backgroundColor: [
                'green', // Completed
                'lightgray' // Remaining
            ]
        }]
    };

    // Initialize chart
    let pieChart = createChart(data);

    // Add event listener to radio buttons
    const radioButtons = document.querySelectorAll('input[type="radio"]');
    radioButtons.forEach(button => {
        button.addEventListener('change', function () {
            chrome.storage.local.get(['userCompletedQuestions', 'job1Questions', 'job2Questions'], function (result) {

                const userCompletedQuestions = result.userCompletedQuestions || [];
                let requiredQuestions = [];

                if (this.value === 'Job 1') {
                    requiredQuestions = result.job1Questions || [];
                } else if (this.value === 'Job 2') {
                    requiredQuestions = result.job2Questions || [];
                }

                const matchedQuestions = requiredQuestions.filter(question => userCompletedQuestions.includes(question));
                const completedPercentage = Math.round((matchedQuestions.length / requiredQuestions.length) * 100);
                const remainingPercentage = 100 - completedPercentage;

                updateChartData(pieChart, [completedPercentage, remainingPercentage]);
                console.log('Pie chart updated:', pieChart.data.datasets[0].data);
            });
        });
    });

    // Extract and store completed questions when the content script is loaded
    extractCompletedQuestions();

    // Example of extracting a specific question title if needed
    let questionText = document.querySelector('.question-title')?.innerText;
    if (questionText) {
        chrome.runtime.sendMessage({ action: 'storeQuestion', question: questionText }, function (response) {
            console.log('Question data sent to background:', response);
        });
    }
});

问题分析与解决办法

你的提取逻辑本身没问题,但大概率是DOM加载时机或选择器精度的问题导致数组没正确更新:

1. 动态内容未被捕获

如果页面是单页应用(比如LeetCode),题目列表是通过AJAX/框架动态渲染的,DOMContentLoaded触发时,目标元素还没生成,querySelectorAll拿不到任何元素,自然存不了数据。

解决办法:用MutationObserver监听DOM变化,当题目容器更新时重新提取:

const observeQuestionsContainer = () => {
  // 替换成你页面中已完成题目所在容器的选择器,比如LeetCode的题目列表容器
  const container = document.querySelector('.your-completed-questions-container');
  if (!container) return;

  const observer = new MutationObserver((mutations) => {
    mutations.forEach(mutation => {
      if (mutation.addedNodes.length > 0) {
        extractCompletedQuestions();
      }
    });
  });

  observer.observe(container, { childList: true, subtree: true });
};

// 初始化时启动监听
document.addEventListener('DOMContentLoaded', () => {
  extractCompletedQuestions();
  observeQuestionsContainer();
});

2. 选择器范围太广

a[href*="/problems/"]会匹配所有包含该路径的链接,包括推荐题目、侧边栏无关链接,导致存入错误数据,甚至覆盖正确的已完成题目数组。

解决办法:查看已完成题目的DOM特征(比如有特定class、图标),精准定位:

// 示例:仅选择带有"ac"类(已完成标记)的题目链接
const questionLinks = document.querySelectorAll('a[href*="/problems/"].ac');

3. 验证提取与存储结果

在extractCompletedQuestions里加日志,确认是否拿到了正确的元素:

const extractCompletedQuestions = () => {
  const questionLinks = document.querySelectorAll('a[href*="/problems/"]');
  console.log('找到的链接数量:', questionLinks.length); // 检查是否有元素被选中
  let questionTopics = [];
  questionLinks.forEach(link => {
    const text = link.textContent.trim();
    console.log('提取的题目文本:', text); // 检查文本是否正确
    questionTopics.push(text);
  });
  chrome.storage.local.set({ 'userCompletedQuestions': questionTopics }, () => {
    console.log('存储的数组:', questionTopics);
  });
};

另外,在读取存储时也可以加日志,确认数据是否正确读取:

chrome.storage.local.get('userCompletedQuestions', (result) => {
  console.log('读取到的已完成题目:', result.userCompletedQuestions);
});

内容的提问来源于stack exchange,提问作者lum wenkang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 09:14:52