• 使用Javascript获取剪贴板图片的DataURL


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


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

    html<!DOCTYPE html>
    <html>
    <head></head>
    <body>
        <textarea id="result" style="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
    type: " + type + "
    
    ";
                }
            });
        </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="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到底是什么机制?看上去是把图片保存到了本地的某个位置,再用那一串字符串去索引?

  • 相关阅读:
    RocketMQ(十):数据存储模型的设计与实现
    常用sql语句
    配色方案
    WPF界面MahApps.Metro之应用
    使用 Zendesk maxwell 对接 kinesis (include producer and consumer)
    oracle报错【ORA-01017:用户名/口令无效;登录被拒绝】问题处理
    oracle报错【ORA-28000:帐户已被锁定】问题处理
    $(window).load(function(){})和$(document).ready(function(){})的区别
    HttpClientFactory 结合 Polly 轻松实现重试机制
    ocelot 中间件的变化
  • 原文地址:https://www.cnblogs.com/10manongit/p/12974046.html
Copyright © 2020-2023  润新知