Chrome浏览器扩展插件开发

news2024/9/26 3:20:47

manifest.json:

{
  "manifest_version": 3,
  "name": "ChatGPT学习",
  "version": "0.0.1",
  "description": "ChatGPT,GPT-4,Claude3,Midjourney,Stable Diffusion,AI,人工智能,AI",
  "icons": {
    "16": "./logo.png",
    "48": "./logo.png",
    "128": "./logo.png"
  },
  "content_scripts": [
    {
      "matches": ["http://*/*", "https://*/*"],
      "exclude_matches": ["https://chat.xutongbao.top/*"],
      "css": ["./dist/lib/layui.css", "./dist/css/app.css"],
      "js": ["./dist/lib/layui.js", "./dist/js/app.js", "./crx.js"]
    }
  ],
  "content_security_policy": {
    "extension_pages": "script-src 'self'; object-src 'self';"
  }
}

dist文件夹下的代码是vue项目打包后的代码

主要作用是动态的给页面右侧插入一个图标,点击图标会弹出一个对话框,对话框内通过iframe浏览我开发的人工智能网站

App.vue:

<template>
  <div class="m-plugin-out-wrap">
    <el-button @click="handleAdd">添加</el-button>
  </div>
</template>

<script>
import { Plugin } from './plugin'
import { Button } from 'element-ui'
import { create } from './tools'
import './index.css'

let feeback
export default {
  name: 'App',
  data() {
    return {}
  },
  components: {
    [Button.name]: Button,
    Plugin,
  },
  mounted() {
    this.handleAdd()
  },
  methods: {
    handleAdd() {
      if (feeback) {
        feeback.remove()
      }
      feeback = create(Plugin)
    },
    handleInit() {
      let node = document.getElementById('m-plugin')
      if (node) {
        node.parentNode.removeChild(node)
      }
      let newElement = document.createElement('div')
      newElement.id = 'm-plugin'
      newElement.innerHTML = 'Hello World'
      document.body.appendChild(newElement)
    },
  },
}
</script>

plugin/index.vue:

<template>
  <div class="m-plugin-wrap" :style="{ top: `${feedbackHeight}px` }">
    <div class="m-plugin-icon-wrap">
      <el-tooltip
        class="item"
        effect="dark"
        content="ChatGPT学习"
        placement="left-end"
      >
        <img
          src="https://static.xutongbao.top/img/logo.png"
          class="m-plugin-img"
          @click="openDialog"
          @mousedown="handleFeedbackDrag"
        />
        <!-- <span
          :class="[`icon iconfont icon-course m-plugin-icon`]"
          @click="openDialog"
          @mousedown="handleFeedbackDrag"
        ></span> -->
      </el-tooltip>
    </div>
  </div>
</template>

<script>
import { Button, Tooltip } from 'element-ui'

import './index.css'

export default {
  data() {
    return {
      feedbackHeight: 200,
    }
  },
  mounted() {
    document.addEventListener('mousemove', this.handleMouseMove)
    document.addEventListener('mouseup', this.handleMouseUp)
  },
  components: {
    [Button.name]: Button,
    [Tooltip.name]: Tooltip,
  },
  methods: {
    //#region layui
    openDialog() {
      const layui = window.layui

      layui.use(function () {
        var layer = layui.layer
        //layer.msg('Hello World', { icon: 6 })
        layer.open({
          type: 1, // page 层类型
          area: ['375px', '667px'],
          title: 'ChatGPT学习',
          skin: 'm-plugin-layer',
          shade: 0.6, // 遮罩透明度
          shadeClose: true, // 点击遮罩区域,关闭弹层
          maxmin: true, // 允许全屏最小化
          anim: 0, // 0-6 的动画形式,-1 不开启
          content:
            '<iframe src="https://chat.xutongbao.top" class="m-plugin-iframe"></iframe>',
        })
      })
    },
    //#endregion

    //#region 拖拽
    handleMouseMove(event) {
      if (this.feedbackDragging) {
        event.preventDefault()
        const deltaY = event.clientY - this.feedbackMouseY
        this.feedbackMouseY = event.clientY
        let tempFeedbackHeight = this.feedbackHeight + deltaY
        if (tempFeedbackHeight < 0) {
          tempFeedbackHeight = 0
        } else if (tempFeedbackHeight > window.innerHeight - 30) {
          tempFeedbackHeight = window.innerHeight - 30
        }

        this.feedbackHeight = tempFeedbackHeight
      }
    },
    handleMouseUp() {
      this.feedbackDragging = false
    },

    handleFeedbackDrag(event) {
      this.feedbackDragging = true
      this.feedbackMouseY = event.clientY
    },
    //#endregion
  },
}
</script>

