React js原生 详解 HTML 拖放 API(鼠标拖放功能)

news2025/3/1 4:55:40

最近碰到了个需求,大概就是要通过可视化拖拽的方式配置一个冰柜,需要把预设好的冰柜内部架子模板一个个拖到冰箱内。一开始的想法是用鼠标事件(mousedown、mouseup等)那一套去实现,能实现但是过程过于复杂,需要控制的状态太多了。其实 Web Api 为 html 元素拖拽量身定制了一套 HTML 拖放API,用这个方法实现一些简单的拖拽功能简直不要太简单。为此写了这篇文章,下面将详细介绍 HTML 拖放 API 的核心知识点

文档

一、被拖拽元素和放置被拖拽元素的元素

通常我们所了解的拖放是按住鼠标左键不放然后移动鼠标把一个页面元素从某个位置移动到另一个位置,然后松开鼠标左键,至此完成了整个拖放过程。在这个过程中我们需要先重点关注两个东西,一个是被拖拽元素另一个是 放置被拖拽元素的元素

1.1 被拖拽元素

我们得先有个概念,页面上显示的元素默认并不都是可以被拖拽的(除了图片、被选中的文字、链接),所以如果当前元素默认不可被拖拽那么就得先把它设置为可拖拽的。ps:可拖拽元素被拖拽时会有一个半透明的快照跟着鼠标移动。

将 HTML 元素的 draggable 属性设置为 true, 元素就可以变为可拖拽元素。效果如下图。

<div id="box" draggable="true">draggable box</div>

在这里插入图片描述

1.2 可放置被拖拽元素的元素

所有的元素区域默认是不支持放置被拖拽元素的,直观的表现是,当被拖拽元素经过不可放置区域时鼠标的样式是一个禁止放置的一个图标(圆圈带一个斜杠),所以需要将目标元素设置为一个可放置区域

默认情况下是这样:

<div id="box" draggable="true">draggable box</div>
<div id="droppable">放置区域</div>

在这里插入图片描述
设置为放置区域需要给元素绑定一个事件 dragover 且要 阻止默认行为

<div id="box" draggable="true">draggable box</div>
<div id="droppable">放置区域</div>
<script>
    let dropDom = document.getElementById('droppable')
    dropDom.addEventListener('dragover', (e) => {
        e.preventDefault()
    })
</script>

React:
放置区域需要绑定onDragOver事件,且要 阻止默认行为 – 其他事件一样加on

<div draggable="true">draggable box</div>
<div onDragOver={(e) => {e.preventDefault()}}>放置区域</div>

设置为可放置区域后鼠标样式也变了不再是禁止图标,而是一个加号图标(图标可以设置,下面会讲解):
在这里插入图片描述
然而你会发现被拖放元素并没有真正的被放置到放置区域,这是必然的,放置操作需要开发者自行定义,以上的设置只是是为了向用户表明这个区域是允许放东西的,那么至于怎么放需要开发者自行决定。

二、拖拽过程触发的一些事件

这一小节将带你了解整个拖放过程的其他细节,比如拖拽过程中会触发哪些事件

2.1 被拖放目标触发的事件

给被拖放目标元素绑定三个事件 dragstart、drag、dragend。

<div id="box" draggable="true">draggable box</div>
<div id="droppable">放置区域</div>
<script>
    let dragDom = document.getElementById('box')
    dragDom.addEventListener('dragstart', (e) => {
        console.log('开始拖动');
    })
    dragDom.addEventListener('drag', (e) => {
        console.log('拖动中');
    })
    dragDom.addEventListener('dragend', (e) => {
        console.log('结束拖动');
    })
</script>

React

<div  
    draggable="true"
    onDragStart={(e) => {
      console.log("开始拖动", e);
    }}
    onDrag={(e) => {
      console.log("拖动中", e);
    }}
    onDragEnd={(e) => {
      console.log("结束拖动", e);
    }}
>
>draggable box</div>
<div onDragOver={(e) => {e.preventDefault()}}>放置区域</div>

开始拖动触发 dragstart ,拖动过程中(鼠标不松开)触发drag,松开鼠标(或者按下 Esc 键)触发 dragend
在这里插入图片描述

2.2 被拖拽元素在放置区域内会触发的事件

先给放置目标元素绑定四个事件

