【谷歌浏览器插件开发教程】三(完结篇)、自定义新打开标签页:自定义搜索引擎;添加日期与时间;调取高德天气接口、名言接口等

已完结,页面内容展示

  • 白天模式
  • 黑夜模式
  • 基础设置

系列

前言

  • 上一章节中,我们完善了新标签页壁纸,设置了字体颜色,壁纸下载按钮等。

本章节内容

  • 自定义搜索引擎,支持GoogleBingBaidu
  • 添加日期与时间
  • 调取高德天气接口、名言接口等
  • 完善popup.html设置,黑暗模式,新开页面按钮

目录介绍

  • 本期因为新增了popup.html,所以创建部分目录。
plaintext 复制代码
my-new-tab/
├── images/             # 存放静态资源,如图片、字体等
│   ├── download.svg
│   ├── icon16.png
│   ├── icon48.png
│   ├── icon128.png
├── css/               # 页面样式
│   ├── clock.css      # 时间样式
│   ├── newtab.css     # 标签页样式
│   ├── popup.css      # 弹出页样式
├── js/                # 页面脚本
│   ├── clock.js       # 时间脚本
│   ├── newtab.js      # 标签页脚本
│   ├── popup.js       # 弹出页脚本
├── background.js  # 后台管理脚本(移动到 js 目录)
├── manifest.json      # Chrome 扩展基础配置文件
├── newtab.html        # 新标签页内容
└── popup.html         # 弹出页内容

自定义搜索引擎

  • 来继续我们在第一小节中挖的坑,完善搜索框

newtab.html 添加内容

html 复制代码
    <div id="search-container">
      <select id="search-engine">
        <option value="https://www.google.com/search?q=">Google</option>
        <option value="https://www.bing.com/search?q=">Bing</option>
        <option value="https://www.baidu.com/s?wd=">百度</option>
      </select>
      <input type="text" id="search-box" placeholder="输入关键字搜索">
      <button id="search-btn">搜索</button>
    </div>
  • 添加了搜索引擎选择,搜索内容框与按钮。

newtab.css 添加内容

css 复制代码
#search-container {
  margin: 80px 0 0 0;
  top: 150px;
  display: flex;
  gap: 0;

  background: rgba(255, 255, 255, 0.7);
  border-radius: 5px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  overflow: hidden;
  width: 650px;
}

#search-engine {
  height: 45px;
  padding: 0 20px;
  border: none;
  background: transparent;
  font-size: 14px;
  color: rgba(0, 0, 0, 0.9);
  cursor: pointer;
}

#search-box {
  flex: 1;
  height: 45px;
  padding: 0 15px;
  border: none;
  background: transparent;
  font-size: 14px;
  
  color: rgba(0, 0, 0, 0.9);
}

#search-box:focus {
  outline: none;
  box-shadow: none;
}

#search-btn {
  width: 100px;
  height: 45px;
  padding: 0 25px;
  /* background: linear-gradient(135deg, #4a90e2, #357abd); */
  background: #409eff;
  border: none;
  color: white;
  font-size: 15px;
  cursor: pointer;
  transition: all 0.3s ease;
}

/* 统一交互效果 */
#search-engine:hover,
#search-box:hover {
  background-color: rgba(74, 144, 226, 0.05);
}

#search-btn:hover {
  background: #357abd;
}

#search-container:focus-within {
  box-shadow: 0 0 0 2px rgba(74, 144, 226, 0.3);
}

#search-engine option {
  color: black;
  /* color: white; */
}

/* 移动端适配 */
@media (max-width: 480px) {
  #search-container {
    width: calc(100% - 40px);
    left: 20px;
  }

  #search-engine {
    padding-right: 30px;
    background-position: right 8px center;
  }
}

newtab.js内容

  • 发起搜索,跳转至搜索页面。并添加一个检测回车,快捷搜索
js 复制代码
document.getElementById("search-btn").addEventListener("click", function () {
  const engine = document.getElementById("search-engine").value;
  const query = document.getElementById("search-box").value.trim();
  if (query) {
    window.location.href = engine + encodeURIComponent(query);
  }
});

document.getElementById("search-box").addEventListener("keypress", function (event) {
  if (event.key === "Enter") {
    document.getElementById("search-btn").click();
  }
});

