免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
復(fù)制粘貼的高級(jí)玩法

  想做一個(gè)好用的在線(xiàn)編輯器,不管是地圖編輯器、PPT創(chuàng)作平臺(tái)還是通過(guò)拖拽快速創(chuàng)建活動(dòng)頁(yè)面的編輯器等等,必然要給用戶(hù)提供各種快捷的操作方法。如非常常用的復(fù)制粘貼功能。

舉個(gè)例子,在iPresst創(chuàng)作平臺(tái),我們的作品在好幾頁(yè)都要用到同一張圖片,總不能每次都點(diǎn)擊上傳一次圖片吧?右鍵復(fù)制粘貼或者直接按快捷鍵無(wú)疑是最符合用戶(hù)預(yù)期的操作方式,然而我們編輯器用到的元素一般比較特別,而且我們復(fù)制粘貼的時(shí)候經(jīng)常要做一些特殊處理,此時(shí)我們就需要覆蓋瀏覽器給我們提供的復(fù)制粘貼功能了。

實(shí)現(xiàn)的原理也挺簡(jiǎn)單:

方法1:監(jiān)聽(tīng)鍵盤(pán)事件

document.addEventListener('keydown', function(e){
	if(e.ctrlKey) {
		switch(e.keyCode) {
			case 88:
				console.log('Ctrl + X, cutting');
				break;
			case 67:
				console.log('Ctrl + C, copying');
				break;
			case 86:
				console.log('Ctrl + V, pasting');
				break;
			default:
		}
	}
}, false);

此時(shí)我們要覆蓋掉瀏覽器的默認(rèn)右鍵菜單,不然快捷鍵和右鍵菜單的復(fù)制粘貼操作效果不一致。這并不奇怪,一般的稍復(fù)雜的編輯器都有定制自己的右鍵菜單。

document.addEventListener('contextmenu', function(e){
	e.preventDefault();
	console.log('show my context menu');
}, false);

方法2:直接覆蓋剪切復(fù)制粘貼事件

document.addEventListener('cut', function(e){
	e.preventDefault();
	console.log('Ctrl + X, cutting');
}, false);
document.addEventListener('copy', function(e){
	e.preventDefault();
	console.log('Ctrl + C, copying');
}, false);
document.addEventListener('paste', function(e){
	e.preventDefault();
	console.log('Ctrl + V, pasting');
}, false);

如此我們就可以定制我們編輯器的特色復(fù)制粘貼功能。

(完)

 

開(kāi)玩笑,如果就這樣結(jié)束那也太水了,前面那些只是鋪墊,鋪墊,咳咳。

上面的代碼只是實(shí)現(xiàn)了編輯器的內(nèi)部元素復(fù)制粘貼的閉環(huán),那來(lái)自外部的元素呢?如別的地方拷貝的一段文本,如用QQ截了一張圖,能否直接粘貼在我們的編輯器生成特有的文本元素、圖片元素?

這就是接下去要講的高級(jí)玩法,Clipboard API。

其實(shí)訪(fǎng)問(wèn)剪貼板的數(shù)據(jù)這并不新鮮,早在多年前IE就支持了,我們可以通過(guò)下面的方式訪(fǎng)問(wèn):

window.clipboardData.clearData();  
window.clipboardData.setData('Text', 'abcd');
// window.clipboardData.setData('Text');

但這種接口注定淪為歷史的塵埃。為什么?不安全!如果用戶(hù)打開(kāi)一個(gè)網(wǎng)頁(yè),在他不知不覺(jué)中JavaScript就訪(fǎng)問(wèn)了系統(tǒng)剪貼板的數(shù)據(jù),然后上傳到服務(wù)器或者做各種猥瑣的操作,那用戶(hù)會(huì)泄露多少的隱私。所以在新的瀏覽器如chrome是不支持這種接口的,一般情況下js代碼是訪(fǎng)問(wèn)不到系統(tǒng)的剪貼板,我們?cè)诰W(wǎng)上看到的點(diǎn)擊復(fù)制網(wǎng)址之類(lèi)的功能,基本都是用Flash來(lái)實(shí)現(xiàn)。