<style></style>

tools.js:

import Vue from 'vue'
 
/**
 * @param Component 组件实例的选项对象
 * @param props 组件实例中的prop
 */
export function create(Component, props) {
  const comp = new (Vue.extend(Component))({ propsData: props }).$mount()
   
  document.body.appendChild(comp.$el)
 
  comp.remove = () => {
    document.body.removeChild(comp.$el)
 
    comp.$destroy()
  }
 
  return comp
}

效果:

人工智能学习网站:

https://chat.xutongbao.top

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1533629.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Effect:由渲染本身引起的副作用

React 组件中的两种逻辑类型&#xff1a; 渲染逻辑代码 位于组件的顶层&#xff0c;接收 props 和 state&#xff0c;进行转换&#xff0c;返回屏幕上看到的 JSX&#xff0c;只计算不做其他任何事情&#xff1b;事件处理程序 嵌套在组件内部的函数&#xff0c;由特定的用户操作…

一句命令解决huggingface.co无法下载模型问题

血来潮从github上下载的模型&#xff0c;在运行demo点批发的时候&#xff0c;发现大模型并不能直接从huggingface上直接下载&#xff0c;这是因为众所周知的网络问题。 其实只要一句命令就可以解决这个问题。 export HF_ENDPOINThttps://hf-mirror.com修改HF_ENDPOINT系统变量…

极客早报第3期:罗斯否认插足凯特王妃婚姻;清明放假调休3天;国产伟哥去年销售近13亿

一分钟速览新闻点&#xff01; 每日简报 罗斯否认插足凯特王妃婚姻清明放假调休3天国产伟哥去年销售近13亿男子持台球杆殴打2名女店员被抓今日春分淀粉肠小王子带货日销售额涨超10倍[高中生被打伤下体休学 邯郸通报](https://www.baidu.com/s?wd高中生被打伤下体休学 邯郸通报…

表的约束【mysql数据库】

表中一定要有各种约束&#xff0c;通过约束来保证未来插入表格的数据是符合预期的。约束本质是通过技术手段倒闭程序员插入正确的数据。反过来&#xff0c;站在mysql视角&#xff0c;插入进来的数据&#xff0c;都是符合数据约束的。 约束的最终目标&#xff1a;保证数据的完整…

腾讯云优惠券、代金券、折扣券领取方法及使用教程

腾讯云作为国内领先的云计算服务提供商&#xff0c;一直致力于为广大用户提供高效、稳定、安全的云服务。为了吸引用户上云&#xff0c;腾讯云经常推出各种优惠活动&#xff0c;其中就包括腾讯云优惠券。下面小编将详细介绍腾讯云优惠券的相关信息&#xff0c;包括种类、领取入…

力扣---完全平方数

思路&#xff1a; 还是比较好想的&#xff0c;g[i]定义为和为 i 的完全平方数的最少数量。那么递推关系式是g[i]min(g[i-1],g[i-4],g[i-9],...)1&#xff0c;数组初始化是g[0]0,g[1]1。注意这里要对g[0]初始化&#xff0c;&#xff08;举个例子&#xff09;因为在遍历到g[4]时&…

算法系列--递归

一.如何理解递归 递归对于初学者来说是一个非常抽象的概念,笔者在第一次学习时也是迷迷糊糊的(二叉树遍历),递归的代码看起来非常的简洁,优美,但是如何想出来递归的思路或者为什么能用递归这是初学者很难分析出来的 笔者在学习的过程中通过刷题,也总结出自己的一些经验,总结来…

[数据集][目标检测]高质量铁路轨道缺陷检测数据集VOC+YOLO格式1050张6类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1050 标注数量(xml文件个数)&#xff1a;1050 标注数量(txt文件个数)&#xff1a;1050 标注…

Altair CFD™ 无比宽广的 CFD 仿真解决方案范围

Altair CFD 提供了一套全面的工具来解决流体力学问题。无论您是要对建筑物进行热分析、预测车辆空气动力学、优化齿轮箱加油、降低冷却风扇噪音还是开发创新医疗设备&#xff0c;Altair CFD 都可以提供帮助。 提供多种方法&#xff0c;包括&#xff1a; 用于热和通用应用的通…