运行测试一下

添加日期与时间

newtab.html添加时间内容,分为时间、日期

html 复制代码
    <div id="time"></div>
    <div id="date"></div>

newtab.css创建时间样式

css 复制代码
#time {
	margin-top: 20px;
	font-size: 48px;
	color: rgba(255, 255, 255, 0.8);
}

#date {
	font-size: 22px;
	color: rgba(255, 255, 255, 0.8);
}

创建时间newtab.js

  • 获取了打开时的、年月日、时分秒与星期
  • 让时间按秒实时显示
js 复制代码
function updateClock() {
    var date = new Date();

    // 年、月、日
    var year = date.getFullYear();
    var month = date.getMonth() + 1;
    var day = date.getDate();

    // 时、分、秒
    var hour = date.getHours();
    var minute = date.getMinutes();
    var second = date.getSeconds();

    // 格式化时间为两位数
    month = month < 10 ? '0' + month : month;
    day = day < 10 ? '0' + day : day;
    hour = hour < 10 ? '0' + hour : hour;
    minute = minute < 10 ? '0' + minute : minute;
    second = second < 10 ? '0' + second : second;

    // 获取星期几
    var weekDays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
    var weekDay = weekDays[date.getDay()];

    // 实时显示
    var element = document.getElementById('time');
    element.innerHTML = hour + ':' + minute + ':' + second;
    
    var dateElement = document.getElementById('date');
    dateElement.innerHTML = year + '年' + month + '月' + day + '日 ' + weekDay;
}

// 每秒更新一次时间
setInterval(updateClock, 1000);

// 初始化显示时间
updateClock();

运行测试一下

调取高德天气接口、名言接口等

调取高德天气接口

  • 高德天气查询
    • 介绍:天气查询是一个简单的 HTTP 接口,根据用户输入的 adcode,查询目标区域当前/未来的天气情况,数据来源是中国气象局。重要的是免费哈哈~
    • 这里我们需要申请一个天气apikey,详见高德api文档
    • 这里大家记得,如果要分享发布内容,还是自定义接口,将内容写在服务器端较好,不然key会泄漏~
  • background.js更新,发起请求
js 复制代码
// 天气请求参数
const apiKey = "key";  // 你的API Key
const city = "110000";  // 北京 adcode
const cacheKey = "weather_cache";
const updateInterval = 30 * 60 * 1000; // 30分钟

  // 天气请求
  chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  
  ...
  
  if (request.action === "getWeather") {
    chrome.storage.local.get(cacheKey, (result) => {
      const cachedData = result[cacheKey];
      if (cachedData && (Date.now() - cachedData.updateTime < updateInterval)) {
        sendResponse(cachedData);
      } else {
        fetchWeather();
        setTimeout(() => {
          chrome.storage.local.get(cacheKey, (newResult) => {
            sendResponse(newResult[cacheKey] || { error: "数据获取失败" });
          });
        }, 2000); // 给 API 一点时间返回数据
      }
    });
    return true; // 表示 sendResponse 是异步的
  }
  
    ...
  
  });
  
  
  function fetchWeather() {
  const url = `https://restapi.amap.com/v3/weather/weatherInfo?key=${apiKey}&city=${city}&extensions=base&output=json`;

  fetch(url)
    .then(response => response.json())
    .then(data => {
      if (data.status === "1") {
        const weatherData = {
          weather: data.lives[0].weather,
          temperature: data.lives[0].temperature,
          updateTime: Date.now()
        };
        chrome.storage.local.set({ [cacheKey]: weatherData });
      }
    })
    .catch(() => {
      console.error("天气请求失败");
    });
}

// **定时更新天气**
setInterval(fetchWeather, updateInterval);
// fetchWeather(); // 立即执行一次
  • 这里添加了请求方法fetchWeather(),请求成功后设置缓存

  • 设置了getWeather方便新标签页调取

  • 参数city有城市编号,也可设置区号,这里放一下高德官方的地区编号文档。城市编码表

  • 首页发起获取

    • newtab.html
    html 复制代码
        <div id="weatherTitle">当前天气</div>
        <div id="weatherInfo">加载中...</div>
    • newtab.js发起添加请求并渲染
    js 复制代码
    chrome.runtime.sendMessage({ action: "getWeather" }, (response) => {
      if (response && !response.error) {
        document.getElementById("weatherInfo").innerText =
          `天气: ${response.weather}, 温度: ${response.temperature}°C`;
      } else {
        document.getElementById("weatherInfo").innerText = "获取天气失败";
      }
    });
    • newtab.css
    css 复制代码
    #weatherTitle {
      font-size: 16px;
      margin-top: 10px;
      color: rgba(255, 255, 255, 0.9);
    }
    
    #weatherInfo {
      font-size: 16px;
      margin-top: 10px;
      color: rgba(255, 255, 255, 0.9);
    }