那如果用戶(hù)點(diǎn)擊了瀏覽器右鍵菜單的復(fù)制粘貼或按下相應(yīng)快捷鍵,此時(shí)訪(fǎng)問(wèn)剪貼板就合理了,而瀏覽器確實(shí)是這么做的。前面提到的方法1監(jiān)聽(tīng)鍵盤(pán)事件是不行的,此時(shí)必須使用方法2,我們可以通過(guò)下面代碼獲取到剪貼板里的圖片或者文本:

document.addEventListener('paste', function(e){
    var clipboard = e.clipboardData;
    // 有無(wú)內(nèi)容
    if(!clipboard.items || !clipboard.items.length){
        clear();
        return;
    }
    
    var temp;
    if((temp = clipboard.items[0]) && temp.kind === 'file' && temp.type.indexOf('image') === 0){
        // 獲取圖片文件
        var imgFile = temp.getAsFile();
        // TODO: 做愛(ài)做的事
    } else if(temp = clipboard.getData('text/plain')){
        // 將文本預(yù)格式化
        var splitList = temp.split(//n/);
        temp = '';
        for(var i = 0, len = splitList.length; i < len; i++){
            temp += splitList[i].replace(//t/g, '    ')
                .replace(/ /g, ' ') + '<br>';
        }
        // TODO: 做愛(ài)做的事
    }
}, false);

要注意兩個(gè)小點(diǎn),第一,我們通過(guò)上面獲取到的圖片文件是一個(gè)file對(duì)象,這跟我們從一個(gè) type=file 的上傳文件節(jié)點(diǎn)監(jiān)聽(tīng)change事件,通過(guò) e.target.files[0] 拿到的file對(duì)象是一樣的(之所以監(jiān)聽(tīng)change是為了實(shí)現(xiàn)選擇文件即時(shí)上傳的效果不用額外點(diǎn)擊上傳按鈕)。從file對(duì)象中可以獲取到圖片的base64編碼:

var reader = new FileReader();
reader.onload = function(e){
    var src = e.target.result;
    // Todo
};
reader.readAsDataURL(imgFile);

file對(duì)象中還可以獲取到文件類(lèi)型等信息,大家想更深入了解可以搜索 e.target.files 。

第二個(gè)要注意的點(diǎn)是從剪貼板獲取到的文本是系統(tǒng)格式的,如果我們不做處理直接通過(guò)類(lèi)似 innerHTML 的方法使用,會(huì)導(dǎo)致?lián)Q行丟失等顯示問(wèn)題。

Ok,大家可以在iPresst的編輯創(chuàng)作頁(yè)面體驗(yàn)效果,QQ截完圖可以直接粘貼進(jìn)來(lái)的感覺(jué)就是爽!

但是這時(shí)候有另外一個(gè)問(wèn)題,怎么保持內(nèi)部元素的復(fù)制和外部元素復(fù)制的統(tǒng)一?簡(jiǎn)單講,我在編輯器里面復(fù)制了我的特有元素,此時(shí)系統(tǒng)的剪貼板不管有什么都應(yīng)該被覆蓋,反之亦然,我在編輯器里面復(fù)制一個(gè)特有元素,然后在別的地方復(fù)制了一段文本,那此時(shí)我在編輯器里面粘貼應(yīng)該是粘貼這段文本而不是粘貼之前的特有元素。

要做到這一點(diǎn),只要處理好兩個(gè)事情:在編輯器里剪切復(fù)制的時(shí)候覆蓋剪貼板、在編輯器里粘貼時(shí)區(qū)分要粘貼的是內(nèi)部元素還是外部元素。程序員嘛,直接上代碼:

var defaultText = 'iPresst,一個(gè)性感的網(wǎng)站';
document.addEventListener('paste', function(e){
    e.clipboardData.setData('text/plain', defaultText);
    e.clipboardData.setData('text/ipresst', 'ipresst');
    eventType = 'cut';
    // TODO: 獲取要剪切的內(nèi)部元素
}, false);
document.addEventListener('paste', function(e){
    e.clipboardData.setData('text/plain', defaultText);
    e.clipboardData.setData('text/ipresst', 'ipresst');
    eventType = 'copy';
    // TODO: 獲取要復(fù)制的內(nèi)部元素
}, false);
document.addEventListener('paste', function(e){
    var clipboard = e.clipboardData;
    // 有無(wú)內(nèi)容
    if(!clipboard.items || !clipboard.items.length){
        clear();
        return;
    }
    // 先區(qū)分是內(nèi)部粘貼還是外部粘貼
    if(clipboard.getData('text/ipresst') === 'ipresst'){
        if(!eventType || !elList.length){
            // TODO: 清空標(biāo)志位
            return;
        }
        // 粘貼
        if(eventType === 'cut') {
            // TODO: 剪切粘貼
        } else {
            // TODO: 復(fù)制粘貼
        }
    } else {
        var temp;
        // ……
        // 此處略去N行前面貼過(guò)的代碼
    }
}, false);

我們?cè)诩糍N板里面設(shè)置了我們的特色數(shù)據(jù) text/ipresst ,如果用戶(hù)在其他地方剪切復(fù)制了東西,剪貼板會(huì)被清空這個(gè)標(biāo)志位就不存在,所以可以用來(lái)區(qū)分內(nèi)部粘貼和外部粘貼。而這行代碼

