最近写博客需要插入一些截图,想着用DataURL会方便点,于是需要一个把图片转成DataURL的工具。搜索一番后发现这个功能用HTML就能实现,通过paste事件。


先尝试在Chrome上实现,Chrome版本 43.0

html<!DOCTYPE html>
<html>
<head></head>
<body>
<textarea id="result" style="width:800px; height:600px; resize:none"></textarea>
<script>
var body = document.getElementsByTagName('body')[0];
body.addEventListener('paste', function(e){
var clipboard = e.clipboardData;
var type = clipboard.items[0].type;
if (type.match(/image/)) {
var blob = clipboard.items[0].getAsFile();
var file = new FileReader();
file.addEventListener('loadend', function(e){
document.getElementById('result').value = e.target.result;
});
file.readAsDataURL(blob);
} else {
document.getElementById('result').value = "not an image\ntype: " + type + "\n\n";
}
});
</script>
</body>
</html>

给body添加一个paste事件,会在粘贴时触发,粘贴有关的信息都会随着e传入回调函数。e是一个ClipboardEvent,获取它的clipboardData,就可以通过一系列操作取出数据。

首先检查一下粘贴数据的类型,如果是图片则取出Blob对象,再用FileReader去读取,结果就是DataURL了。

如果不是图片,直接打印提示信息。

粘贴一段文本的效果:

这里需要注意的是,paste是在粘贴前触发的,所以文本会在提示信息打印后被粘贴到文本框里(粘贴的默认行为)。如果需要取消这种默认行为,可以用 e.preventDefault()


Chrome的代码在IE上完全无法工作,然后我找到了一个微软IE的粘贴图片的演示

这个演示很有意思,IE可以直接在“编辑器”里粘贴图片,而且这是由浏览器支持的,甚至不需要Javascript。

给div设置一个contenteditable属性之后,这个div就可以被任意编辑,在其中粘贴的图片会自动通过img标签显示,它的src就是我们要的DataURL,直接获取就可以了。

这个演示需要IE11(Edge),以下我写的也一样。

html<!DOCTYPE html>
<html>
<body>
<textarea id="result" style="width:800px; height:600px; resize:none"></textarea>
<div id="editor" contenteditable="true" style="border:1px solid #ccc">
paste here
</div>
</body>
<script>
var editor = document.getElementById('editor'); editor.addEventListener('paste', function(e){
console.log(e);
setTimeout("updateDivContent()", 0);
}); function updateDivContent(){
for (var i=0;i<editor.childNodes.length;i++) {
var node = editor.childNodes[i];
if(node.nodeName == "IMG"){
result = node.src;
}
}
for (var i=0;i<editor.childNodes.length;i++) {
editor.removeChild(editor.childNodes[i]);
}
document.getElementById('result').value = result;
}
</script>
</html>

这里传给paste回调的e实际上是个DragEvent,不过它没有包含粘贴的数据(dataTransfer是null),所以并没有什么用。

如果在回调里获取不到粘贴的数据,我们便需要在粘贴结束后,再去获取div里的img标签,因为粘贴的行为是在回调之后执行的。

这里我通过setTimeout实现在粘贴后执行函数,这种做法看上去很不靠谱(我不知道),不过微软那个例子里也有类似的写法。

在updateDivContent里,先获取img的src,然后清空div,再设置textarea来显示DataURL。


实际上呢IE这个例子有点舍本逐末的感觉,既然浏览器支持这样的特性,可以把div直接做成一个编辑器,这样就更方便了。

最后有一个疑问是,微软的例子里的Blob String到底是什么机制?看上去是把图片保存到了本地的某个位置,再用那一串字符串去索引?

最新文章

  1. Guava学习笔记:Immutable(不可变)集合
  2. Visual Studio: Show Solution Platform in Toolbar
  3. atitit.压缩算法 ZLib ,gzip ,zip 最佳实践 java .net php
  4. Xcode 插件失效的临时解决方案
  5. jquery+ajax(用ajax.dll)实现无刷新分页
  6. php 实现多线程
  7. android中广播接收SD卡状态
  8. Grafana关键表结构分析
  9. VMware虚拟机下安装CentOS6.5
  10. 连接H3C交换机的Console口连不上
  11. day11_python_1124
  12. js对象之window和document区别
  13. HDU 5288 OO&amp;rsquo;s Sequence
  14. 【Java】 剑指offer(29) 顺时针打印矩阵
  15. hibernate4 , spring3 使用 org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean 报错 Implementing class
  16. Python urllib模块学习
  17. 【软件】chrome设置默认字体
  18. IOS 创建简单表视图
  19. php设置文件类型content-type
  20. 【python 3.6】xlwt和xlrd对excel的读写操作

热门文章

  1. parquet和orc选型以及压缩格式
  2. Java:IO流(二)——InputStream/OutputStream具体用法:FileXXXStream、ByteArrayXXXStream
  3. 进程&amp;线程(三):外部子进程subprocess、异步IO、协程、分布式进程
  4. 【有奖调研】来,聊聊TTS音色定制这件事儿
  5. JZ-056-删除链表中重复的结点
  6. Python 细聊可以媲美 PS 的 PIL 图片处理库
  7. SpringBoot接入轻量级分布式日志框架(GrayLog)
  8. 25 面向对象编程 继承概念 代码 快捷键 super注意点
  9. 4月28日 python学习总结 线程与协程
  10. java对xml文件的操作