名言接口

  • 这里使用了客观api,文档详细,大家可以自行查看随机一言api

  • 这里就不用设置key了

  • background.js更新,发起请求,设置缓存等

jss 复制代码
  chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  
  ...
  
  // 语录请求
  if (request.action === "fetchQuote") { // 确保 action 名称正确

    chrome.storage.local.get(quoteCacheKey, (result) => {
      const cachedData = result[quoteCacheKey];
      if (cachedData && Date.now() - cachedData.updateTime < cacheDuration) {
        sendResponse({ quote: cachedData.quote });
      } else {
        fetchQuote().then(() => {
          chrome.storage.local.get(quoteCacheKey, (newResult) => {
            sendResponse(newResult[quoteCacheKey] || { error: "数据获取失败" });
          });
        });
      }
    });

    return true; // 异步返回
  }
  
      ...
  
  });
  
  function fetchQuote() {
  fetch("https://api.keguan.org.cn/api/yiyan/api.php?type=json&c=i")
    .then(response => response.json())
    .then(data => {
      const quoteData = {
        quote: data,  // API 返回的语录
        updateTime: Date.now()
      };
      chrome.storage.local.set({ [quoteCacheKey]: quoteData });
    })
    .catch(() => {
      console.error("语录请求失败");
    });
}

// **定时更新语录**
setInterval(fetchQuote, cacheDuration);
// fetchQuote(); // 立即执行一次
  • 这里我请求了诗词内容

  • 这里添加了请求方法fetchQuote(),请求成功后设置缓存

  • 设置了fetchQuote方便新标签页调取

  • 首页发起获取

    • newtab.html
    html 复制代码
    <div id="quote"></div>
    • newtab.js
    js 复制代码
    // 如果你想添加动态内容,可以在这里做其他处理
    // const quotes = [
    //   "生活就是不断的开始,又不断的结束。",
    //   "活在当下,珍惜每一刻。",
    //   "每天都是新的一天,充满新的希望。"
    // ];
    
    // document.getElementById('quote').innerText = quotes[Math.floor(Math.random() * quotes.length)];
    
    
    chrome.runtime.sendMessage({ action: "fetchQuote" }, (response) => {
    
    
      console.log(response);
    
      if (response && !response.error) {
        document.getElementById("quote").innerText = response.quote.text + " ------ 《" + response.quote.from + "》";
      } else {
        document.getElementById("quote").innerText = "获取语录失败";
      }
    });
    • newtab.css
    css 复制代码
    #quote {
      font-size: 16px;
      margin-top: 10px;
      color: rgba(255, 255, 255, 0.9);
    }

结果展示

完善popup.html设置,黑暗模式,新开页面按钮

创建popup.html配置内容

  • popup.html添加按钮,与黑夜模式开关。
html 复制代码
<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <title>新标签页扩展</title>
    <link rel="stylesheet" href="/css/popup.css">
    <script src="/js/popup.js" defer></script>
</head>

<body>
    <label class="switch">
        <input type="checkbox" id="toggleDarkMode">
        <span class="slider"></span>
    </label>
    <span style="font-size: 15px;">黑暗模式</span>
    <br>
    <br>
    <button id="openNewTab">打开新标签页</button>
</body>

</html>
  • popup.css
css 复制代码
body {
    width: 250px;
    padding: 10px;
    text-align: center;
}

button {
    width: 75%;
    padding: 10px;
    margin-top: 10px;
    border-radius: 5px;
    background: #409eff;
    color: white;
    font-size: 15px;
    border: none;
    cursor: pointer;
}

/* 开关按钮样式 */
.switch {
    position: relative;
    display: inline-block;
    width: 40px;
    height: 20px;
    margin-right: 10px;
}