e.clipboardData.setData('text/plain', defaultText);

則讓我們復(fù)制了內(nèi)部元素然后在外面如QQ聊天窗口粘貼時(shí)(顯然在聊天窗口沒(méi)法粘貼我們編輯器的內(nèi)部特有元素),貼出文本:iPresst,一個(gè)性感的網(wǎng)站。so cool!

此時(shí)我們內(nèi)部和外部的閉環(huán)就打通了。只是很遺憾地,為了保持交互邏輯的一致性,我不得不把iPresst的自定義右鍵菜單中剪切、復(fù)制、粘貼這幾項(xiàng)去掉,因?yàn)辄c(diǎn)擊事件沒(méi)法訪(fǎng)問(wèn)到剪貼板對(duì)象(只有cut/copy/paste可以訪(fǎng)問(wèn)到),也就說(shuō)沒(méi)法粘貼外部元素,和按下快捷鍵的表現(xiàn)是不一致的。這一點(diǎn)沒(méi)有更好的解決方案,當(dāng)然你放棄自定義右鍵菜單就不會(huì)有這個(gè)問(wèn)題。

或許有人會(huì)說(shuō):那我們可以點(diǎn)擊右鍵菜單的復(fù)制粘貼時(shí),通過(guò) execCommand 或者模擬鍵盤(pán)事件來(lái)觸發(fā)cut、copy、paste事件,那不就可以訪(fǎng)問(wèn)到剪貼板了?我只能說(shuō):朋友,你想多了。那樣會(huì)跟前面討論的IE的接口一樣,有安全風(fēng)險(xiǎn)的,我自測(cè)過(guò)在chrome是行不通的。在caniuse.com上面也是這樣寫(xiě):

至此,復(fù)制粘貼的高級(jí)玩法講完了,雖說(shuō)還有點(diǎn)小不滿(mǎn)意的點(diǎn),但還是一個(gè)比較推薦的實(shí)用性挺高的實(shí)踐。

(完)

 

(真的完了)

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
ZeroClipboard支持IE,firefox,Chrome復(fù)制到剪貼板
[轉(zhuǎn)載]使用ZeroClipboard解決跨瀏覽器復(fù)制到剪貼板的問(wèn)題
7款裝機(jī)必備技術(shù)神器,相見(jiàn)恨晚的黑
用純JavaScript實(shí)現(xiàn)“復(fù)制到剪貼板”功能01
監(jiān)視剪切版
delphi 獲取剪貼板圖像
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服