圖片粘貼上傳

圖片粘貼上傳场晶,大家基本都司空見慣了诗轻,不足為奇。(本文只是水記一下扳炬,有空深挖細耕)

某日產(chǎn)品大大發(fā)話:

  • 某:“這個沖賬憑證上傳恨樟,能加個圖片粘貼上傳功能嗎?”
  • 我(凡事一句):“為什么缩多?”
  • 某:“理由是:用戶覺得,截個屏 > 保存到本地 > 選擇這個文件上傳衬吆,太麻煩逊抡。直接截圖上傳,省事冒嫡〉埔ィ”
  • 我(無力反駁):“哦,我試試峻呛」家ぃ”

由于用的 iView,先去扒扒有沒有 API 提供牙勘。文檔沒有所禀,圍觀源碼,欸恭金,居然寫了這么一段代碼褂策,upload.vue#L7

...
@paste="handlePaste"
...
...
handlePaste (e) {
  if (this.paste) {
    this.uploadFiles(e.clipboardData.files);
  }
}
...

但是斤寂,為什么凡事都有個但是?人家還沒發(fā)布 releases...

這種類似的功能罗侯,網(wǎng)上搜羅也一大堆溪猿。哎呦喂蒂培,挺簡單的护戳,監(jiān)聽 paste 事件垂睬,獲取 event 里面的內容就行了。擼起袖子就是干钳枕,照著源碼畫葫蘆赏壹。
分分鐘就搞定了,圖片也能上傳昔瞧。然鵝菩佑,為什么可粘貼區(qū)域這么詭異...

看來 iView 那個也是個半成品稍坯,我還是扶墻好了

開始去 MDN 看 paste ,結果寥寥幾字混巧,沒什么參考性勤揩。
梅西表示,我現(xiàn)在慌的一匹...

順著摸到 W3 的 clipboard-event-paste
...
The paste action has no effect in a non-editable context, but the paste event fires regardless.
...

表示并沒怎么看懂這段英文...

所以缠犀,大致意思是,不可編輯的元素辨液,無效滔迈?加個屬性試試:

<div contenteditable="true" @paste="pasteHandler" ></div>

嗯被辑,現(xiàn)在敬惦,只有點擊這個 div 才會觸發(fā)這個 paste 事件。
但是宏怔,但是畴椰,同時也帶來了用戶可以隨意輸入斜脂、編輯、粘貼任何內容的問題......

我的內心玷或,時而堅強销斟,時而奔潰...

然后蚂踊,我想了個搓的方式:

  • 字體設置為 0
  • 子元素 display: none
  • 子元素字體大小為 0
.paste {
        overflow: hidden;
        height: 140px;
        font-size: 0;
        line-height: 140px;
        text-align: center;
        border: 1px dashed #dddee1;
        background-color: #fff;

        /deep/ * {
            display: none !important;
            font-size: 0 !important;
        }

        &:after {
            display: inline-block;
            font-size: 12px;
            content: "點擊,粘貼圖片上傳";
        }
    }

這種方式棱诱,就是不顯示給你看涝动,倒是非常不優(yōu)雅的解決了。

不過本身這種交互方式靡菇,就感覺怪怪的:

  • 點擊一個區(qū)域
  • Ctrl + V 粘貼圖片
  • 上傳

暫且這樣吧米愿,目前木有想到更好的方式。

待我發(fā)了個測試版后较鼓,發(fā)現(xiàn) FireFox 4.x 不支持博烂。
經(jīng)測測試,paste 事件有響應畜伐。但是 event 里面谆级,files 為空,啊哈哈哈...

偶然發(fā)現(xiàn)脚仔,其實舆绎,瀏覽器插入富文本到里面了:

再回想到 W3 的 clipboard-event-paste
...
If the cursor is in an editable context, the paste action will insert clipboard data in the most suitable format (if any) supported for the given context.
...

再讀一遍 ...in the most suitable format ...

怎么辦呢吕朵?

  • 獲取 img 元素
  • 讀取 base64
  • base64 轉 Blob
  • Blob 轉 File
  • 上傳
base64toBlob (base64Data) {
    let byteString

    if (base64Data.split(',')[0].indexOf('base64') >= 0) {
        byteString = atob(base64Data.split(',')[1])
    } else {
        byteString = unescape(base64Data.split(',')[1])
    }

    const mimeString = base64Data.split(',')[0].split(':')[1].split(';')[0]
    const ia = new Uint8Array(byteString.length)

    for (let i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i)
    }

    return new Blob([ia], {type:mimeString})
},
hackForFireFox () {
    // 等待 dom 更新
    this.$nextTick(() => {
        const $img = this.$refs.paste.querySelector('img')

        if (!$img) {
            return
        }

        const base64Data = $img.getAttribute('src')
        const blob = this.base64toBlob(base64Data)
        const file = new File([blob], 'image.png')

        this.$refs.paste.innerHTML = '' // 清空上傳的圖片
        this.$refs.upload.uploadFiles([file])
    })
},
// 粘貼事件處理
pasteHandler (e) {
    // 如果配置了運行粘貼上傳
    if (this.paste) {
        // 高版本瀏覽器努溃,能直接拿到 files
        // 我司不考慮 IE,故未兼容處理
        if (e.clipboardData.files.length > 0) {
            this.$refs.upload.uploadFiles(e.clipboardData.files)
        } else {
            // 否則沦疾,嘗試讀取富文本
            this.hackForFireFox()
        }
    }
}

總結

不是很好的解決方式第队,踩了幾個坑,算是個思路吧忆畅。后面有新想法尸执,再補上如失。

其實,我的內心岖常,是不接受這種方式的...

—— 2018/07/31 By Vinci竭鞍, Partly Cloudy.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市冯乘,隨后出現(xiàn)的幾起案子晒夹,更是在濱河造成了極大的恐慌,老刑警劉巖喷好,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梗搅,死亡現(xiàn)場離奇詭異效览,居然都是意外死亡,警方通過查閱死者的電腦和手機哆键,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進店門瘦锹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來沼本,“玉大人,你說我怎么就攤上這事抽兆”韬欤” “怎么了?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵切油,是天一觀的道長名惩。 經(jīng)常有香客問我,道長攻谁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任个曙,我火速辦了婚禮受楼,結果婚禮上艳汽,老公的妹妹穿的比我還像新娘。我一直安慰自己骚灸,他們只是感情好,可當我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著丈钙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪劫笙。 梳的紋絲不亂的頭發(fā)上星岗,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天俏橘,我揣著相機與錄音,去河邊找鬼靴寂。 笑死召耘,一個胖子當著我的面吹牛,可吹牛的內容都是我干的污它。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼虫埂,長吁一口氣:“原來是場噩夢啊……” “哼圃验!你這毒婦竟也來了缝呕?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎栈暇,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體煎源,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡香缺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年图张,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兽埃。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡柄错,死狀恐怖痪蝇,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情躏啰,我是刑警寧澤给僵,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布详拙,位于F島的核電站蔓同,受9級特大地震影響,放射性物質發(fā)生泄漏斑粱。R本人自食惡果不足惜弃揽,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望则北。 院中可真熱鬧矿微,春花似錦、人聲如沸尚揣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽快骗。三九已至娜庇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間方篮,已是汗流浹背名秀。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工藕溅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留泰偿,地道東北人。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓蜈垮,卻偏偏與公主長得像耗跛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子攒发,可洞房花燭夜當晚...
    茶點故事閱讀 44,955評論 2 355

推薦閱讀更多精彩內容