【前端开发实战】从零开始开发Chrome浏览器扩展 - 快乐传播者项目完整教程

【前端开发实战】从零开始开发Chrome浏览器扩展 - 快乐传播者项目完整教程

📖 前言

大家好!今天我将带领大家从零开始开发一个Chrome浏览器扩展项目 - 快乐传播者。这个项目不仅实用有趣,还能让你掌握现代浏览器扩展开发的核心技术。

通过本教程,你将学会:

  • Chrome扩展的Manifest V3规范
  • 现代JavaScript ES6+语法
  • 响应式CSS设计
  • 本地存储和通知系统
  • 内容脚本和后台脚本的使用
    在这里插入图片描述

🎯 项目介绍

快乐传播者是一个致力于主动创造和传播快乐的浏览器扩展工具,具有以下特色功能:

  • 🎉 随机快乐消息推送
  • 📸 快乐时刻记录分享
  • 😄 幽默内容推荐
  • 🎮 快乐挑战游戏
  • 📊 快乐影响力统计
    在这里插入图片描述
    在这里插入图片描述

🛠️ 技术栈

  • Manifest V3 - 最新Chrome扩展标准
  • 原生JavaScript - ES6+语法
  • CSS3 - 现代样式设计
  • Chrome Extension API - 浏览器扩展接口

📁 项目结构

HappyOne/
├── manifest.json          # 扩展配置文件
├── popup.html             # 弹出窗口界面
├── popup.js               # 弹出窗口逻辑
├── popup.css              # 弹出窗口样式
├── content.js             # 内容脚本
├── content.css            # 内容脚本样式
├── background.js          # 后台脚本
├── icons/                 # 图标文件夹
│   ├── icon16.png
│   ├── icon48.png
│   └── icon128.png
└── README.md              # 项目说明

🚀 开始开发

第一步:创建项目基础结构

首先创建项目文件夹并初始化基础文件:

mkdir HappyOne
cd HappyOne

第二步:配置manifest.json

这是扩展的核心配置文件,定义了扩展的基本信息和权限:

{
  "manifest_version": 3,
  "name": "快乐传播者 - Happy Spreader",
  "version": "1.0.0",
  "description": "主动创造和传播快乐的浏览器扩展工具",
  "permissions": [
    "storage",
    "activeTab", 
    "notifications",
    "alarms"
  ],
  "host_permissions": [
    "https://*/*"
  ],
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"],
      "css": ["content.css"]
    }
  ],
  "action": {
    "default_popup": "popup.html",
    "default_title": "快乐传播者",
    "default_icon": {
      "16": "icons/icon16.png",
      "48": "icons/icon48.png", 
      "128": "icons/icon128.png"
    }
  },
  "icons": {
    "16": "icons/icon16.png",
    "48": "icons/icon48.png",
    "128": "icons/icon128.png"
  }
}

关键配置说明:

  • manifest_version: 3 - 使用最新的Manifest V3标准
  • permissions - 申请必要的权限
  • content_scripts - 注入到所有网页的脚本
  • background - 后台服务工作线程

第三步:创建弹出窗口界面

popup.html - 主界面结构:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>快乐传播者</title>
    <link rel="stylesheet" href="popup.css">
</head>
<body>
    <div class="container">
        <!-- 头部区域 -->
        <header class="header">
            <h1 class="title">🌟 快乐传播者</h1>
            <p class="subtitle">让世界充满快乐!</p>
        </header>

        <!-- 功能按钮区域 -->
        <div class="features">
            <button class="feature-btn" id="randomMessage">
                <span class="icon">🎉</span>
                <span class="text">随机快乐消息</span>
            </button>
            
            <button class="feature-btn" id="shareMoment">
                <span class="icon">📸</span>
                <span class="text">分享快乐时刻</span>
            </button>
            
            <button class="feature-btn" id="humorContent">
                <span class="icon">😄</span>
                <span class="text">幽默内容</span>
            </button>
            
            <button class="feature-btn" id="dailyChallenge">
                <span class="icon">🎮</span>
                <span class="text">每日挑战</span>
            </button>
            
            <button class="feature-btn" id="statistics">
                <span class="icon">📊</span>
                <span class="text">影响力统计</span>
            </button>
        </div>

        <!-- 结果显示区域 -->
        <div class="result-area" id="resultArea">
            <div class="result-content" id="resultContent"></div>
            <button class="copy-btn" id="copyBtn" style="display: none;">复制</button>
        </div>

        <!-- 底部信息 -->
        <footer class="footer">
            <p>今日已传播快乐 <span id="todayCount">0</span></p>
        </footer>
    </div>
    
    <script src="popup.js"></script>
