包阅导读总结
1. `Electron`、`浏览器`、`功能`、`组装`、`下载拦截`
2. 作者基于 Electron 和 WebView 写了一个给自己玩的浏览器,介绍了下载拦截、页面搜索等功能的实现,还提到了当前标签页打开、标签页切换、地址栏等功能,最后给出了安装包地址。
3.
– 下载拦截功能
– 可监听 BrowserWindow 的页面下载事件,将下载状态传给渲染线程,实现类似浏览器的下载器功能。
– 页面搜索功能
– WebView 内置搜索功能,只需处理弹出搜索框的 UI 及相关操作。
– 当前标签页打开功能
– 强制所有标签在当前标签覆盖,通过相关代码处理窗口打开方式。
– 标签页切换功能
– 借助 Vue-router 实现 CSS 的显示隐藏来切换标签页。
– 地址栏功能
– 支持多种输入方式,包括直接访问链接、打开收藏网站和关键字搜索,有优先级设定。
– 桌面图标任意位置拖动
– 设定中间区域固定大小解决拖动问题,给出相关代码。
– 安装包地址
– github.com/jddk/aweb-b…
– 官网 aweb123.com 可进微软商店下载,mac 版本因文件大暂未上传。
思维导图:
文章地址:https://juejin.cn/post/7395389351641612300
文章来源:juejin.cn
作者:九段刀客
发布时间:2024/7/25 20:56
语言:中文
总字数:1414字
预计阅读时间:6分钟
评分:90分
标签:Electron,Webview,JavaScript,浏览器开发,下载拦截
以下为原文内容
本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com
浏览器这种东西工程量很唬人,但是有了electron+webview我们就相当于只需要干组装的活就可以了,而且产品目标就是给自己玩,成品的效果
😄本来想写成专业的技术博客,但是发现大家好像对那种密密麻麻,全是代码的技术博客不感兴趣,我就挑重点来写吧。
下载拦截功能
下载逻辑如果不做拦截处理的话,默认就是我们平常写web那种弹窗的方式,既然是浏览器肯定不能是那样的。electron中可以监听BrowserWindow的页面下载事件,并把拿到的下载状态传给渲染线程,实现类似浏览器的下载器功能。
global.WIN.webContents.session.on('will-download', (evt, item) => { item.on('updated', (evt, state) => { }) })
页面搜索功能
当时做这个功能的时候我就觉得完了,这个玩意看起来太麻烦了,还要有一个的功能这不是头皮发麻啊。
查资料和文档发现这个居然是webview内置的功能,瞬间压力小了很多,我们只需要出来ctrl+f的时候把搜索框弹出来这个UI就可以了,关键字变色和下一个都是内部已经实现好了的。
function toSearch() { let timer return () => { if (timer) { clearTimeout(timer) } timer = setTimeout(() => { if (keyword.value) { webviewRef.value.findInPage(keyword.value, { findNext: true }) } else { webviewRef.value.stopFindInPage('clearSelection') } }, 200) }} function closeSearch() { showSearch.value = false webviewRef.value.stopFindInPage('clearSelection')}function installFindPage(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 { let reg = /http|https/g if (webviewRef.value && reg.test(url)) { webviewRef.value.src = url } } catch (err) { console.log(err) }})
标签页切换功能
这里的切换是css的显示隐藏,借助了vue-router
这里我们看dom就能清晰的看出来。
地址栏功能
地址栏支持输入url直接访问链接、支持关键字直接打开收藏的网站、还支持关键字搜索。优先级1打开收藏的网页 2访问网站 3关键字搜索
function toSearch(keyword) { if (`${keyword}`.length === 0) { return false } if (`${keyword}`.length < 20) { let item = null const list = [...deskList.value, ...ALL_DATA] for (let i = 0; i < list.length; i++) { if ( list[i].title.toUpperCase().search(keyword.toUpperCase()) !== -1 && list[i].type !== 'mini-component' ) { item = list[i] break } } if (item) { goApp(item) return false } } let url if (isUrl(keyword)) { if (!/^https?:\/\//i.test(keyword)) { url = 'http://' + keyword } else { url = keyword } goAppNewTab(url) return false } else { let searchEngine = 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) } }
桌面图标任意位置拖动
这个问题困扰了我很久,因为它不像电脑桌面大小是固定的,浏览器可以全屏也可以小窗口,如果最开始是大窗口然后拖成小窗口,那么图标就看不到了。后来想到我干脆给个中间区域固定大小,就可以解决这个问题了。因为固定大小出来起来就方便多了。这个桌面是上下两层
//背景格子 <div v-show="typeActive === 'me'" class="bg-boxs"> <div v-for="(item, i) in 224" //这里有点不讲究了直接写死了 :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'import useDesk from '@/store/deskList'import { storeToRefs } from 'pinia'export default function useDrag() { const dragging = ref(null) const currentTarget = ref() const desk = useDesk() const { deskList } = storeToRefs(desk) const { setDeskList, updateDeskData } = desk function start(e, item) { e.target.classList.add('dragging') e.dataTransfer.effectAllowed = 'move' dragging.value = item currentTarget.value = e console.log('开始') } let timer2 function end(e) { dragging.value = null e.target.classList.remove('dragging') setDeskList(deskList.value) if (timer2) { clearTimeout(timer2) } timer2 = setTimeout(() => { updateDeskData() }, 2000) } function over(e) { e.preventDefault() } let timer function enter(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) } function leave(e) {} function drop(e) { e.preventDefault() } return { start, end, over, enter, leave, drop }}
东西太多了就先介绍这些了
安装包地址
github.com/jddk/aweb-b…
也可以到官网后aweb123.com 如何进入微软商店下载,mac版本因为文件大于100mb没有传上去所以暂时还用不了。