使用Javascript獲取剪貼板圖片的DataURL


最近寫博客需要插入一些截圖,想着用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到底是什么機制?看上去是把圖片保存到了本地的某個位置,再用那一串字符串去索引?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM