Laravel項(xiàng)目中使用markdown編輯器及圖片粘貼上傳七牛云

本文為轉(zhuǎn)載蜜唾,原文:Laravel項(xiàng)目中使用markdown編輯器及圖片粘貼上傳七牛云

Markdown

Markdown是一種可以使用普通文本編輯器編寫的標(biāo)記語言哪痰,通過簡單的標(biāo)記語法行冰,它可以使普通文本內(nèi)容具有一定的格式姜胖。
本次我們選用的編輯器是: Editor.md朴艰,官網(wǎng)中也有很詳細(xì)的介紹法焰。從官網(wǎng)中下載安裝


下載的內(nèi)容中怎炊,也有很多demo可以借鑒谭企。
在下載的包中,去除一些多余的內(nèi)容评肆,只保留我們需要的內(nèi)容赞咙,然后加到項(xiàng)目的public目錄下,如下圖紅色框內(nèi)的內(nèi)容:

項(xiàng)目中使用

在項(xiàng)目中使用editor.md編輯內(nèi)容時(shí)糟港,首先要先在blade模板中添加相對應(yīng)的引用攀操,css的引用如下:

<link rel="stylesheet" href="{{asset('editormd/editormd.min.css')}}">

js的引用如下:

<script src="{{asset('editormd/editormd.min.js')}}" type="text/javascript"></script>

然后在html中添加以下代碼,作為編輯器區(qū)域秸抚。

<div id="myeditormd">
    <textarea style="display:none;"></textarea>
</div>

最后在添加js代碼速和,加載出editor.md:

<script type="text/javascript">
        var testEditor;
        $(function () {
            testEditor = editormd("myeditormd",{
                width:"100%",
                height:600,
                syncScrolling:"single",
                taskList : true,
                tocm: true,
                path:"{{asset('/editormd/lib/')}}" + "/",
                tex:true,
                flowChart       : true,
                sequenceDiagram:true,
                saveHTMLToTextarea : true,
                imageUploadURL: "php/upload.php",
            });
        });
</script>

相關(guān)參數(shù)含義:

saveHTMLToTextarea: 保存 HTML 到 Textarea
tex: 科學(xué)公式TeX語言支持,默認(rèn)關(guān)閉
flowChart: 流程圖支持剥汤,默認(rèn)關(guān)閉
sequenceDiagram: 時(shí)序/序列圖支持颠放,默認(rèn)關(guān)閉
toolbar: 工具欄,默認(rèn)開啟
watch: 實(shí)時(shí)預(yù)覽吭敢,默認(rèn)開啟

如此碰凶,便可完整的加載出編輯器了。效果如下圖:



其中還有些比較重要的js方法。

testEditor.gotoLine(90);//跳轉(zhuǎn)至第90行
testEditor.show();//顯示編輯器
testEditor.hide;//隱藏編輯器
testEditor.getMarkdown();//獲取markdown代碼
testEditor.getHTML();//獲取markdown解析后的html代碼
testEditor.watch();//開啟實(shí)時(shí)預(yù)覽
testEditor.unwatch();//關(guān)閉實(shí)時(shí)預(yù)覽
testEditor.previewing();//預(yù)覽
testEditor.fullscreen();//全屏
testEditor.showToolbar();//顯示工具欄
testEditor.hideToolbar();//隱藏工具欄

在編輯器中編輯完內(nèi)容后欲低,一般情況下辕宏,保存的是markdown標(biāo)記。但是如何解析已保存的markdown標(biāo)記呢砾莱。

markdown解析

添加以下引用:

//css引用
<link rel="stylesheet" href="{{asset('editormd/editormd.min.css')}}">
//js引用
<script src="{{asset('editormd/editormd.min.js')}}" type="text/javascript"></script>
<script src="{{asset('editormd/lib/marked.min.js')}}"></script>
<script src="{{asset('editormd/lib/prettify.min.js')}}"></script>
<script src="{{asset('editormd/lib/raphael.min.js')}}"></script>
<script src="{{asset('editormd/lib/underscore.min.js')}}"></script>
<script src="{{asset('editormd/lib/sequence-diagram.min.js')}}"></script>
<script src="{{asset('editormd/lib/flowchart.min.js')}}"></script>
<script src="{{asset('editormd/lib/jquery.flowchart.min.js')}}"></script>

然后在html中添加解析的區(qū)域

<div id="show_editor">
    <textarea style="display: none">{{$article->content}}</textarea>
</div>

其中{{$article->content}}為數(shù)據(jù)庫中讀取的已保存的markdown標(biāo)記瑞筐。
最后再添加響應(yīng)的js代碼,便可完美解析了腊瑟。

<script type="text/javascript">
    $(function() {
        var testEditormdView;
        testEditormdView = editormd.markdownToHTML("show_editor", {
            htmlDecode      : "style,script,iframe",  // you can filter tags decode
            emoji           : true,
            taskList        : true,
            tex             : true,  // 默認(rèn)不解析
            flowChart       : true,  // 默認(rèn)不解析
            sequenceDiagram : true,  // 默認(rèn)不解析
        });
    });
