用electron写个浏览器给自己玩
点击关注公众号,“技术干货”及时达!
浏览器这种东西工程量很唬人,但是有了electron+webview我们就相当于只需要干组装的活就可以了,而且产品目标就是给自己玩,成品的效果
??本来想写成专业的技术博客,但是发现大家好像对那种密密麻麻,全是代码的技术博客不感兴趣,我就挑重点来写吧。
下载拦截功能下载逻辑如果不做拦截处理的话,默认就是我们平常写web那种弹窗的方式,既然是浏览器肯定不能是那样的。electron中可以监听BrowserWindow的页面下载事件,并把拿到的下载状态传给渲染线程,实现类似浏览器的下载器功能。
//这个global.WIN=global.WIN=newBrowserWindow({...})
global.WIN.webContents.session.on('will-download',(evt,item)={
//其他逻辑
item.on('updated',(evt,state)={
//实时的下载进度传递给渲染线程
})
})
页面搜索功能当时做这个功能的时候我就觉得完了,这个玩意看起来太麻烦了,还要有一个的功能这不是头皮发麻啊。
查资料和文档发现这个居然是webview内置的功能,瞬间压力小了很多,我们只需要出来ctrl+f的时候把搜索框弹出来这个UI就可以了,关键字变色和下一个都是内部已经实现好了的。
functiontoSearch(){
lettimer
return()={
if(timer){
clearTimeout(timer)
}
timer=setTimeout(()={
if(keyword.value){
webviewRef.value.findInPage(keyword.value,{findNext:true})
}else{
webviewRef.value.stopFindInPage('clearSelection')
}
},200)
}
}
functioncloseSearch(){
showSearch.value=false
webviewRef.value.stopFindInPage('clearSelection')
}
functioninstallFindPage(webview){
webviewRef.value=webview
webviewRef.value.addEventListener('found-in-page',(e)={
current.value=e.result.activeMatchOrdinal
total.value=e.result.matches
})
}
当前标签页打开功能就是因为chrome和edge这些浏览器每次使用的时候开非常多的标签,挤在一起,所以我想这个浏览器不能主动开标签,打开了一个标签后强制所有的标签都在当前标签覆盖。
app.on('web-contents-created',(event,contents)={
contents.setWindowOpenHandler((info)={
global.WIN?.webContents.send('webview-url-is-change')
if(info.disposition==='new-window'){
return{action:'allow'}
}else{
global.WIN?.webContents.send('webview-open-url',info.url)
return{action:'deny'}
}
})
})
渲染线程监听到webview-open-url后也就是tart="_blank"的情况,强制覆盖当前不打开新窗口
ipcRenderer.on('webview-open-url',(event,url)={
try{
letreg=/http|https/g
if(webviewRef.valuereg.test(url)){
webviewRef.value.src=url
}
}catch(err){
console.log(err)
}
})
标签页切换功能这里的切换是css的显示隐藏,借助了vue-router
这里我们看dom就能清晰的看出来。
地址栏功能地址栏支持输入url直接访问链接、支持关键字直接打开收藏的网站、还支持关键字搜索。优先级1打开收藏的网页 2访问网站 3关键字搜索
functiontoSearch(keyword){
if(`${keyword}`.length===0){
returnfalse
}
//app搜索
if(`${keyword}`.length20){
letitem=null
constlist=[...deskList.value,...ALL_DATA]
for(leti=0;ilist.length;i++){
if(
list[i].title.toUpperCase().search(keyword.toUpperCase())!==-1&&
list[i].type!=='mini-component'
){
item=list[i]
break
}
}
if(item){
goApp(item)
returnfalse
}
}
//网页访问
leturl
if(isUrl(keyword)){
if(!/^https?:\/\//i.test(keyword)){
url='http://'+keyword
}else{
url=keyword
}
goAppNewTab(url)
returnfalse
}else{
//关键字搜索
letsearchEngine=localStorage.getItem('searchEngine')
searchEngine=searchEngine||CONFIG.searchEngine
url=searchEngine+keyword
if(!router.hasRoute('search')){
router.addRoute({
name:'search',
path:'/search',
meta:{
title:'搜索',
color:'var(--app-icon-bg)',
icon:'search.svg',
size:1
},
component:WebView
})
keepAliveInclude.value.push('search')
}
router.push({
path:'/search',
query:{url}
})
setTimeout(()={
Bus.$emit('toSearch',url)
},20)
}
}
桌面图标任意位置拖动这个问题困扰了我很久,因为它不像电脑桌面大小是固定的,浏览器可以全屏也可以小窗口,如果最开始是大窗口然后拖成小窗口,那么图标就看不到了。后来想到我干脆给个中间区域固定大小,就可以解决这个问题了。因为固定大小出来起来就方便多了。这个桌面是上下两层
//背景格子
divv-show="typeActive==='me'"class="bg-boxs"
div
v-for="(item,i)in224"//这里有点不讲究了直接写死了
:key="item"
class="bg-box"
@dragenter="enter($event,{x:(i%14)+1,y:Math.floor(i/14)+1})"
@dragover="over($event)"
@dragleave="leave($event)"
@drop="drop($event)"
/div
/div
//桌面层
//...
import{ref,computed}from'vue'
importuseDeskfrom'@/store/deskList'
import{storeToRefs}from'pinia'
exportdefaultfunctionuseDrag(){
constdragging=ref(null)
constcurrentTarget=ref()
constdesk=useDesk()
const{deskList}=storeToRefs(desk)
const{setDeskList,updateDeskData}=desk
functionstart(e,item){
e.target.classList.add('dragging')
e.dataTransfer.effectAllowed='move'
dragging.value=item
currentTarget.value=e
console.log('开始')
}
lettimer2
functionend(e){
dragging.value=null
e.target.classList.remove('dragging')
setDeskList(deskList.value)
if(timer2){
clearTimeout(timer2)
}
timer2=setTimeout(()={
updateDeskData()
},2000)
}
functionover(e){
e.preventDefault()
}
lettimer
functionenter(e,item){
e.dataTransfer.effectAllowed='move'
if(timer){
clearTimeout(timer)
}
timer=setTimeout(()={
if(item?.x){
dragging.value.x=item.x
dragging.value.y=item.y
}
},100)
}
functionleave(e){}
functiondrop(e){
e.preventDefault()
}
return{start,end,over,enter,leave,drop}
}
东西太多了就先介绍这些了
安装包地址https://github.com/jddk/aweb-browser.git
也可以到官网后https://aweb123.com 如何进入微软商店下载,mac版本因为文件大于100mb没有传上去所以暂时还用不了。
点击关注公众号,“技术干货”及时达!
阅读原文
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。 项目经理在线