百度 / 谷歌 / 必应 ? 我全都要

我心飞翔 分类:javascript

每天又想谷歌,又想百度,怎么办,要是能在一个页面就好了

因此有了它

gif.gif

在线预览传送

仓库地址 是search目录

涉及到的相关知识

  • vue 的基本使用
  • grid 布局
  • 挺多的默认事件
  • 右键自定义菜单
  • 点击空白关闭菜单( 借鉴elementui源码 )
  • 读取剪贴板( 需要获取权限 )
  • H5 拖放更换两个搜索引擎的位置操作
  • ECMA中所有函数的参数都是按值传递的

首先设计一个数据结构(搜索引擎列表)

const defaultEngineList = [
    {
        logo: './image/google-logo.png',
        mark: '谷歌',
        link: 'https://www.google.com/search?q=',
        wd: ''
    },
    {
        logo: './image/baidu-logo.png',
        mark: '百度',
        link: 'https://www.baidu.com/s?wd=',
        wd: ''
    },
    {
        logo: './image/bing-logo.png',
        mark: '必应',
        link: 'https://www.bing.com/search?q=',
        wd: ''
    },
    {
        logo: './image/develop-logo.png',
        mark: '开发者',
        link: 'https://kaifa.baidu.com/searchPage?wd=',
        wd: ''
    }
]
 

借助vuegrid 布局渲染出来

进行搜索

这里只要通过索引拿到相应的引擎数据就行了

访问链接后 让 a = null, 以便更好的垃圾回收

search(idx) {
    let { link, wd } = this.engineList[idx]
    if (!wd) return

    let a = document.createElement('a')
    a.setAttribute('target', '_blank')
    a.setAttribute('href', link + wd)
    a.click()
    a = null
}
 

右键菜单(借鉴elementui源码)

image.png

  1. 对目标元素使用 contextmenu 事件并阻止默认事件, 可用vue的事件修饰符.prevent, 或者js的evt.preventDefault()

  2. 在浏览器给的事件对象取到 clientXclientY, 这俩就是菜单的左上角的位置, 我细心的让每个坐标减去 1, 以便右键点击后不用移动鼠标就能完成粘贴操作

  3. 点击菜单之外的元素关闭菜单, 需要 Dom对象的contains 方法

    只要监听整个页面的点击事件, 判断菜单的dom是否包含点击的目标元素就行了

    为此特意翻了一下 elementui 的源码, 原来他也是用的这个方法

    image.png

    window.addEventListener('click', e => {
        const isInside = document.querySelector('.context-menu').contains(e.target)
        if (!isInside) this.isShowContextMenu = false
    })
     
  4. 读取剪贴板

window.navigator.clipboard.readText()
 

这个方法来自百度, 暂时知道的不多, 它会返回Promise, 得到的就是剪贴板的文字

使用数组的 splice 方法让文字显示在输入框, 再调搜索方法直接搜索并在新页面打开

拖放换位操作

需要用到四个 api

dragstart 拖拽开始的时候

dragenter 鼠标移入可被拖拽元素的时候 (只是为了设置样式)

drop 鼠标松开的时候

dragover 持续移动的时候, 只是用来阻止他的默认事件

其实我们只要拿到两个索引之后对数组进行数据的换位就行了

dragstart 时存一下原索引, drop 时拿到目标索引后, 进行引擎列表数组的位置互换, 由vue来做视图更新的操作

换位的方法也比较简单

function exchangeLocation(arr, idx1, idx2) {
    const tempElement1 = arr[idx1]
    const tempElement2 = arr[idx2]
    arr.splice(idx1, 1, tempElement2)
    arr.splice(idx2, 1, tempElement1)
}
 

我这里直接在函数内部进行了换位, 因为ECMA中所有函数的参数都是按值传递的

函数的参数是函数作用域内的局部变量

贴心操作

  • 总是习惯按 Ctrl + S, 禁止了默认事件
window.addEventListener('keydown', evt => evt.keyCode == 83 && evt.ctrlKey && evt.preventDefault())
 
  • 刷新浏览器后排序状态保留

每次更换位置后向 localStorage 存储了这样一个排序后的数据

["谷歌", "开发者", "百度", "必应"]
 

刷新页面优先读取缓存数据

const cacheSort = localStorage.cacheSort
const engineList = cacheSort ? JSON.parse(cacheSort).map(x => defaultEngineList.find(y => y.mark === x)) : defaultEngineList
 

engineList 就是用来 v-for 的数据


建议掘金写文章的编辑器也禁止掉 Ctrl + S 的默认事件, 我总误触, 呜呜呜!!!

回复

我来回复
  • 暂无回复内容