</script>

解析后的效果如下圖:


圖片粘貼上傳

首先分析一下實(shí)現(xiàn)步驟:

  1. QQ截圖后在編輯器中粘貼聚假,肯定會有一個(gè)粘貼事件,即 paste 事件
  2. 在事件回調(diào)函數(shù)中對前端進(jìn)行圖片的一次壓縮
  3. 前端壓縮多是使用canvas闰非,返回的是base64膘格,這里我使用了一個(gè) localResizeIMG.js的插件
  4. 將生成好的base64傳給后臺,后臺可以進(jìn)行圖片的第二次壓縮财松,但是感覺沒必要
  5. 后臺先得到七牛云的upToken闯袒,即一個(gè)上傳的憑證,然后執(zhí)行七牛sdk提供的上傳函數(shù)

paste事件

截圖之后游岳,在富文本編輯器中右鍵黏貼或者CTRL V就會觸發(fā)這個(gè)事件,這個(gè)事件有一個(gè)clipboardData屬性其徙。我們需要使用js代碼監(jiān)聽paste事件胚迫,并獲取clipboardData屬性,代碼如下:

        function paste(event) {
            var clipboardData = event.clipboardData;
            var items, item, types;
            if (clipboardData) {
                items = clipboardData.items;
                if (!items) {
                    return;
                }
                // 保存在剪貼板中的數(shù)據(jù)類型
                types = clipboardData.types || [];
                for (var i = 0; i < types.length; i++) {
                    if (types[i] === 'Files') {
                        item = items[i];
                        break;
                    }
                }
                // 判斷是否為圖片數(shù)據(jù)
                if (item && item.kind === 'file' && item.type.match(/^image\//i)) {
                    // 讀取該圖片
                    var file = item.getAsFile(),
                            reader = new FileReader();
                    reader.readAsDataURL(file);
                    reader.onload = function () {
                        //前端壓縮
                        lrz(reader.result, {width: 1080}).then(function (res) {
                            $.ajax({
                                url: "{{asset('php-sdk/myapis/uploadImageToQiliu.php')}}",
                                type: 'post',
                                data: {
                                    "image": res.base64,
                                    "name": new Date().getTime() + ".png"
                                },
                                contentType: 'application/x-www-form-urlencoded;charest=UTF-8',
                                success: function (data) {
                                    var imageName;
                                    try {
                                        imageName = JSON.parse(data).key;
                                    } catch (e) {
                                        alert(e.toString);
                                    }

                                    var qiniuUrl = '![](http://opgmvuzyu.bkt.clouddn.com/' + imageName + ')';

                                    testEditor.insertValue(qiniuUrl);
                                }
                            })
                        });
                    }
                }
            }
        }
        document.addEventListener('paste', function (event) {
            paste(event);
        })

前端壓縮

前端壓縮使用的是localResizeIMG.js插件唾那。
兼容IE10以上访锻,所以還得做個(gè)IE版本判斷,然后看自己是否需要使用干這個(gè)插件闹获,我這里就不寫IE的判斷了期犬。
使用方法也很簡單,lrz方法接受一個(gè)文件路徑或者base64的圖片避诽,可以設(shè)置一個(gè)壓縮寬度的對象龟虎,低于這個(gè)寬度的圖片不會壓縮,大于這個(gè)寬度的就會壓縮沙庐,然后在then方法中取得壓縮后的圖片:
得先引入這個(gè)插件鲤妥,可以使用src引入,也支持amd or cmd模塊化

<script src="{{asset('js/lrz.bundle.js')}}" type="text/javascript"></script>

開始使用:

//image就是經(jīng)過paste事件后得到的圖片
lrz(image, {width: 1080}).then(function (res) {
    var base64 = res.base64;
}

七牛云sdk

七牛云注冊好像就送10G的云儲存拱雏,需要的可以去注冊棉安,先下載七牛云sdk,我使用的是php铸抑,地址https://developer.qiniu.com/kodo/sdk/php
配置這個(gè)上傳的文件也很簡單贡耽。將下載后的壓縮包解壓,刪掉一下沒用的文件,然后拖到項(xiàng)目中:


uploadImageToQiliu.php文件是自己新增的蒲赂,代碼如下:

<?php
require_once __DIR__ . '/../autoload.php';
use Qiniu\Auth;
// 引入上傳類
use Qiniu\Storage\UploadManager;
$accessKey = '你的accessKey';
$secretKey = '你的secretKey';
// 初始化簽權(quán)對象阱冶。
$auth = new Auth($accessKey, $secretKey);
$bucket = "空間名字";
$upToken = $auth->uploadToken($bucket);
// 初始化 UploadManager 對象并進(jìn)行文件的上傳。
$uploadMgr = new UploadManager();
$key = $_POST['name'];
$filePath = $_POST['image'];
list($ret, $err) = $uploadMgr->putFile($upToken, $key, $filePath);
if ($err !== null) {
    echo json_encode($err);
} else {
    echo json_encode($ret);
}

accessKey和secretKey注冊后就可以看到凳宙,bucket是云儲存空間名字熙揍。
接下來是前臺傳圖片和圖片名給后臺,圖片名我就直接用 new Date().getTime() 了氏涩。

$.ajax({
    url: "{{asset('php-sdk/myapis/uploadImageToQiliu.php')}}",
    type: 'post',
    data: {
        "image": res.base64,
        "name": new Date().getTime() + ".png"
    },
    contentType: 'application/x-www-form-urlencoded;charest=UTF-8',
    success: function (data) {
        var imageName;
        try {
            imageName = JSON.parse(data).key;
        } catch (e) {
            alert(e.toString);
        }
        var qiniuUrl = '![](http://opgmvuzyu.bkt.clouddn.com/' + imageName + ')';
       testEditor.insertValue(qiniuUrl);
    }
})

testEditor 是我使用的markdown編輯器的對象實(shí)例届囚,testEditor.insertValue(qiniuUrl);就是把格式化好的markdown語句插到光標(biāo)處。
整個(gè)前端代碼如下:

    <script type="text/javascript">
        function paste(event) {
            var clipboardData = event.clipboardData;
            var items, item, types;
            if (clipboardData) {
                items = clipboardData.items;
                if (!items) {
                    return;
                }
                // 保存在剪貼板中的數(shù)據(jù)類型
                types = clipboardData.types || [];
                for (var i = 0; i < types.length; i++) {
                    if (types[i] === 'Files') {
                        item = items[i];
                        break;
                    }
                }
                // 判斷是否為圖片數(shù)據(jù)
                if (item && item.kind === 'file' && item.type.match(/^image\//i)) {
                    // 讀取該圖片
                    var file = item.getAsFile(),
                            reader = new FileReader();
                    reader.readAsDataURL(file);
                    reader.onload = function () {
                        //前端壓縮
                        lrz(reader.result, {width: 1080}).then(function (res) {
                            $.ajax({
                                url: "{{asset('php-sdk/myapis/uploadImageToQiliu.php')}}",
                                type: 'post',
                                data: {
                                    "image": res.base64,
                                    "name": new Date().getTime() + ".png"
                                },
                                contentType: 'application/x-www-form-urlencoded;charest=UTF-8',
                                success: function (data) {
                                    var imageName;
                                    try {
                                        imageName = JSON.parse(data).key;
                                    } catch (e) {
                                        alert(e.toString);
                                    }

                                    var qiniuUrl = '![](http://opgmvuzyu.bkt.clouddn.com/' + imageName + ')';

                                    testEditor.insertValue(qiniuUrl);
                                }
                            })
                        });
                    }
                }
            }
        }
        document.addEventListener('paste', function (event) {
            paste(event);
        })
    </script>

再編輯器中粘貼完圖片的效果如下:


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末是尖,一起剝皮案震驚了整個(gè)濱河市意系,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌饺汹,老刑警劉巖蛔添,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異兜辞,居然都是意外死亡迎瞧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門逸吵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凶硅,“玉大人,你說我怎么就攤上這事扫皱∽闵穑” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵韩脑,是天一觀的道長氢妈。 經(jīng)常有香客問我,道長段多,這世上最難降的妖魔是什么首量? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮进苍,結(jié)果婚禮上蕾总,老公的妹妹穿的比我還像新娘。我一直安慰自己琅捏,他們只是感情好生百,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著柄延,像睡著了一般蚀浆。 火紅的嫁衣襯著肌膚如雪缀程。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天市俊,我揣著相機(jī)與錄音杨凑,去河邊找鬼。 笑死摆昧,一個(gè)胖子當(dāng)著我的面吹牛撩满,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播绅你,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼伺帘,長吁一口氣:“原來是場噩夢啊……” “哼置尔!你這毒婦竟也來了厉亏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤西壮,失蹤者是張志新(化名)和其女友劉穎偶垮,沒想到半個(gè)月后张咳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡似舵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年脚猾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片砚哗。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡龙助,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出频祝,到底是詐尸還是另有隱情,我是刑警寧澤脆淹,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布常空,位于F島的核電站,受9級特大地震影響盖溺,放射性物質(zhì)發(fā)生泄漏漓糙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一烘嘱、第九天 我趴在偏房一處隱蔽的房頂上張望昆禽。 院中可真熱鬧,春花似錦蝇庭、人聲如沸醉鳖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盗棵。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間纹因,已是汗流浹背喷屋。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瞭恰,地道東北人屯曹。 一個(gè)月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像惊畏,于是被迫代替她去往敵國和親恶耽。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容