Chrome插件开辟入门:怎样完成一键上班赖皮

很多人引见过Chrome插件,但必须要说,插件开辟就是玩弄一个小玩具,第一要素是有用,其次是好玩。 纯真排列种种功用是异常无趣的。 所以把一篇旧文拿出来与人人分享。

人,在世就是为了赖皮。

作为一个及格的开辟人员,把30%的时候用来赖皮(上班偷懒)是值得引荐的。

由于,假如你事情时候没法赖皮,并不能申明你事情认真,只能申明你的事情自动化水平不够。

赖皮狗,平常会在上班时候阅读:SGamer论坛、虎扑论坛、斗鱼、BiliBili这一类的网站。

但在阅读历程中会碰到以下痛点:

  • 老板查岗,贴子或直播间翻开太多,不能实时封闭悉数的赖皮站点。
  • 老板走了从新赖皮,不记得之前翻开的贴子或直播间在那里。
  • 每次在阅读器里输入赖皮网址,打字真的很贫苦!
  • 事情时翻开了太多标签页,歇息时很难找到想要的赖皮页面。

所以,我们须要:

简朴的一键赖皮插件须要如何的体验:

  1. 翻开阅读器后,一个疾速键,马上翻开赖皮页面,喜孜孜最先赖皮的一天。
  2. 老板/leader查岗时,一个疾速键,马上封闭一切赖皮页面。
  3. 老板走后,或事情一段时候后,一个疾速键,马上翻开本来的赖皮贴子和直播间。

简朴的一键赖皮插件功用:

  1. 包括简朴的一键赖皮站点功用
  2. 能自定义设置赖皮网站。
  3. 上传Google,宣布插件。

从零最先,开辟简朴的一键赖皮插件

90%的上班族都在运用Chrome阅读器赖皮,所以我们挑选采纳Chrome插件来完成功用。

Chrome插件没什么大不了的,依旧照样采纳HTMLCSSJS的组合。

在这里,我将手把手带你从零最先制造插件。

mainfest.json

就像node.js的package.json一样,每一个插件必需有一个manifest.json,作为最初设置文件。

我们建立一个新的项目,在根目次下建立manifest.json,填入以下代码

==mainfest.json==

 {
  "name": "上班一键赖皮东西",
  "version": "0.1",
  "description": "windows:按Alt+S开启、封闭赖皮网站\nmac:按Control+S开启、封闭赖皮网站",
  "manifest_version": 2
 }

解释一下:

  • name: 插件的名字
  • version: 插件的版本
  • description: 插件简介栏
  • manifest_version: 这个是写死的,每一个文件必需有

接下来请右键保留虎扑logo到根目次,名字照样如apple-touch-icon.png就行吧。

《Chrome插件开辟入门:怎样完成一键上班赖皮》

也能够点击
https://b1.hoopchina.com.cn/c… 保留图片

修正mainfest.json,设置四个尺寸的icon都变成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

在chrome内加载插件

点击Chorme右上角的三个点按钮...> More Tools > Extensions

《Chrome插件开辟入门:怎样完成一键上班赖皮》

在右上角把Developer mode翻开

《Chrome插件开辟入门:怎样完成一键上班赖皮》

再找到顶部的LOAD UNPACKED,把项目的根目次导入进去

《Chrome插件开辟入门:怎样完成一键上班赖皮》

项目导入后会涌现一个新的卡片,是这个结果:

《Chrome插件开辟入门:怎样完成一键上班赖皮》

这时候,你假如在Windows中按下Alt+S就会弹出音讯,音讯为toggle-tags,正好是我们在mainfest.json中定义好的。

同时我们能够点击上图蓝色键头所指导的background page,翻开一个调试东西,能够看到toggle-tags的输出。

我们在以后当地编辑插件后,能够按灰色键头所指的革新,新功用就可以马上革新加载了!

有了这些事情,意味着你能够进入下一步了!

标签页设置

一键翻开/封闭赖皮网站,完成道理实在就是chrome的标签页功用。

标签页功用接见须要在manifest.json中增加权限
==mainfest.json==

  ...
  "permissions": ["tabs"]
  ...

接下来,我们写一下background.js完成经由过程疾速键(windows的Alt+S,或mac的Ctrl+S)建立新的主页:
==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接口,就建立了一个新的标签页。
革新一下插件,再试一试疾速键功用————是否是已能掌握阅读器弹出标签 页了!
《Chrome插件开辟入门:怎样完成一键上班赖皮》

完成详细逻辑:

稍显庞杂的处所是标签页isOpen状况的处置惩罚,
下图重要关注isOpen状况的变化,以及tabCache的值变化。

《Chrome插件开辟入门:怎样完成一键上班赖皮》

详细背景逻辑以下,能够跟据备注、对比流程图举行明白:

//初始化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了。

你须要翻开storage权限:

manifest.json内增加

...
  "permissions": [
    "tabs","storage"
  ],
...

然后运用

chrome.storage.local.set({
        'value1':theValue1,
        'value2',theValue2
})

这类情势来寄存storage。
这后运用

chrome.storage.local.get(['value1'],(res)=>{
    const theValue1 = res.value1
})

如许获得寄存的value值。

最先改写background.js

我们把mainPageUrlmyPattern改成从storage中猎取。

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页面,假如点击图标就会显现,如图:

《Chrome插件开辟入门:怎样完成一键上班赖皮》

下面我们完美一下popup.html和popup.css和pupup.js页面

一切js文件都能够直接挪用chrome.storage.local.get

只须要特别注意一下js文件的chrome.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">&times</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">&times</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>')
}

好了,一个文雅的赖皮插件就做好了,人人能够检察
https://github.com/wanthering…

祝人人上班赖得高兴。 别老躲茅厕玩手机了,不健康!赖皮插件用起来!

    原文作者:刘羽冲
    原文地址: https://segmentfault.com/a/1190000017388764
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