公职人员上班时间看股票,该不该上纲上线?

公职人员炒股是一个复杂的问题&#xff0c;需要综合考虑多方面的因素。首先&#xff0c;炒股作为一种个人投资行为&#xff0c;本身并不违法&#xff0c;但在特定情况下&#xff0c;公职人员参与股市投资可能会引发一些问题和争议。 对于公职人员炒股&#xff0c;关键是要确保其…

vue@2.7.16 使用less、less-loader

遇到问题&#xff0c;npm install less-loader7.3.0 --save安装好less-loader后&#xff0c;执行npm run serve 项目运行不起来&#xff0c;排查后发现在安装less-loader后就提示需要安装less&#xff0c;正确的安装应如下&#xff1a; npm install less less-loader7.3.0 --sa…

docker实践教程,mysql中使用自定义目录实现数据挂载(二)

有一些知识点在docker实践教程&#xff0c;nginx中使用数据卷映射修改前端网页&#xff08;一&#xff09;&#xff0c;就不累述了。 下载mysql的镜像 docker pull mysql创建容器 先去Docker Hub看看mysql是怎么使用的 可知&#xff0c;运行命令为&#xff1a;&#xff08;…

vue-admin-template极简的 vue admin 管理后台的动态路由实现方法

项目源码地址&#xff1a;GitHub - PanJiaChen/vue-admin-template: a vue2.0 minimal admin template 注意&#xff1a;项目中的路由均写在 src\router\index.js 中&#xff0c;其中默认包含 constantRoutes 数组&#xff0c;这是固定路由&#xff0c;无论用户是什么角色&…

数据结构从入门到精通——冒泡排序

冒泡排序 前言一、冒泡排序的基本思想二、冒泡排序的特性总结三、冒泡排序的动画演示四、冒泡排序的具体代码test.c 前言 冒泡排序是一种简单的排序算法&#xff0c;通过重复遍历待排序数列&#xff0c;比较相邻元素的大小并交换位置&#xff0c;使得每一轮遍历后最大&#xf…

ubuntu内存不足,用Swap扩展增加虚拟内存

Linux增大Swap分区&#xff0c;可以增加虚拟内存&#xff0c;以解决电脑卡机&#xff0c;内存不足等问题 top可以查看cpu的使用情况 lscpu可以查看本机配置的cpu硬件情况 查看内存使用情况 free -h (下面显示"交换"或者Swap等字样说明系统已经启动了Swap&#xff…

EMC Unity存储系统(包含VNXe)常用检查命令

DELL EMC的Unity存储系统&#xff0c;包括VNXe存储系统的OS已经完全和Clariion 的VNX不同了&#xff0c;近期遇到很多关于EMC unity存储系统故障的一些初步检查需求&#xff0c;下面是一些对于DELL EMC Unity存储系统的最常用的底层检查命令&#xff0c;可以对系统故障有个初步…

深度学习——线性代数相关知识

线性代数基础知识 一、线性代数基础知识1、标量2、向量3、矩阵4、张量5、点积6、向量—矩阵积7、矩阵—矩阵乘法 二、小结 一、线性代数基础知识 本节将介绍简要地回顾一下部分基本线性代数内容&#xff0c;线性代数中的基本数学对象、算术和运算&#xff0c;并用数学符号和相…

Linux编程4.11 网络编程-广播

广播实现一对多的通讯 它通过向广播地址发送数据报文实现的 1、套接字选项 套接字选项用于修饰套接字以及其底层通讯协议的各种行为。函数setsockopt和getsockopt可以查看和设置套接字的各种选项。 #include <sys/types.h> #include <sys/socket.h>int getso…

申请免费IP地址证书

目录 IP申请SSL证书需要满足什么条件呢&#xff1f; 为什么需要申请IP地址证书&#xff1f; 支持IP地址SSL证书类型 DV级别IP SSL证书和OV级别IP SSL证书的区别 申请公网IP地址证书有免费的吗&#xff1f; 背景&#xff1a;当用户直接通过IP地址而非域名访问网站时&#xf…

后端如何返回404地址

当我们网站输入不存在的地址&#xff0c;经常会出现404的页面&#xff0c;这是如何做到的 1.添加配置 spring:mvc:view:prefix: /templates/suffix: .html 2.resources下添加templates目录&#xff0c;下面放404的网站 3.添加依赖&#xff0c;版本在主pom里面配置好了&#x…