</body>
</html>

第四步:设计现代化样式

popup.css - 响应式设计:

/* 基础样式重置 */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    min-height: 100vh;
    color: #333;
}

.container {
    width: 350px;
    min-height: 500px;
    background: rgba(255, 255, 255, 0.95);
    backdrop-filter: blur(10px);
    border-radius: 20px;
    box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
    overflow: hidden;
}

/* 头部样式 */
.header {
    background: linear-gradient(135deg, #ff6b6b, #ee5a24);
    color: white;
    padding: 20px;
    text-align: center;
}

.title {
    font-size: 24px;
    font-weight: bold;
    margin-bottom: 5px;
}

.subtitle {
    font-size: 14px;
    opacity: 0.9;
}

/* 功能按钮样式 */
.features {
    padding: 20px;
    display: grid;
    gap: 15px;
}

.feature-btn {
    display: flex;
    align-items: center;
    padding: 15px 20px;
    background: white;
    border: 2px solid #e0e0e0;
    border-radius: 15px;
    cursor: pointer;
    transition: all 0.3s ease;
    font-size: 16px;
    font-weight: 500;
}

.feature-btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
    border-color: #667eea;
}

.feature-btn .icon {
    font-size: 24px;
    margin-right: 15px;
}

/* 结果显示区域 */
.result-area {
    padding: 0 20px 20px;
    display: none;
}

.result-content {
    background: #f8f9fa;
    border-radius: 15px;
    padding: 20px;
    margin-bottom: 15px;
    font-size: 16px;
    line-height: 1.6;
    border-left: 4px solid #667eea;
}

.copy-btn {
    width: 100%;
    padding: 12px;
    background: linear-gradient(135deg, #667eea, #764ba2);
    color: white;
    border: none;
    border-radius: 10px;
    cursor: pointer;
    font-size: 16px;
    font-weight: 500;
    transition: all 0.3s ease;
}

.copy-btn:hover {
    transform: translateY(-1px);
    box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
}

/* 底部样式 */
.footer {
    background: #f8f9fa;
    padding: 15px 20px;
    text-align: center;
    border-top: 1px solid #e0e0e0;
    font-size: 14px;
    color: #666;
}

#todayCount {
    color: #667eea;
    font-weight: bold;
}

第五步:实现交互逻辑

popup.js - 核心功能实现:

// 快乐消息数据库
const happyMessages = [
    "🌟 今天又是充满希望的一天!",
    "😊 微笑是最好的语言,快乐是最好的礼物",
    "🌈 生活就像彩虹,需要经历风雨才能看到美丽",
    "💪 每一个挑战都是成长的机会",
    "🎉 快乐是会传染的,让我们一起传播正能量",
    "🌞 阳光总在风雨后,快乐总在坚持中",
    "✨ 你的笑容是世界上最美的风景",
    "🎊 今天也要开开心心的哦!",
    "💖 爱自己,爱生活,爱这个世界",
    "🚀 梦想在前方,快乐在路上",
    "🎵 生活就像一首歌,用心去感受它的美好",
    "🌺 花开不是为了花落,而是为了绽放",
    "🌟 你比想象中更强大,更美好",
    "🎭 人生如戏,但你是主角",
    "💎 你本身就是一颗闪耀的钻石"
];

// 幽默内容数据库
const humorContent = [
    "程序员笑话:为什么程序员总是分不清万圣节和圣诞节?因为 Oct 31 == Dec 25",
    "程序员日常:写代码时觉得自己是天才,调试时觉得自己是智障",
    "最浪漫的事:和代码一起变老,直到它不再报错",
    "程序员的爱情:if(you.love(me)) { return true; }",
    "调试的真相:99%的bug都是因为少了一个分号"
];

