Плагины для Chrome внедряли многие, но надо сказать, что разработка плагинов — это просто игра с маленькой игрушкой.Первый элемент — это практичность, а второй — удовольствие. Просто перечислять различные функции очень скучно. Поэтому я достал старую статью, чтобы поделиться с вами.
Люди, живите, чтобы быть грубыми.
Как квалифицированному разработчику рекомендуется тратить 30% своего времени на лень (бездельничать на работе).
Потому что если вы не можете работать по часам, это не значит, что вы много работаете, это просто означает, что ваша работа недостаточно автоматизирована.
Laipigou обычно просматривает такие сайты, как SGamer Forum, Hupu Forum, Douyu и BiliBili в рабочее время.
Но в процессе просмотра вы столкнетесь со следующими болевыми точками:
- Начальник проверяет посты, открыто слишком много постов или комнат прямого эфира, а все позорные сайты вовремя закрыть не могут.
- Начальник ушел и начал снова, он не помнил пост, который открывал раньше, и где находилась комната прямого эфира.
- Действительно хлопотно печатать каждый раз, когда вы вводите небрежный URL-адрес в браузере!
- Когда на работе открыто столько вкладок, трудно найти нужную страницу во время перерыва.
Итак, нам нужно:
Возможности простого подключаемого модуля для копирования в один клик:
- После открытия браузера горячая клавиша сразу же откроет хромую страницу и с радостью начнет хромой день.
- Когда начальник/руководитель проверит пост, комбинация клавиш сразу же закроет все грубые страницы.
- После того, как босс уйдет или поработает в течение определенного периода времени, комбинация клавиш сразу же откроет исходный хромой пост и комнату прямой трансляции.
Возможности простого подключаемого модуля для копирования в один клик:
- Включает в себя простую функциональность мошеннического сайта в один клик
- Можно настроить конфигурацию веб-сайта Lapi.
- Загрузите Google, опубликуйте плагин.
С нуля разработайте простой подключаемый модуль в один клик
90% офисных работников пользуются браузером Chrome, поэтому для реализации этой функции мы решили использовать подключаемый модуль Chrome.
Плагин Chrome не имеет большого значения и по-прежнему использует комбинацию HTML\CSS\JS.
Здесь я проведу вас через создание плагина с нуля.
mainfest.json
Так же, как package.json для node.js, каждый плагин должен иметь manifest.json в качестве исходного файла конфигурации.
Мы создаем новый проект, создаем manifest.json в корневом каталоге и заполняем следующий код
==mainfest.json==
{
"name": "上班一键赖皮工具",
"version": "0.1",
"description": "windows:按Alt+S开启、关闭赖皮网站\nmac:按Control+S开启、关闭赖皮网站",
"manifest_version": 2
}
объяснять:
- имя: название плагина
- версия: версия плагина
- описание: вводная колонка плагина
- manifest_version: Это жестко запрограммировано, каждый файл должен иметь
Затем щелкните правой кнопкой мыши и сохраните логотип Hupu в корневом каталоге, имя остается прежним.apple-touch-icon.png
Просто сделай это.
Вы также можете нажатьБоюсь 1-solve.byte IMG.com/to S-talent-i-he 2…сохранить изображение
Измените mainfest.json, установите значки четырех размеров, чтобы они стали apple-touch-icon.png, а на панели подключаемых модулей также отображается apple-touch-icon.png.
==mainfest.json==
{
"name": "上班一键赖皮工具",
"version": "0.1",
"description": "windows:按Alt+S开启、关闭赖皮网站 \nmac:按Control+S开启、关闭赖皮网站",
"icons": {
"16": "apple-touch-icon.png",
"32": "apple-touch-icon.png",
"48": "apple-touch-icon.png",
"128": "apple-touch-icon.png"
},
"browser_action": {
"default_icon": "apple-touch-icon.png",
"default_popup": "popup.html"
},
"commands": {
"toggle-tags": {
"suggested_key": {
"default": "Alt+S",
"mac": "MacCtrl+S"
},
"description": "Toggle Tags"
}
},
"manifest_version": 2
}
объяснять:
-
icons
: настроенные значки отображаются в разных местах -
browser_action
: плагин в верхнем правом углу,browser_action > default_icon
То есть значок плагина в правом верхнем углу -
commands
: Обычно используется для команд быстрого доступа.commands > toggle-tags > suggested_key
Ниже установлена горячая клавиша, пока она нажата, она будет публиковать сообщение в фоновом режиме в Chrome.command
, значениеtoggle-tags
.
В среде Windows мы устанавливаем сочетания клавиш на
Alt+S
В среде Mac мы устанавливаем ярлыки наControl+S
, прописав в конфиг файлеMacCtrl+S
Теперь, когда у нас есть команда, нам нужен фоновый скрипт для получения, добавим фоновый скрипт в mainfest.json:==mainfest.json==
...
"background": {
"scripts": [
"background.js"
]
}
...
и создайте background.js в корневом каталоге.==background.js==
chrome.commands.onCommand.addListener(function(command) {
alert(command)
console.log(command)
})
Теперь наша структура каталогов выглядит следующим образом:
├── manifest.json
└── background.js
└── sgamers.png
Загрузить плагин внутри хрома
Нажмите кнопку с тремя точками в правом верхнем углу Chorme....
> More Tools
> Extensions
Включите режим разработчика в правом верхнем углу.
найти вершинуLOAD UNPACKED
, импортируем в него корневую директорию проекта
После импорта проекта появится новая карточка с таким эффектом:
В этот момент, если вы нажметеAlt+S
Появится сообщение, сообщениеtoggle-tags
, что мы и определили в mainfest.json.
В то же время мы можем нажать кнопку, обозначенную синей кнопкой на картинке выше.background page
, откройте инструмент отладки, вы можете увидетьtoggle-tags
Выход.
После того, как мы отредактируем плагин локально, мы можем нажать кнопку обновления, обозначенную серой кнопкой, и новая функция может быть немедленно обновлена и загружена!
Наличие этих рабочих мест означает, что вы можете перейти к следующему шагу!
Конфигурация вкладки
Один щелчок, чтобы открыть/закрыть уродливый веб-сайт, принцип реализации на самом деле является функцией вкладки Chrome.
Доступ к функции вкладки требует добавления разрешений в manifest.json==mainfest.json==
...
"permissions": ["tabs"]
...
Затем давайте напишем background.js для создания новой домашней страницы с помощью сочетаний клавиш (Alt+S для Windows или Ctrl+S для Mac):==background.js==
// 输入你想要的网站主页
const MainPageUrl = 'http://https://bbs.hupu.com/all-gambia'
chrome.commands.onCommand.addListener(function (command) {
if (command === 'toggle-tags') {
chrome.tabs.create({"url": MainPageUrl, "selected": true});
}
})
На самом деле реализация очень проста, достаточно вызвать интерфейс chrome.tabs.create для создания новой вкладки. Обновите подключаемый модуль и снова попробуйте функцию сочетания клавиш — возможно ли управлять всплывающими вкладками в браузере!
Реализовать конкретную логику:
Чуть более сложная часть — это обработка состояния isOpen вкладки. На следующем рисунке основное внимание уделяется изменению статуса isOpen и значения tabCache.
Конкретная фоновая логика выглядит следующим образом, что можно понять по примечаниям и блок-схеме:
//初始化isOpen和tabCache状态
let isOpen = false
let tabCache = []
//新标签打开的主页
const mainPageUrl = 'https://bbs.hupu.com/all-gambia'
//四个赖皮网站的正则匹配表达式
const myPattern = 'sgamer\.com/|douyu\.com|hupu\.com|bilibili\.com'
//当前页面的Url
let currentPageUrl = ''
/**
* 开始步骤: 判断isOpen状态
* 情形一:isOpen为true,则移除页面
* 情形二:isOpen为false,则重载页面
*/
chrome.commands.onCommand.addListener(function (command) {
if (command === 'toggle-tags') {
if (isOpen) {
//情形一:isOpen为true
removePages(myPattern)
//情形二:isOpen为false
} else {
reloadPages(myPattern, mainPageUrl)
}
}
})
/**
* 情形1:移除页面
* 1、清空tabCache缓存
* 2、关闭所有域名内标签
* 3、将关闭的标签存入tabCache缓存数组
* 4、将isOpen状态改为false
*/
function removePages(patternStr) {
tabCache = []
chrome.tabs.query({active: true}, function (tab) {
currentPageUrl = tab[0].url
})
let pattern = new RegExp(patternStr)
walkEveryTab(function (tab) {
if (pattern.test(tab.url)) {
chrome.tabs.remove(tab.id,function(){
tabCache.push(tab.url)
})
}
},function(){
isOpen = false
})
}
/**
* 情形2:重载页面
* 判断有没有缓存:
* 情形2-1无缓存:开启新标签或定位到域名内的标签
* 情形2-2有缓存:打开全部缓存内的页面
*/
function reloadPages(patternStr, mainPageUrl) {
if (tabCache.length === 0) {
focusOrCreateTab(patternStr, mainPageUrl)
} else {
openAllCachedTab(tabCache)
}
}
/**
* 情形2-1:开启新标签或定位到域名内的标签
* 1、遍历全部标签,记录符合域名的标签的url,以及最后一个标签页
* 2、如果没有符合域名的标签,则创建主页,并将isOpen状态改为true
* 3、如果有符合域名的标签:
* 1、获取当前的页面url
* 2、如果当前页面url不符合域名,则定位到这个标签页,将isOpen状态改为true
* 3、如果当前页面url符合域名,则关闭所有标签页(按情形1处理),将isOpen状态改为false
*/
function focusOrCreateTab(patternStr, url) {
let pattern = new RegExp(patternStr)
let theTabs = []
let theLastTab = null
walkEveryTab(function (tab) {
if (pattern.test(tab.url)) {
theTabs.push(tab.url)
theLastTab = tab
}
}, function () {
if (theTabs.length > 0) {
chrome.tabs.query({active: true}, function (tab) {
let currentUrl = tab[0].url
if (theTabs.indexOf(currentUrl) > -1) {
removePages(patternStr)
isOpen = false
} else {
chrome.tabs.update(theLastTab.id, {"selected": true});
isOpen = true
}
})
} else {
chrome.tabs.create({"url": url, "selected": true});
isOpen = true
}
}
)
}
/**
* 情形2-2:
* 1、把tabCache所有标签页重新打开
* 2、将isOpen状态改为true
*/
function openAllCachedTab(tabCache) {
let focusTab = null
tabCache.forEach(function (url, index) {
chrome.tabs.create({'url': url}, function (tab) {
if (tab.url === currentPageUrl) {
focusTab = tab.id
}
if (index === tabCache.length-1 - 1) {
if (focusTab) {
chrome.tabs.update(focusTab, {"selected": true},function(){
});
}
}
})
})
isOpen = true
}
/**
*
* @param callback
* @param lastCallback
* 包装一下遍历全部标签的函数,创建两个回调。
* 一个回调是每一次遍历的过程中就执行一遍。
* 一个回调是全部遍历完后执行一遍。
*/
function walkEveryTab(callback, lastCallback) {
chrome.windows.getAll({"populate": true}, function (windows) {
for (let i in windows) {
let tabs = windows[i].tabs;
for (let j in tabs) {
let tab = tabs[j];
callback(tab)
}
}
if(lastCallback) lastCallback()
})
}
Загружайте и публикуйте плагины
Нам нужно опубликовать плагин в центре разработчиков Chrome, введитеDeveloper Dashboard
Ну вот, простой и удобный в работе плагин готов! В режиме отладки вы можете использовать Ctrl+S для быстрого поиска, открытия, закрытия и повторного открытия мошеннической страницы. В любое время, в любом месте, во всех направлениях и спокойно встречайте босса.
Настраиваемый расширенный читерский плагин
Теперь я хочу, чтобы все мои плагины могли настраивать сайт в любое время:
Тогда вам нужно использовать chrome.storage.
Вам нужно открыть разрешение на хранение:
manifest.jsonдобавить в
...
"permissions": [
"tabs","storage"
],
...
затем используйте
chrome.storage.local.set({
'value1':theValue1,
'value2',theValue2
})
Эта форма используется для хранения запасов. использовать после этого
chrome.storage.local.get(['value1'],(res)=>{
const theValue1 = res.value1
})
Это получает сохраненное значение.
начать переписыватьbackground.js
мы кладемmainPageUrl
а такжеmyPattern
Измените, чтобы получить его из хранилища.
const INIT_SITES_LIST = ['bilibili.com','douyu.com','sgamer.com','hupu.com']
const INIT_MAIN_PAGE = 'https://bbs.hupu.com/all-gambia'
// 在安装时即设置好storage
chrome.runtime.onInstalled.addListener(function() {
chrome.storage.local.set({
sites: INIT_SITES_LIST,
mainPage:INIT_MAIN_PAGE
})
});
//初始化isOpen和tabCache状态
let isOpen = false
let tabCache = []
let currentPageUrl = ''
/**
* 开始步骤: 判断isOpen状态
* 情形一:isOpen为true,则移除页面
* 情形二:isOpen为false,则重载页面
*/
chrome.commands.onCommand.addListener(function (command) {
if (command === 'toggle-tags') {
chrome.storage.local.get(['sites','mainPage'],function(res){
let sites = res.sites
let mainPageUrl = res.mainPage
let myPattern = sites.map(item=>item.replace('.','\\.')).join('|')
console.log(myPattern)
if (isOpen) {
//情形一:isOpen为true
removePages(myPattern)
//情形二:isOpen为false
} else {
reloadPages(myPattern, mainPageUrl)
}
})
}
})
// ======================== 下面的部分不需要改动,看到这里就够了)
/**
* 情形1:移除页面
* 1、清空tabCache缓存
* 2、关闭所有域名内标签
* 3、将关闭的标签存入tabCache缓存数组
* 4、将isOpen状态改为false
*/
function removePages(patternStr) {
tabCache = []
chrome.tabs.query({active: true}, function (tab) {
currentPageUrl = tab[0].url
})
let pattern = new RegExp(patternStr)
walkEveryTab(function (tab) {
if (pattern.test(tab.url)) {
chrome.tabs.remove(tab.id,function(){
tabCache.push(tab.url)
})
}
},function(){
isOpen = false
})
}
/**
* 情形2:重载页面
* 判断有没有缓存:
* 情形2-1无缓存:开启新标签或定位到域名内的标签
* 情形2-2有缓存:打开全部缓存内的页面
*/
function reloadPages(patternStr, mainPageUrl) {
if (tabCache.length === 0) {
focusOrCreateTab(patternStr, mainPageUrl)
} else {
openAllCachedTab(tabCache)
}
}
/**
* 情形2-1:开启新标签或定位到域名内的标签
* 1、遍历全部标签,记录符合域名的标签的url,以及最后一个标签页
* 2、如果没有符合域名的标签,则创建主页,并将isOpen状态改为true
* 3、如果有符合域名的标签:
* 1、获取当前的页面url
* 2、如果当前页面url不符合域名,则定位到这个标签页,将isOpen状态改为true
* 3、如果当前页面url符合域名,则关闭所有标签页(按情形1处理),将isOpen状态改为false
*/
function focusOrCreateTab(patternStr, url) {
let pattern = new RegExp(patternStr)
let theTabs = []
let theLastTab = null
walkEveryTab(function (tab) {
if (pattern.test(tab.url)) {
theTabs.push(tab.url)
theLastTab = tab
}
}, function () {
if (theTabs.length > 0) {
chrome.tabs.query({active: true}, function (tab) {
let currentUrl = tab[0].url
if (theTabs.indexOf(currentUrl) > -1) {
removePages(patternStr)
isOpen = false
} else {
chrome.tabs.update(theLastTab.id, {"selected": true});
isOpen = true
}
})
} else {
chrome.tabs.create({"url": url, "selected": true});
isOpen = true
}
}
)
}
/**
* 情形2-2:
* 1、把tabCache所有标签页重新打开
* 2、将isOpen状态改为true
*/
function openAllCachedTab(tabCache) {
let focusTab = null
tabCache.forEach(function (url, index) {
chrome.tabs.create({'url': url}, function (tab) {
if (tab.url === currentPageUrl) {
focusTab = tab.id
}
if (index === tabCache.length-1 - 1) {
if (focusTab) {
chrome.tabs.update(focusTab, {"selected": true},function(){
});
}
}
})
})
isOpen = true
}
/**
*
* @param callback
* @param lastCallback
* 包装一下遍历全部标签的函数,创建两个回调。
* 一个回调是每一次遍历的过程中就执行一遍。
* 一个回调是全部遍历完后执行一遍。
*/
function walkEveryTab(callback, lastCallback) {
chrome.windows.getAll({"populate": true}, function (windows) {
for (let i in windows) {
let tabs = windows[i].tabs;
for (let j in tabs) {
let tab = tabs[j];
callback(tab)
}
}
if(lastCallback) lastCallback()
})
}
Затем мы можем написать всплывающую страницу, которая будет отображаться при нажатии на иконку, как показано на рисунке:
Давайте улучшим страницы popup.html, popup.css и pupup.js.
Все файлы js можно вызывать напрямуюchrome.storage.local.get
Просто нужно обратить особое внимание на файл jschrome.storage
часть вызова
Другие копии в порядке, мы здесь не для того, чтобы изучать макет страницы
popup.html
<html>
<head>
<title>常用网站配置页面</title>
<link rel="stylesheet" href="popup.css">
</head>
<body>
<div class="container">
<h2 class="lapi-title">常用赖皮站点域名</h2>
<ul class="lapi-content">
</ul>
<p>
<label><input type="text" id="add" class="add"></label>
<button class="button add-button ">+</button>
</p>
<p></p>
<p></p>
<p></p>
<h2>我的赖皮主页</h2>
<div id="change-content">
<span class="main-page-inactive" id="main-page-inactive"></span><button class="button change-button " id="change">✎</button>
</div>
<p class="lapi-tip">按<span class="lapi-key">Alt+S</span>快速开启/关闭赖皮站点</p>
</div>
<script src="zepto.min.js"></script>
<script src="popup.js"></script>
</body>
</html>
popup.css
* {
margin: 0;
padding: 0;
color:#6a6f77;
}
input, button, select, textarea {
outline: none;
-webkit-appearance: none;
border-radius: 0;
border: none;
}
input:focus{
list-style: none;
box-shadow: none;
}
ol, ul {
list-style: none;
}
li{
margin: 5px 0;
}
.container {
width: 200px;
padding: 10px;
}
.container h2{
margin: 10px;
text-align: center;
display: block;
}
.lapi-content li{
transition: opacity 1s;
}
.site{
cursor: pointer;
color: #00b0ff;
}
.add, .main-page{
box-sizing: border-box;
text-align:center;
font-size:14px;
/*height:27px;*/
border-radius:3px;
border:1px solid #c8cccf;
color:#6a6f77;
outline:0;
padding:0 10px;
text-decoration:none;
width: 170px;
}
#main-page{
font-size: 12px;
text-align: left;
width: 166px;
margin: 0;
padding: 2px;
}
.add{
height: 27px;
}
.main-page{
width: 170px;
outline: none;
resize: none;
}
.main-page-inactive{
width: 160px;
line-break: auto;
word-break: break-word;
overflow: hidden;
display: inline-block;
cursor: pointer;
color: #00b0ff;
margin: 3px;
}
.button{
font-size: 16px;
/*border: 1px solid #c8cccf;*/
color: #c8cccf;
/*border: none;*/
padding: 0 4px 1px 3px;
border-radius: 3px;
}
.close-button{
transition: all 1s;
}
.button:hover{
background: #E27575;
color: #FFF;
}
.add-button{
transition:all 1s;
font-size: 20px;
padding: 0 6px 1px 5px;
}
.change-button{
position: absolute;
transition:all 1s;
font-size: 20px;
padding: 0 6px 1px 5px;
}
.change-button:hover{
background: #f9a825;
color: #FFF;
}
#change-check{
color: #f9a825;
}
#change-check:hover{
color: #fff;
}
.add-button:hover{
background: #B8DDFF;
color: #FFF;
}
.submit{
transition: all 1s;
margin: 10px;
padding: 5px 10px;
font-size: 16px;
border-radius: 4px;
background: #B8DDFF;
border: 1px solid #B8DDFF;
color: #FFF;
}
.submit:hover{
border: 1px solid #B8DDFF;
background: #fff;
color: #B8DDFF;
}
.fade{
opacity: 0;
}
.add-wrong,.add-wrong:focus{
border: #e91e63 1px solid;
box-shadow:0 0 5px rgba(233,30,99,.3);
}
.lapi-tip{
margin-top: 20px;
border-top: 1px solid #c8cccf;
padding-top: 8px;
color: #c8cccf;
text-align: center;
}
.lapi-key{
color: #B8DDFF;
}
Фокус:chrome.storage
часть
popup.js
let sites = []
let mainPage = ''
const isMac = /Macintosh/.test(navigator.userAgent)
let $lapiKey = $('.lapi-key')
isMac? $lapiKey.text('Control+S'):$lapiKey.text('Alt+S')
// 从storage中取出site和mainPage字段,并设置在页面上。
chrome.storage.local.get(['sites','mainPage'], function (res) {
if (res.sites) {
sites = res.sites
mainPage = res.mainPage
sites.forEach(function (item) {
let appendEl = '<li><span class="site">' + item + '</span>\n' +
'<button class="button close-button">×</button>\n' +
'</li>'
$('ul.lapi-content').append(appendEl)
})
}
$('#main-page').val(mainPage)
$('#main-page-inactive').html(mainPage)
})
$('#save').on('click', function () {
alert()
})
$('#change-content').delegate('#main-page-inactive','click',function(){
let mainPageUrl = $(this).html()
if(/^http:\/\/|^https:\/\//.test(mainPageUrl)){
chrome.tabs.create({"url": mainPageUrl, "selected": true})
}else{
chrome.tabs.create({"url": 'http://'+mainPageUrl, "selected": true})
}
})
let addEl = $('#add')
addEl.focus()
let lapiCon = $('ul.lapi-content')
lapiCon.delegate('.close-button', 'click', function () {
let $this = $(this)
let siteValue = $this.siblings().html()
sites = sites.filter(function (item) {
return item !== siteValue
})
chrome.storage.local.set({sites: sites})
$this.parent().addClass('fade')
setTimeout(function () {
$this.parent().remove()
}, 800)
})
$('.add-button').on('click',addEvent)
addEl.bind('keypress',function(event){
if(event.keyCode === 13) addEvent()
})
function addEvent(){
if(!validate(addEl.val())){
addEl.addClass('add-wrong')
}else{
let appendEl = '<li><span class="site">' + addEl.val() + '</span>\n' +
'<button class="button close-button">×</button>\n' +
'</li>'
$('ul.lapi-content').append(appendEl)
sites.push(addEl.val())
chrome.storage.local.set({sites:sites})
addEl.removeClass('add-wrong')
addEl.focus().val('')
}
}
function validate(value){
value = value.trim()
if(value.length ===0){
return false
}
return /^([\w_-]+\.)*[\w_-]+$/.test(value)
}
lapiCon.delegate('.site','click',function(){
let siteUrl = $(this).html()
chrome.tabs.create({"url": 'http://'+siteUrl, "selected": true})
})
$('#change-content').delegate('#change','click',function(){
changeMainPage($(this))
}).delegate('#change-check','click',function(){
changeCheck($('#change-check'))
}).delegate('#main-page','blur',function(){
changeCheck($('#change-check'))
})
function changeMainPage($this){
$this.siblings().remove()
$this.parent().prepend('<label><textarea id="main-page" class="main-page"></textarea></label>')
$this.parent().append('<button class="button change-button " id="change-check">✓</button>')
$('#main-page').val(mainPage).focus()
$this.remove()
}
function changeCheck($this){
let mainPageVal = $('#main-page').val()
$this.siblings().remove()
$this.parent().prepend('<span class="main-page-inactive" id="main-page-inactive"></span>')
$('#main-page-inactive').text(mainPageVal)
chrome.storage.local.set({mainPage:mainPageVal})
$this.parent().append('<button class="button change-button " id="change">✎</button>')
}
Что ж, элегантный плагин для фарса готов, можете его проверитьGitHub.com/хочу и звоню/…
Желаю всем счастливой работы. Не прячьтесь в туалете и не играйте с телефоном, это вредно для здоровья! Используйте плагин Lapi!