问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

(C++)如何用代码实现粘贴功能

发布网友 发布时间:2022-04-23 00:53

我来回答

3个回答

懂视网 时间:2022-05-15 07:56

这次给大家带来vue-simplemde实现图片拖拽粘贴功能(附代码),vue-simplemde实现图片拖拽粘贴功能的注意事项有哪些,下面就是实战案例,一起来看一下。

项目使用的是vue框架,需要一个markdown的编辑框,就在npm上找了一下,发现simplemde挺不错的,由于我比较懒,就顺便在npm又搜了一下,找到了vue-simplemde这个 package ,那就开始使用它吧。

但是这个 vue-simplemde 不支持图片拖拽上传、粘贴上传,也不能说是因为这个 vue-simplemde ,因为 vue-simplemde 只是对 simplemde 的基础上封装成一个Vue插件。所以最后还是由于 simplemde 没有提供相关的功能,但是为了用户体验考虑,这个功能时必要的,除非不使用markdown编辑器。而去使用富文本编辑器,那样的话,项目很多的代码都要进行更改。所以就在网上查了文章,及在github上查了一些代码。下面将进行分析

拖拽

拖拽的API核心是 drop 这个事件,就是当我们从桌面拖动一个文件到浏览器里时,松开的时候,而触发的事件名。

我们都知道,你随便拖动一个图片到浏览器里,会直接打开这个图片,这是因为浏览器默认你拖动文件到浏览器里时,将打开这个文件,所以,我们需要阻止原生的操作。

我们现在先写一段代码,让其屏蔽掉默认事件

window.addEventListener("drop", e => {
 e = e || event
 if (e.target.className === 'CodeMirror-scroll') { // 如果进入到编辑器的话,将阻止默认事件
 e.preventDefault()
 }
}, false)

CodeMirror-scroll 这个Class就是 simplemde 编辑框的Class名称。

现在我们拖拽文件到这个编辑框,然后松掉,不会出现任何反应。如果在编辑框之外的地方,还是会继续触发默认事件。

下面就是获取 simplemde 方法,给他 drop 事件处理方法。

// 假设页面一共有三个编辑窗口,所以需要循环监听事件
[ this.$refs.simplemde1,
 this.$refs.simplemde2,
 this.$refs.simplemde3
].map(({simplemde}) => {
 simplemde.codemirror.on('drop', (editor, e) => {
 if (!(e.dataTransfer && e.dataTransfer.files)) {
 // 弹窗说明,此浏览器不支持此操作
 return
 }
 let dataList = e.dataTransfer.files
 let imageFiles = [] // 要上传的文件实例数组
 // 循环,是因为可能会同时拖动几个图片文件
 for (let i = 0; i < dataList.length; i++) {
 // 如果不是图片,则弹窗警告 仅支持拖拽图片文件
 if (dataList[i].type.indexOf('image') === -1) {
 // 下面的continue,作用是,如果用户同时拖动2个图片和一个文档,那么文档不给于上传,图片照常上传。
 continue
 }
 imageFiles.push(dataList[i]) // 先把当前的文件push进数组里,等for循环结束之后,统一上传。
 }
 // uploadImagesFile方法是上传图片的方法
 // simplemde.codemirror的作用是用于区分当前的图片上传是处于哪个编辑框
 this.uploadImagesFile(simplemde.codemirror, imageFiles)
 // 因为已经有了下面这段代码,所以上面的屏蔽默认事件代码就不用写了
 e.preventDefault()
 })
})

诈一看,代码好像有点多,那是因为注释的原因,下面是没有注释的代码。你可以根据下面的代码,有自己的见解和理解:

[ this.$refs.simplemde1,
 this.$refs.simplemde2,
 this.$refs.simplemde3
].map(({simplemde}) => {
 simplemde.codemirror.on('drop', (editor, e) => {
 if (!(e.dataTransfer && e.dataTransfer.files)) {
 return
 }
 let dataList = e.dataTransfer.files
 let imageFiles = []
 for (let i = 0; i < dataList.length; i++) {
 if (dataList[i].type.indexOf('image') === -1) {
 continue
 }
 imageFiles.push(dataList[i])
 }
 this.uploadImagesFile(simplemde.codemirror, imageFiles)
 e.preventDefault()
 })
})

粘贴

粘贴的API是 paste 方法,这个不像上面一样,粘贴不需要禁止默认事件,因为我们可以看到,你复制一个图片,到浏览器里按下 ctrl+v 的时候,是不会发生任何变化的,所以没用必要禁止默认事件。

下面是代码:

simplemde.codemirror.on('paste', (editor, e) => { // 粘贴图片的触发函数
 if (!(e.clipboardData && e.clipboardData.items)) {
 // 弹窗说明,此浏览器不支持此操作
 return
 }
 try {
 let dataList = e.clipboardData.items
 if (dataList[0].kind === 'file' && dataList[0].getAsFile().type.indexOf('image') !== -1) {
 this.uploadImagesFile(simplemde.codemirror, [dataList[0].getAsFile()])
 }
 } catch (e) {
 // 弹窗说明,只能粘贴图片
 }
})

之所以这里写上 try...catch 方法,是因为如果你粘贴的时候,如果是一个文件, items 将是空的,而在下面的if循环里,使用 dataList[0].kind 。也就是 e.clipboardData.items[0].kind 。当 item 为空时,还去访问一个不存的 kind 属性时,就会报错了。所以这里需要使用 try...catch 方法进行判断。

dataList[0].getAsFile().type.indexOf('image') !== -1 这个句话是判断,粘贴的东西确认是图片,而不是其他东西。