<div id="box" draggable="true">draggable box</div>
<div id="droppable">放置区域</div>
<script>
    let dropDom = document.getElementById('droppable')
    dropDom.addEventListener('dragenter', (e) => {
        console.log('进入到了放置区域~');
    })
    dropDom.addEventListener('dragover', (e) => {
        e.preventDefault()
        console.log('在放置区域内拖拽中~');
    })
    dropDom.addEventListener('dragleave', (e) => {
        console.log('离开了放置区域~');
    })
    dropDom.addEventListener('drop', (e) => {
        console.log('在放置区域内,放下了被拖拽元素~')
    })
</script>

拖拽元素进入放置区域内时触发 dragenter 事件,在放置区域内移动被拖放(鼠标不松开)元素触发 dragover 事件,被拖放元素离开放置区域触发 dragleave 事件,在放置区域内松开鼠标触发 drop 事件。
在这里插入图片描述

三、实现真正意义上的元素拖放

通过上面触发的事件我们可以知道,用户真正在放置区域释放鼠标的时候只有 drop 事件能够监听到。所以开发者需要在这个事件里做真正的放置操作,放置什么由开发者决定,可以是被拖拽元素,也可以是自定义的一些内容。

放置被拖拽元素:

<div id="box" draggable="true">draggable box</div>
<div id="droppable">放置区域</div>
<script>
    let dropDom = document.getElementById('droppable')
    dropDom.addEventListener('dragover', (e) => {
        e.preventDefault()
        console.log('在放置区域内拖拽中~');
    })
    dropDom.addEventListener('drop', (e) => {
        console.log('在放置区域内,放下了被拖拽元素~')
        e.target.appendChild(document.getElementById('box'))
    })
</script>

在这里插入图片描述
放置自定义内容

dropDom.addEventListener('drop', (e) => {
    console.log('在放置区域内,放下了被拖拽元素~')
    let customCOntent = '<p>自定义内容</p>'
    e.target.innerHTML = e.target.innerHTML + customCOntent
})

在这里插入图片描述

四、dataTransfer 对象

4.1 从被拖放元素向可放置元素传递数据

dataTransfer 对象提供了一个setData()方法,它接受两个参数,第一个参数是传递数据的类型(一般是标准的MIME类型),第二个数据是数据值。dataTransfer 还提供了 getData() 的方法用于获取传递的数据,它接受一个参数,参数值为 setData 对应的第一个参数。

传递一个简单的字符串数据

<div id="box" draggable="true">draggable box</div>
<div id="droppable">放置区域</div>
<script>
    let dropDom = document.getElementById('droppable')
    let dragDom = document.getElementById('box')

    dragDom.addEventListener('dragstart', (e) => {
        e.dataTransfer.setData('text/plain', '自定义数据')
    })
    dropDom.addEventListener('dragover', (e) => {
        e.preventDefault()
    })
    dropDom.addEventListener('drop', (e) => {
        let data = e.dataTransfer.getData('text/plain')
        console.log('你传递的数据为:', data);
    })
</script>

在这里插入图片描述
⚡注意:只能在 dragstart 事件中设置数据,在其他地方设置无效。且只能在 drop 事件中获取设置的数据,其他事件中获取不到。
案例:根据传递的数据放置不同的内容。

<div id="box" draggable="true">draggable box</div>
<div id="droppable">放置区域</div>
<script>
    let dropDom = document.getElementById('droppable')
    let dragDom = document.getElementById('box')
    dropDom.addEventListener('dragover', (e) => {
        e.preventDefault()
    })
    dropDom.addEventListener('drop', (e) => {
        let num = e.dataTransfer.getData('num')
        console.log(num);
        if(num > 5)
            e.target.innerHTML = e.target.innerHTML + '<p>传递的数字大于5</p>'
        else if(num == 5) 
            e.target.innerHTML = e.target.innerHTML + '<p>传递的数字等于5</p>'
        else
            e.target.innerHTML = e.target.innerHTML + '<p>传递的数字小于5</p>'
    })
    dragDom.addEventListener('dragstart', (e) => {
        let num = Math.floor(Math.random() * 10) + 1;
        e.dataTransfer.setData('num', num)
    })
</script>

在这里插入图片描述

4.2 自定义拖拽过程中跟随鼠标移动的内容

默认情况下元素被拖拽时会有一个半透明的元素快照跟随着鼠标移动。通过 dataTransfer 提供的 setDragImage(elemnt, xOffset, yOffset) 方法是可以自定义跟随内容。接受三个参数 elemnt 可以是 dom 节点或者一个图片对象,xOffset, yOffset 是相对于鼠标的偏移量。