// 每日挑战任务
const dailyChallenges = [
    "今天对3个人说一句赞美的话",
    "帮助一个需要帮助的人",
    "分享一个有趣的笑话给朋友",
    "记录今天最开心的一件事",
    "给家人一个温暖的拥抱"
];

// DOM元素
const resultArea = document.getElementById('resultArea');
const resultContent = document.getElementById('resultContent');
const copyBtn = document.getElementById('copyBtn');
const todayCount = document.getElementById('todayCount');

// 初始化
document.addEventListener('DOMContentLoaded', function() {
    loadTodayCount();
    setupEventListeners();
});

// 设置事件监听器
function setupEventListeners() {
    document.getElementById('randomMessage').addEventListener('click', showRandomMessage);
    document.getElementById('shareMoment').addEventListener('click', shareMoment);
    document.getElementById('humorContent').addEventListener('click', showHumorContent);
    document.getElementById('dailyChallenge').addEventListener('click', showDailyChallenge);
    document.getElementById('statistics').addEventListener('click', showStatistics);
    copyBtn.addEventListener('click', copyToClipboard);
}

// 显示随机快乐消息
function showRandomMessage() {
    const message = happyMessages[Math.floor(Math.random() * happyMessages.length)];
    displayResult(message, '🎉 快乐消息');
    updateTodayCount();
}

// 分享快乐时刻
function shareMoment() {
    const moment = prompt('请记录你的快乐时刻:');
    if (moment && moment.trim()) {
        const formattedMoment = `📸 快乐时刻:${moment}\n\n记录时间:${new Date().toLocaleString()}`;
        displayResult(formattedMoment, '📸 快乐时刻');
        saveMoment(moment);
        updateTodayCount();
    }
}

// 显示幽默内容
function showHumorContent() {
    const humor = humorContent[Math.floor(Math.random() * humorContent.length)];
    displayResult(humor, '😄 幽默内容');
    updateTodayCount();
}

// 显示每日挑战
function showDailyChallenge() {
    const challenge = dailyChallenges[Math.floor(Math.random() * dailyChallenges.length)];
    const challengeText = `🎮 今日挑战:${challenge}\n\n完成这个挑战,让世界更美好!`;
    displayResult(challengeText, '🎮 每日挑战');
    updateTodayCount();
}

// 显示统计信息
function showStatistics() {
    chrome.storage.local.get(['totalCount', 'moments'], function(result) {
        const totalCount = result.totalCount || 0;
        const moments = result.moments || [];
        
        const stats = `📊 快乐影响力统计\n\n` +
                     `总传播次数:${totalCount}\n` +
                     `快乐时刻记录:${moments.length} 条\n` +
                     `今日传播:${getTodayCount()} 次\n\n` +
                     `继续加油,让世界更美好!`;
        
        displayResult(stats, '📊 统计信息');
    });
}

// 显示结果
function displayResult(content, title) {
    resultContent.innerHTML = `<strong>${title}</strong><br><br>${content}`;
    resultArea.style.display = 'block';
    copyBtn.style.display = 'block';
}

// 复制到剪贴板
function copyToClipboard() {
    const text = resultContent.textContent;
    navigator.clipboard.writeText(text).then(function() {
        copyBtn.textContent = '已复制!';
        setTimeout(() => {
            copyBtn.textContent = '复制';
        }, 2000);
    });
}

// 保存快乐时刻
function saveMoment(moment) {
    chrome.storage.local.get(['moments'], function(result) {
        const moments = result.moments || [];
        moments.push({
            content: moment,
            timestamp: new Date().toISOString()
        });
        chrome.storage.local.set({ moments: moments });
    });
}