.switch input {
    opacity: 0;
    width: 0;
    height: 0;
}

.slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #ccc;
    transition: 0.4s;
    border-radius: 20px;
}

.slider:before {
    position: absolute;
    content: "";
    height: 14px;
    width: 14px;
    left: 3px;
    bottom: 3px;
    background-color: white;
    transition: 0.4s;
    border-radius: 50%;
}

input:checked+.slider {
    background-color: #409eff;
}

input:checked+.slider:before {
    transform: translateX(20px);
}
  • popup.js
    • 设置点击按钮打开新标签页
    • 设置切换黑暗模式,添加黑暗模式缓存
js 复制代码
document.getElementById("openNewTab").addEventListener("click", function () {
    chrome.tabs.create({ url: "newtab.html" });  // 打开新标签页
});

chrome.storage.sync.get(["darkMode"], function (data) {
    toggleDarkMode.checked = data.darkMode ?? false; // 默认关闭黑暗模式
    if (toggleDarkMode.checked) {
        document.body.classList.add("dark-mode");
    }
});

// 监听用户开关(黑暗模式)
toggleDarkMode.addEventListener("change", function () {
    chrome.storage.sync.set({ darkMode: toggleDarkMode.checked }, function () {
        if (toggleDarkMode.checked) {
            document.body.classList.add("dark-mode");
        } else {
            document.body.classList.remove("dark-mode");
        }
    });
});
  • 黑暗模式添加后,添加部分样式

    • clock.css
    css 复制代码
        .dark-mode #date {
            color: rgba(0, 0, 0, 0.8);
        }
    
        .dark-mode #time {
            color: rgba(0, 0, 0, 0.8);
        }
    • newtab.css
    css 复制代码
        .dark-mode #quote {
          color: rgba(0, 0, 0, 0.9);
        }
        
        ...
        
        .dark-mode #weatherTitle {
          color: rgba(0, 0, 0, 0.9);
        }
    
    
        .dark-mode #weatherInfo {
          color: rgba(0, 0, 0, 0.9);
        }
    
        .dark-mode #search-container {
          background: rgba(0, 0, 0, 0.7);
        }
    
        .dark-mode #search-engine {
          color: rgba(255, 255, 255, 0.6);
        }
    
        .dark-mode #search-box {
          color: rgba(255, 255, 255, 0.9);
        }
    
        .dark-mode #search-btn {
          background: #357abd;
          color: rgba(255, 255, 255, 0.8);
        }

来看看整体效果

  • 打开新标签页
  • 白天模式
  • 黑夜模式
  • 基础设置

结语

  • 本教程就此完结啦~(挖的坑终于填完了)
  • 后续可能会上架谷歌商店,或者添加一些,附属内容,云同步配置等【番外?】。
  • 其实现在的谷歌浏览器有很好用的新开标签页这里推荐大家一些:iTab ,还有微软官方的WowTab都是很好的工具。
  • OK,各位再见~

教程内容已同步到github,欢迎大家提交BUG,new-tab

相关推荐
Fantasywt2 小时前
THREEJS 片元着色器实现更自然的呼吸灯效果
前端·javascript·着色器
IT、木易3 小时前
大白话JavaScript实现一个函数,将字符串中的每个单词首字母大写。
开发语言·前端·javascript·ecmascript
Mr.NickJJ4 小时前
JavaScript系列06-深入理解 JavaScript 事件系统:从原生事件到 React 合成事件
开发语言·javascript·react.js
张拭心5 小时前
2024 总结,我的停滞与觉醒
android·前端
念九_ysl5 小时前
深入解析Vue3单文件组件:原理、场景与实战
前端·javascript·vue.js
Jenna的海糖5 小时前
vue3如何配置环境和打包
前端·javascript·vue.js
Mr.NickJJ5 小时前
React Native v0.78 更新
javascript·react native·react.js
星之卡比*6 小时前
前端知识点---库和包的概念
前端·harmonyos·鸿蒙
灵感__idea6 小时前
Vuejs技术内幕:数据响应式之3.x版
前端·vue.js·源码阅读
烛阴6 小时前
JavaScript 构造器进阶:掌握 “new” 的底层原理,写出更优雅的代码!
前端·javascript