设置为一个图片:

<script>
	import Tag from "../../style/imgs/attributeTag/路径.png"; //已经存在的图片
    let dragDom = document.getElementById('box')
    dragDom.addEventListener('dragstart', (e) => {
        let img = new Image()
        // 创建一个图像并且使用它作为拖动图像
 		// 请注意: 改变 "example.gif" 为一个已经存在的图片
 		// 或者,一个还没有创建出来的图片,那么浏览器将会使用默认的拖动图片
 		// 译者注:默认的拖动图片与拖动对象没有联系。一般是一个小型文件图标
 		// 例如:
 		// mg.src = Tag 
 		//或
 		// mg.src = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAmCAYAAACoPemuAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABklJREFUeNqsmFtwE1UYx/97Tdqkbei91Gk6IFouYjqjBR3aQTstoM40DD4gOIO++sL4pr45+q7iu+OMyJMD1RcZAXGEBxiUm0JrKfQiDoVeSEmv2WSP3znJJpt0d1Mgpz3d3bPJnt/+v8v5TqX9X89HGMNZ6iGGdGOZP9a11Riz3bddm4n4tz991Pg+SthkDmVmoPhE2Q5bLxwruIakRVHiJnMo+9s/SZMULfTW56PRUiuWB8UKjmCrIqNfva+kYPb5vRiYi5/lnuQrsWIOkzyWWixnzjc/K505VUcgN9Ai5qwo1w7duHknFgzoUDU5Ky+z+YrbuW3sajgcjqmsCAnzSBeFLcn06NJSPBoI+CBJMmQZjw1mmmZsbGzsQ3kFUBEopxewbi3DhyujBhYXl8TnJUl67C7Lcoj6F6rb61vD5TrQ3mKiNsiy45fHZIxPSw7fUnBrphwvPJqDrikIBMposidIP5IUUr38qWdTCn2RlICztyiNDU7IOHJaxXwi/95wrBJJI454fB6qKsPv93marsC/LLBcVBZGJwd6pyMfamou9/ot1TkV7aZeZj4MTqpIJk3Mzy8gkUg8fVRaE7RUMwHG2wI999hFFeeH0+5YG2A4sC2F/isKxmYkx+gcmirDpsY5cmQm4AKBcmia5qiOK5jT/Z7Nqez5kTMamU3K2pmrduSM6hmttx5yc84imTIhKxIFw2J6MlV9CsWotzWmpxgnRQRUZsZoe8oxSE5cVvLGEmTOfyZ1RMpN4WcUE5iYmsbQv/ex7plGtDbVFwdzEtTyHRF5tg84gfE2cE+mnlNVmHO6DFuayZykGiO42bkF/HrpKt2MINxY5+r4ropZTs7hWmrYqrL/ZHzlGDfn8bNnoOkSqSYhkUwKk/9xcwij9x5AymRflin+GmpC2LO93QbmMOMgvf2ODUwEwfNNTFzzdugbPfuwT95Ioq3JFMGRjVabryUo2Y7MlMHP7tLyRMlTTn+GKzdLAaEopImUgRM/KK7YuWGFwExxfrjbwFc8AAiOA/H0cXB7Goq3P8dkx1WAm7NmbQTd69ZSVOoUlTIID8i8w/lrg7g7+RDtbesR2RCGX9eL+xiH+OWGgt7N6Tz28R5DqDIVl7JAVio5ekF1tDP3mYlEPRRpGinys+a6NfD7NJE8lxMGxiemBGTHxnVYW1dTPCqtdvSCIrL63ozDc5+zJ1QO+uUpFQvLTusqy0SnHz9cuAfVGEVrcx0O7u5MW+TaQDpJN9SiuiJA4CkyrZL3fdUrz/E0cG5IRudzZjaFTM2lo5CPOy/2toDhpVDtFhgP/hMK/XV7HKFgAJcGbguLdkY2is8ZhpFeaW1warGKdZKUOW7PU8x9bc2Dyhy5ObtaW3B95A5OX7puuRhe2vRsXtpIUtRaFQZ/zoq10rXEdiiJikFZ5gxUt6GpphpLSwaWyL/qq6vQ+WLbynqO4Kgey6/54QXDvCtaNygr2f49oWFx2cg+anZuXqQNp4Dh/iYUg5tkrDgjf4AnlK0UejDzCDqtlfVrKoVq3588h/szMceX43DyEwjmCMS8qmAtCPjD2LdzO/Z370DDmioBd/Tk75gguMLlyNPHmEsht+IhHnuF3B5VQVO4gyIyKCqMA71daCA/W6Ra7buff3NUTmZm0rOitHfXWFjFXkGUQklGizqDT1NxcFdnVrlTF6877CtTy7FCACcQV9N6po/cOa9sByZUGFTZ8mfrVDi+u7sLW9eH8Xb3K3lq8aOyvuuD+7Rp2kkLqh+MQrVIZ/xoOo8z69q0nVudkFVa2jc2GNCoDFKogNTIrG3hZqiZxCrZdi7ibNenIyFRKK1iZ+vse5S9R4YPI4Wom015mb23pwqvbinLLuq0TcsmVAsqeyzVln5n37GorAZPiFKm0LykYF9vFba1V9GuSYVPV0kxWWzt8lTKZP6SgvH2+r7+h5Ksh/KVMhHtrSSoSrHX1AmKl9tuUNaYXNL/trFUP6+5cmteGqojUkmmU0TnvrWanVJJwZhp/JgOBEoLJm2WeyoIqoKUkkXnUGlBmCcUrzZKCna2f3+/aRoxrlRfTxAvbw0Ks/EuZ0prt1RkV5E2yTEVJW6pVKK/r7fivfbNZeQ4JhnWFFGbTKbyo67Ap6zo5FDUX/tfgAEAQ3WUFGFdgUwAAAAASUVORK5CYII=`;
        img.src = 'example.gif'
        e.dataTransfer.setDragImage(img, 10, 10)
    })