// 更新今日计数
function updateTodayCount() {
    const today = new Date().toDateString();
    chrome.storage.local.get(['todayCount', 'lastDate'], function(result) {
        let todayCount = result.todayCount || 0;
        const lastDate = result.lastDate;
        
        if (lastDate !== today) {
            todayCount = 1;
        } else {
            todayCount++;
        }
        
        chrome.storage.local.set({
            todayCount: todayCount,
            lastDate: today
        });
        
        document.getElementById('todayCount').textContent = todayCount;
    });
    
    // 更新总计数
    chrome.storage.local.get(['totalCount'], function(result) {
        const totalCount = (result.totalCount || 0) + 1;
        chrome.storage.local.set({ totalCount: totalCount });
    });
}

// 加载今日计数
function loadTodayCount() {
    chrome.storage.local.get(['todayCount', 'lastDate'], function(result) {
        const today = new Date().toDateString();
        if (result.lastDate === today) {
            document.getElementById('todayCount').textContent = result.todayCount || 0;
        } else {
            document.getElementById('todayCount').textContent = '0';
        }
    });
}

// 获取今日计数
function getTodayCount() {
    return document.getElementById('todayCount').textContent;
}

第六步:创建内容脚本

content.js - 在网页中注入快乐元素:

// 创建浮动快乐按钮
function createFloatingButton() {
    const button = document.createElement('div');
    button.id = 'happy-floating-btn';
    button.innerHTML = '😊';
    button.style.cssText = `
        position: fixed;
        bottom: 20px;
        right: 20px;
        width: 60px;
        height: 60px;
        background: linear-gradient(135deg, #ff6b6b, #ee5a24);
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 24px;
        cursor: pointer;
        z-index: 10000;
        box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
        transition: all 0.3s ease;
        user-select: none;
    `;
    
    button.addEventListener('mouseenter', function() {
        this.style.transform = 'scale(1.1)';
        this.style.boxShadow = '0 6px 20px rgba(0, 0, 0, 0.3)';
    });
    
    button.addEventListener('mouseleave', function() {
        this.style.transform = 'scale(1)';
        this.style.boxShadow = '0 4px 15px rgba(0, 0, 0, 0.2)';
    });
    
    button.addEventListener('click', showRandomHappyElement);
    
    document.body.appendChild(button);
}

// 显示随机快乐元素
function showRandomHappyElement() {
    const happyEmojis = ['😊', '🌟', '🎉', '💖', '🌈', '✨', '🎊', '💪', '🌞', '🎵'];
    const emoji = happyEmojis[Math.floor(Math.random() * happyEmojis.length)];
    
    const element = document.createElement('div');
    element.innerHTML = emoji;
    element.style.cssText = `
        position: fixed;
        left: ${Math.random() * (window.innerWidth - 100)}px;
        top: ${Math.random() * (window.innerHeight - 100)}px;
        font-size: 40px;
        z-index: 9999;
        pointer-events: none;
        animation: floatUp 2s ease-out forwards;
    `;
    
    document.body.appendChild(element);
    
    setTimeout(() => {
        document.body.removeChild(element);
    }, 2000);
}

// 添加CSS动画
const style = document.createElement('style');
style.textContent = `
    @keyframes floatUp {
        0% {
            opacity: 1;
            transform: translateY(0) scale(1);
        }
        100% {
            opacity: 0;
            transform: translateY(-100px) scale(1.5);
        }
    }
`;
document.head.appendChild(style);

// 页面加载完成后创建浮动按钮
if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', createFloatingButton);
} else {
    createFloatingButton();
}

// 监听来自popup的消息
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if (request.action === 'showHappyMessage') {
        showRandomHappyElement();
        sendResponse({success: true});
    }
});

第七步:创建后台脚本

background.js - 后台服务工作线程:

// 安装时的初始化
chrome.runtime.onInstalled.addListener(function() {
    console.log('快乐传播者扩展已安装!');
    
    // 设置默认数据
    chrome.storage.local.set({
        totalCount: 0,
        todayCount: 0,
        moments: [],
        lastDate: new Date().toDateString()
    });
    
    // 创建定时提醒
    createReminderAlarm();
});

// 创建定时提醒
function createReminderAlarm() {
    chrome.alarms.create('happyReminder', {
        delayInMinutes: 60, // 每小时提醒一次
        periodInMinutes: 60
    });
}