if 里的上传图片,不一样的地方是 [dataList[0].getAsFile()] ,因为为了统一格式,方便 uploadImagesFile 函数进行处理,我加上了 [] ,使之成为数组。 dataList[0].getAsFile() 就是获取文件实例了。

上传

上传就有一点麻烦了:

uploadImagesFile (simplemde, files) {
 // 把每个文件实例使用FormData进行包装一下,然后返回一个数组
 let params = files.map(file => {
 let param = new FormData()
 param.append('file', file, file.name)
 return param
 })
 let makeRequest = params => {
 return this.$http.post('/Api/upload', params)
 }
 let requests = params.map(makeRequest)
 this.$http.spread = callback => {
 return arr => {
 return callback.apply(null, arr)
 }
 }
 // 服务端返回的格式是{state: Boolean, data: String}
 // state为false时,data就是返回的错误信息
 // state为true时,data是图片上传后url地址,这个地址是针对网站的绝对路径。如下:
 // /static/upload/2cfd6a50-3d30-11e8-b351-0d25ce9162a3.png
 Promise.all(requests)
 .then(this.$http.spread((...resps) => {
 for (let i = 0; i < resps.length; i++) {
 let {state, data} = resps[i].data
 if (!state) {
 // 弹窗显示data的错误信息
 continue
 }
 let url = `![](${location.origin + data})` // 拼接成markdown语法
 let content = simplemde.getValue()
 simplemde.setValue(content + url + '
') // 和编辑框之前的内容进行拼接
 }
 }))
}

因为我是把 axiox 封装成vue插件来使用,这样会导致, this.$http 是实例化后的,而不是他本身。 axios 维护者说的解决方案是,重新引入 axios 包,来使用。但是我觉得没有必要。 axios.all 内部是 Promise.all 。 axios.spread 实现代码比较少,就直接拿过来,重新赋值给 axios 就好了

所以上面有段代码是

Promise.all(requests)
 .then(this.$http.spread((...resps) => {
 // code
 })

把这段代码翻译一下就是

axios.all(requests)
 .then(axios.spread((...resps) => {
 // code
 })

关于这个问题,请看下官方的解释:axios-all-is-not-a-function-inside-vue-component 。也可以看下 axios 的代码: axios.js#L45-L48

这个问题,暂时就不深究了,我们回到刚刚的话题上。

上面我说到当state为true时,data是文件相对于网站的绝对路径,如: /static/upload/2cfd6a50-3d30-11e8-b351-0d25ce9162a3.png

相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!

推荐阅读:

jQuery编码转化base64通过AJAX上传

vue组件写法规范

热心网友 时间:2022-05-15 05:04

如果那样,还要知道程序什么时候开始复制并粘贴到编辑光标的后面.必须告诉程序什么时候开始粘贴的消息.
模拟键盘:
SendMessage(....WM_KEYDOWN..."ctrl+C"....);
SendMessage(....WM_KEYUP....);
SendMessgae(.....WM_KEYDOWN..."ctrl+V".....);
SendMessgae(.....WM_KETUP....);

热心网友 时间:2022-05-15 06:22

好象应该是
SendMessage( WM_HOTKEY.... )
直接发送这些消息好象是没有用的
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
石璜镇历史演变 ...突突的声音,排气管还冒黑烟,有时走也是走走停停的, 我手机型号步步高V206的,手机的内存U盘显示以满但我查看了手机,手机里 ... 步步高v206,我想下载手机英语,希望各位指点指点,哪里有下载,下载后具体... 步步高V206B手机怎么下载java软件 如何通过化妆修饰不同脸型和鼻型? 最近我的手机总是莫名收到一条短信,说的SIM卡已被更换,这是怎么... 丈母娘和女婿什么相处模式最和谐? 女婿怎么跟岳父岳母搞好关系? 诛仙2中宠物怎样恢复到绑定前 java 代码实现复制粘粘功能,详细细节如图,我自己写了一段代码,搞了半天没搞好。 复制和粘贴的代码要怎么写 我的世界命令方块的代码,怎样粘贴和复制? 怎么样查询苹果手机是不是正品 过期的茶叶能喝么? 茶叶放时间久了会不会过期?还能喝么? 茶叶过期6个月可以喝吗? 茶叶过期还能喝吗 茶叶过期能不能喝 请问茶叶过期可以喝吗 过期的茶还能喝吗 茶叶过期还能喝吗? 茶叶过期了,还能喝吗 茶过期之后还可以喝吗 武汉可以用车到银行做抵押贷款吗? 武汉按揭车不押车贷款能做吗 武汉汽车抵押贷款不押车是真的吗 武汉如何办理车辆抵押贷款? 武汉那家货款公司对征信要求不高 武汉汽车抵押贷款需要的手续有哪些? C# 窗体程序中怎样用代码实现复制、粘贴、剪切 excel vba 如何使用for循环复制粘贴 c#窗体程序文件的复制拷贝粘贴功能?求详细的代码 怎么用vba把vba代码复制粘贴 怎么用html代码复制 中国最好的中学? 如何将复制的HTML代码粘贴到自己的网页上 南阳市最好的初中是哪个? 青岛市北区比较好的初中有哪些? 绝地求生怎么复制粘贴代码 邯郸最好的初中是哪个? excel复制粘贴代码 衡阳哪些初中是比较好的? 按键精灵如何向我们复制和粘贴,要代码。谢谢 沈阳哪个初中学校比较好? 2020王者空白代码怎么复制粘贴? 山东聊城那所中学(初中)比较不错! EXCEL如何实现使用代码让特定单元格复制-粘贴为数值 天津比较好的初中有哪些? 如何将复制的HTML代码粘贴到自己的网页上?