</script>

在这里插入图片描述

4.3 设置放置前的反馈图标

dataTransfer 提供了一个 dropEffect属性设置放置前的反馈图标,它有四种取值 none move copy link

在 dragover 中设置 dropEffect 的值

dropDom.addEventListener('dragover', (e) => {
    e.preventDefault()
    e.dataTransfer.dropEffect = 'link' // none || move || copy || link
})
  • 值为 none 或者经过不可放置区域,显示禁止放置图标在这里插入图片描述
  • 值为 move 时
    在这里插入图片描述
  • 值为 copy 时
    在这里插入图片描述
  • 值为 link 时
    在这里插入图片描述

4.4 拖动文件上传

通过 dataTransfer 的 files 属性可以获取用户拖拽的文件信息

拖拽系统文件到放置区域,并打印拖拽的文件信息:

dropDom.addEventListener('drop', (e) => {
    e.preventDefault()
    // 上传的文件列表
    let fileList = e.dataTransfer.files
    for (let i = 0; i < fileList.length; i++) {
        const file = fileList[i];
        console.log('文件名:' + file.name);
        console.log('文件大小:' + file.size);
        // 后续操作 比如:调接口上传文件
    }
})

在这里插入图片描述

4.5 清除 setData() 的值

dataTransfer 提供了 clearData() 清除 setData 设置的值,传参数则删除指定类型的值,不传则全部清除。

dropDom.addEventListener('drop', (e) => {
    console.log(e.dataTransfer.getData('text/plain'));
    console.log(e.dataTransfer.getData('text/html'));
})

dragDom.addEventListener('dragstart', (e) => {
    e.dataTransfer.setData('text/plain', '自定义数据')
    e.dataTransfer.setData('text/html', '自定义数据2')
    e.dataTransfer.clearData('text/html')
})

在这里插入图片描述

4.6 查看设置了哪些类型的值

dataTransfer 提供了 types 属性查看 setData 设置了哪些类型的值。

dropDom.addEventListener('drop', (e) => {
    console.log(e.dataTransfer.types);
})
dragDom.addEventListener('dragstart', (e) => {
    e.dataTransfer.setData('text/plain', '自定义数据')
    e.dataTransfer.setData('text/html', '自定义数据2')
})

在这里插入图片描述

4.7 effectAllowed 属性取值会影响到 dropEffect 的取值效果。

effectAllowed 用于限制 dropEffect 只能设置哪些值