// 监听定时器
chrome.alarms.onAlarm.addListener(function(alarm) {
    if (alarm.name === 'happyReminder') {
        showHappyNotification();
    }
});

// 显示快乐提醒通知
function showHappyNotification() {
    const messages = [
        "🌟 时间到啦!该传播一些快乐了!",
        "😊 休息一下,给自己一个微笑吧!",
        "🎉 快乐时刻到了,分享你的好心情!",
        "💖 记得关心身边的人,传递温暖!",
        "🌈 生活很美好,保持积极心态!"
    ];
    
    const randomMessage = messages[Math.floor(Math.random() * messages.length)];
    
    chrome.notifications.create({
        type: 'basic',
        iconUrl: 'icons/icon128.png',
        title: '快乐传播者',
        message: randomMessage
    });
}

// 监听扩展图标点击
chrome.action.onClicked.addListener(function(tab) {
    // 如果popup没有打开,发送消息到content script
    chrome.tabs.sendMessage(tab.id, {
        action: 'showHappyMessage'
    });
});

// 监听来自content script的消息
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if (request.action === 'updateCount') {
        updateStatistics(request.count);
        sendResponse({success: true});
    }
});

// 更新统计数据
function updateStatistics(count) {
    chrome.storage.local.get(['totalCount'], function(result) {
        const totalCount = (result.totalCount || 0) + count;
        chrome.storage.local.set({ totalCount: totalCount });
    });
}

第八步:创建图标文件

你需要准备三个尺寸的图标文件:

  • icons/icon16.png (16x16像素)
  • icons/icon48.png (48x48像素)
  • icons/icon128.png (128x128像素)

可以使用在线工具如Canva或Figma创建,或者使用现成的图标。

🚀 安装和测试

在Chrome中安装扩展

  1. 打开Chrome浏览器
  2. 访问 chrome://extensions/
  3. 开启右上角的"开发者模式"
  4. 点击"加载已解压的扩展程序"
  5. 选择你的项目文件夹
  6. 扩展安装完成!

测试功能

  1. 点击工具栏中的扩展图标
  2. 测试各个功能按钮
  3. 在任意网页上查看右下角的浮动按钮
  4. 检查通知功能是否正常工作

🎨 自定义和扩展

添加新功能

你可以轻松添加新功能,比如:

  • 天气提醒
  • 每日名言
  • 健康提醒
  • 学习计划

样式定制

修改CSS文件来自定义界面:

  • 更改颜色主题
  • 调整布局
  • 添加动画效果
  • 优化响应式设计

数据管理

扩展使用Chrome Storage API存储数据:

  • 本地存储:chrome.storage.local
  • 同步存储:chrome.storage.sync
  • 会话存储:chrome.storage.session

📱 发布到Chrome Web Store

完成开发后,你可以:

  1. 打包扩展文件
  2. 创建开发者账号
  3. 提交到Chrome Web Store
  4. 等待审核通过

🎯 项目亮点

  1. 现代化设计 - 使用渐变色彩和圆角设计
  2. 响应式布局 - 适配不同屏幕尺寸
  3. 丰富交互 - 动画效果和悬停反馈
  4. 数据持久化 - 本地存储用户数据
  5. 定时提醒 - 智能的快乐提醒机制
  6. 页面注入 - 在网页中注入快乐元素

💡 学习收获

通过这个项目,你学会了:

  • Manifest V3 的新特性和配置
  • Chrome Extension API 的使用方法
  • 现代JavaScript 的异步编程
  • CSS3 的动画和响应式设计
  • 本地存储 的数据管理
  • 内容脚本 的页面注入技术

🌟 总结

这个项目不仅实用有趣,更重要的是让你掌握了现代浏览器扩展开发的核心技术。通过实际项目练习,你将更好地理解前端开发的各个方面。

记住,编程不仅是技术,更是创造快乐的过程。希望这个项目能给你带来快乐,也能让你成为快乐的传播者!


项目源码GitHub仓库

如果觉得有帮助,请点赞收藏支持! 👍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值