effectAllowed 的取值有: + none -> 此项表示 dropEffect 设置任何值都是禁止效果 + copy -> dropEffect 可以设置为 copy + copyLink -> dropEffect 可以设置为 copy 和 link + copyMove -> dropEffect 可以设置为 copy 和 Move + link -> dropEffect 可以设置为 link + linkMove -> dropEffect 可以设置为 link 和 Move + move -> dropEffect 可以设置为 Move + all -> dropEffect 可以设置为所有合法值 + uninitialized -> 等同 all 效果

dropDom.addEventListener('dragover', (e) => {
    e.preventDefault()
    e.dataTransfer.dropEffect = 'move'
})
dragDom.addEventListener('dragstart', (e) => {
    e.dataTransfer.effectAllowed = 'none'
})

上面即使 dropEffect 设置为 move, 但是 effectAllowed 的值为 none,所有还是禁止放置的反馈图标。
在这里插入图片描述

五、总结

  • 实现一个拖拽功能时先定义好被拖拽元素和放置区域元素。
  • 所有的放置操作都是在 drop 事件中完成。
  • 放置前的反馈效果可以根据你传递的数据来设置 dropEffect 显示不同的效果。
  • 被拖拽元素也可以是放置区域,放置区域也可以是被拖拽元素,两者没有明确的界限。
  • 功能自定义按需求开发

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

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

相关文章

Linux 回顾总结

学习前提&#xff08;环境搭建&#xff09;&#xff1a;RHCSA Linux环境搭建-CSDN博客 目录 一、shell 二、文件 三、用户和组管理 四、权限 五、软件 六、网络 七、磁盘 一、shell Linux的操作界面常称为Shell&#xff0c;Shell是操作系统提供给用户使用的界面&#xf…

【Python】PaddleOCR文字识别国产之光 从安装到pycharm中测试 (保姆级图文)

目录 官方项目地址Python环境搭建&#xff08;也就是使用Anaconda的python&#xff09;1. 安装Anaconda1. 打开终端并创建conda环境 安装PaddlePaddle&#xff08;CPU演示&#xff09;安装PaddleOCR whl包如果安装shapely库报错&#xff08;我没有报错&#xff0c;其他类似库安…

MongoDB 索引和常用命令

一、基本常用命令 1.1 案例需求 存放文章评论的数据存放到 MongoDB 中&#xff0c;数据结构参考如下&#xff0c;其中数据库为 articledb&#xff0c; 专栏文章评论 comment 字段名称 字段含义 字段类型 备注 _id ID ObjectId或String Mongo的主键的字段 articlei…

【Mybatis】基于Mybatis插件+注解,实现敏感数据自动加解密

一、介绍 业务场景中经常会遇到诸如用户手机号&#xff0c;身份证号&#xff0c;银行卡号&#xff0c;邮箱&#xff0c;地址&#xff0c;密码等等信息&#xff0c;属于敏感信息&#xff0c;需要保存在数据库中。而很多公司会会要求对数据库中的此类数据进行加密存储。 敏感数据…

光伏三相并网逆变器的控制策略与性能分析

微❤关注“电击小子程高兴的MATLAB小屋”获得资料&#xff08;专享优惠&#xff09; 光伏三相并网逆变器的控制策略与性能分析 引言&#xff1a; 随着可再生能源的日益重视和发展&#xff0c;光伏发电系统在电力系统中的地位越来越重要。其中&#xff0c;光伏三相并网逆变器…

什么台灯最好学生晚上用?开学适合孩子学习的台灯

作为学龄期儿童的家长&#xff0c;最担心的就是孩子长时间学习影响视力健康。无论是上网课、写作业、玩桌游还是陪伴孩子读绘本&#xff0c;都需要一个足够明亮的照明环境&#xff0c;因此选购一款为孩子视力发展保驾护航的台灯非常重要。推荐五款适合孩子学习的台灯。 1. 书客…

distcc分布式编译

distcc https://gitee.com/bison-fork/distcc.git 下载工具链 mingw&#xff0c;https://www.mingw-w64.org/downloads/#w64devkitperl&#xff0c;https://strawberryperl.com/releases.html免安装zip版本&#xff0c;autoconf等脚本依赖perlautoconf、automake&#xff0c…

软件测试学习(四)自动测试和测试工具、缺陷轰炸、外包测试、计划测试工作、编写和跟踪测试用例

目录 自动测试和测试工具 工具和自动化的好处 测试工具 查看器和监视器 驱动程序 桩 压力和负载工具 干扰注入器和噪声发生器 分析工具 软件测试自动化 宏录制和回放 可编程的宏 完全可编程的自动测试工具 随机测试&#xff1a;猴子和大猩猩 使用测试工具和自动…

SpringBoot 前端406 后端Could not find acceptable representation

原因:返回对象没有get方法,无法转成JSON格式

2023年10月13日历史上的今天大事件早读

54年10月13日罗马帝国皇帝克劳狄一世逝世 467年10月13日北魏孝文帝拓跋宏出生 982年10月13日辽国皇帝辽景宗逝世 1847年10月13日李沅发起义 1884年10月13日国际标准时间日 1925年10月13日前英国首相撒切尔夫人出生 1927年10月13日鲁丝-埃尔德飞渡大西洋失败 1928年10月1…

电脑怎么剪辑视频?高手分享的独家秘诀

视频剪辑是一项有趣而具有创造性的活动&#xff0c;可以帮助您将录制的视频片段转化为有趣、有启发性的作品。无论您是想创建家庭影片、Vlog视频、教程&#xff0c;还是其他任何类型的视频&#xff0c;掌握视频剪辑技巧都是必要的。那电脑怎么剪辑视频呢&#xff1f;在本篇文章…

竞赛 深度学习 机器视觉 车位识别车道线检测 - python opencv

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习 机器视觉 车位识别车道线检测 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满分5分) …

QTableWidget中cell 和 item区别

1.cell&#xff1a;某行某列中单元格。cell相当于一个容器&#xff0c;如箱子。里面不管有没有东西&#xff0c;cell都在那里。 2.item&#xff1a;item是某行某列单元格中的内容&#xff0c;即cell箱子中所放置的东西&#xff0c;即实实在在的东西。 通过调用 itemClicked()…

VMware虚拟机安装Linux教程(史上最全)

前言 许多想学网络安全的小伙伴&#xff0c;因为自己电脑是Windows系统的&#xff0c;并且电脑里面有很多重要文件&#xff0c;一般这种情况最好是安装一个虚拟机&#xff0c;然后虚拟机安装Linux的操作系统&#xff0c;这样就不会对原本的系统和文件产生影响。 需要网络安全…

云原生网关可观测性综合实践

作者&#xff1a;钰诚 可观测性 可观测性&#xff08;Observability&#xff09;是指系统、应用程序或服务的运行状态、性能和行为能够被有效地监测、理解和调试的能力。 随着系统架构从单体架构到集群架构再到微服务架构的演进&#xff0c;业务越来越庞大&#xff0c;也越来…

【Unity实战100例】Unity内部软键盘输入制作

目录 一. 样式颜色设置 二. UI逻辑 源码地址: 哔哩哔哩工房 一. 样式颜色设置 可以在预制体上提前设置一下对应组件的颜色,包括按键边框的颜色,内部填充色,普通按键文本颜色,功能按键文本颜色,大家可以根据自己的需求处理按钮逻辑。

基于PHP+laravel+vue自主研发的医院手术麻醉信息系统源码

大型医院AIMS手术麻醉信息系统全套成品源码 开发语言&#xff1a;PHP、 js 技术架构&#xff1a;mysqllaravelvue2 开发工具&#xff1a;oh-storm 前端框架&#xff1a;vue2 element 后端框架&#xff1a;laravel 数 据 库&#xff1a;mysql 8.0 手术麻醉临床信息系统…

【小余送书第三期】CTF/AWD竞赛标准参考书+实战指南:《AWD特训营》,参与活动,领书咯!

目录 一、背景介绍 二、内容简介 三、读者对象 四、本书目录 五、书籍概览 一、背景介绍 随着网络安全问题日益凸显&#xff0c;国家对网络安全人才的需求持续增长&#xff0c;其中&#xff0c;网络安全竞赛在国家以及企业的人才培养和选拔中扮演着至关重要的角色。 在数…

virtuoso如何导出def?

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 数模混合的项目中需要把PAD位置通过def的形式读入pr设计中,以此让power plan规避PAD的区域,避免DRC问题。 使用virtuoso导出def的流程如下: 1)新建一个空cell,在Library Manager-File-New-Cell…

(七)Python函数和lambda表达式

函数就是一段封装好的&#xff0c;可以重复使用的代码&#xff0c;它使得我们的程序更加模块化&#xff0c;不需要编写大量重复的代码。 函数可以提前保存起来&#xff0c;并给它起一个独一无二的名字&#xff0c;只要知道它的名字就能使用这段代码。函数还可以接收数据&#…