富文本編輯器使用心得

最近因業(yè)務(wù)需求在項(xiàng)目中嵌入了tinymce這個(gè)編輯器,用于滿足平臺(tái)給用戶編輯各類文章。

各大WYSIWYG編輯器的簡(jiǎn)單比較

UEditor: 因?yàn)橐呀?jīng)不再維護(hù)了,需要大量修改源碼,很多都是專門為jsp等服務(wù)器渲染項(xiàng)目寫的代碼需要?jiǎng)h除, 然后越刪越害怕越刪越不敢用,依賴jquery,需要專門用js去parse編輯完成的內(nèi)容,parse完的內(nèi)容還可能污染全局css,兼容老瀏覽器還不錯(cuò), 但是,我們不怎么考慮兼容IE。所以,告辭。


wangEditor: 中文文檔,上手快,依賴jquery,功能少點(diǎn)要花時(shí)間去寫插件,需要單獨(dú)為圖片上傳功能寫個(gè)接口,老項(xiàng)目忙著上線臨時(shí)用過(guò),感覺(jué)并不適合當(dāng)前業(yè)務(wù)這么重的編輯功能于是放棄了。


Quill:api友好, 功能少,需要特定的css去解析文本(這點(diǎn)我不大喜歡),ui好看,適合作為論壇回帖功能使用。


CKEditor: CKEditor目前主流的還是4.x的版本,但是文檔看著很瞎眼實(shí)在是提不起興致去配置,草草用了下就放棄了,5.x版本剛從beta結(jié)束,需要指定專門的node以及npm版本,雖然功能強(qiáng)大配置靈活ui漂亮不過(guò)目前糟糕的兼容性基本是不可能出現(xiàn)在大眾視野了。


KingEditor: 丑,不喜歡,不愛(ài)用


Draft-js: 知乎最近剛改的文本編輯器就是在draft的基礎(chǔ)上開發(fā)的,依賴react, 棄。


Medium-editor: 雖然看著感覺(jué)很酷炫,但是,不適合我們的業(yè)務(wù)場(chǎng)景啊, api也簡(jiǎn)陋可怕。


trix: 嗯,又一個(gè)小而美,放棄


Slate:react,放棄


Bootstrap-wysiwyg:bootstrap, jquery, 放棄

tinymce: 文檔好,功能強(qiáng),bug少,無(wú)外部依賴,大家用了都說(shuō)好,嗯,沒(méi)錯(cuò)就是它了。

https://www.tiny.cloud/docs/quick-start/

編輯器配置方面只要能看得懂英文耍起來(lái)還是比較簡(jiǎn)單的,適配中碰到的大部分問(wèn)題都可以通過(guò)看文檔解決,即便看文檔解決不了網(wǎng)上也有大量的文章能告訴你怎么配置能解決。

當(dāng)然了,主要是我這里需要解決一些別人覺(jué)得超簡(jiǎn)單自己一想都很煩人的需求,比如:

word文檔粘貼進(jìn)來(lái)要帶格式

兼容移動(dòng)端

word文檔粘貼進(jìn)來(lái)要正常顯示并且還要兼容移動(dòng)端

電腦網(wǎng)頁(yè)里粘貼進(jìn)來(lái)內(nèi)容要正常顯示并且排版還不能亂

電腦網(wǎng)頁(yè)拷過(guò)來(lái)的內(nèi)容還要兼容到移動(dòng)端

初始化

因?yàn)閠inymce的Plugins是按需加載的

為了能先快速上手這個(gè)編輯器

就先在vue-cli的index.html中默認(rèn)塞入一條在線cdn地址

記得去下載語(yǔ)言包到本地,

然后就在文件內(nèi)引入

import'./zh_CN.js'

后面有機(jī)會(huì)再寫下單獨(dú)打包的事項(xiàng),畢竟這貨體積還不小。

插入vue組件模板

記得一定要在textarea外面包一層div,不然...你自己試試看就知道了。

組件基礎(chǔ)配置

將tinymce通過(guò)指定的selector掛載到組件中

import'./zh_CN.js'exportdefault{ data () {constId =Date.now()return{Id: Id,Editor:null,DefaultConfig: {} } },props: {value: {default:'',type:String},config: {type:Object,default:()=>{return{theme:'modern',height:300} } } }, mounted () {this.init() }, beforeDestroy () {// 銷毀tinymcethis.$emit('on-destroy')window.tinymce.remove(`#${this.Id}`) },methods: { init () {constself =thisthis.Editor =window.tinymce.init({// 默認(rèn)配置...this.DefaultConfig,// prop內(nèi)傳入的的config...this.config,// 掛載的DOM對(duì)象selector:`#${this.Id}`,setup:(editor) =>{// 拋出 'on-ready' 事件鉤子editor.on('init', () => { self.loading =falseself.$emit('on-ready') editor.setContent(self.value) } )// 拋出 'input' 事件鉤子,同步value數(shù)據(jù)editor.on('input change undo redo', () => { self.$emit('input', editor.getContent()) } ) } }) } } }

好了,組件基本的初始化完成,后面正式開始踩坑之旅

API

具體內(nèi)容看官網(wǎng)的API就行,英語(yǔ)不好的用chrome翻譯下對(duì)照著demo也能看個(gè)七七八八,當(dāng)然主要原因還是我比較懶。

我這邊根據(jù)自身業(yè)務(wù)需求在組件的data內(nèi)寫了個(gè)默認(rèn)配置

TinyMCE默認(rèn)的工具欄按鈕列表:

newdocument(新文檔)

bold(加粗)

italic(斜體)

underline(下劃線)

strikethrough(刪除線)

alignleft(左對(duì)齊)

aligncenter(居中對(duì)齊)

alignright(右對(duì)齊)

alignjustify(兩端對(duì)齊)

styleselect(格式設(shè)置)

formatselect(段落格式)

fontselect(字體選擇)

fontsizeselect(字號(hào)選擇)

cut(剪切)

copy(復(fù)制)

paste(粘貼)

bullist(項(xiàng)目列表UL)

numlist(編號(hào)列表OL)

outdent(減少縮進(jìn))

indent(增加縮進(jìn))

blockquote(引用)

undo(撤銷)

redo(重做/重復(fù))

removeformat(清除格式)

subscript(下角標(biāo))

superscript(上角標(biāo))

DefaultConfig: {// GLOBALheight:500,theme:'modern',menubar:false,toolbar:`styleselect | fontselect | formatselect | fontsizeselect | forecolor backcolor | bold italic underline strikethrough | image media | table | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | preview removeformat hr | paste code link | undo redo | fullscreen `,plugins:` paste importcss image code table advlist fullscreen link media lists textcolor colorpicker hr preview `,// CONFIGforced_root_block:'p',force_p_newlines:true,importcss_append:true,// CONFIG: ContentStyle 這塊很重要, 在最后呈現(xiàn)的頁(yè)面也要寫入這個(gè)基本樣式保證前后一致, `table`和`img`的問(wèn)題基本就靠這個(gè)來(lái)填坑了content_style:` * { padding:0; margin:0; } html, body { height:100%; } img { max-width:100%; display:block;height:auto; } a { text-decoration: none; } iframe { width: 100%; } p { line-height:1.6; margin: 0px; } table { word-wrap:break-word; word-break:break-all; max-width:100%; border:none; border-color:#999; } .mce-object-iframe { width:100%; box-sizing:border-box; margin:0; padding:0; } ul,ol { list-style-position:inside; } `,insert_button_items:'image link | inserttable',// CONFIG: Pastepaste_retain_style_properties:'all',paste_word_valid_elements:'*[*]',// word需要它paste_data_images:true,// 粘貼的同時(shí)能把內(nèi)容里的圖片自動(dòng)上傳,非常強(qiáng)力的功能paste_convert_word_fake_lists:false,// 插入word文檔需要該屬性paste_webkit_styles:'all',paste_merge_formats:true,nonbreaking_force_tab:false,paste_auto_cleanup_on_paste:false,// CONFIG: Fontfontsize_formats:'10px 11px 12px 14px 16px 18px 20px 24px',// CONFIG: StyleSelectstyle_formats: [? ? {title:'首行縮進(jìn)',block:'p',styles: {'text-indent':'2em'}? ? },? ? {title:'行高',items: [? ? ? ? {title:'1',styles: {'line-height':'1'},inline:'span'},? ? ? ? {title:'1.5',styles: {'line-height':'1.5'},inline:'span'},? ? ? ? {title:'2',styles: {'line-height':'2'},inline:'span'},? ? ? ? {title:'2.5',styles: {'line-height':'2.5'},inline:'span'},? ? ? ? {title:'3',styles: {'line-height':'3'},inline:'span'}? ? ? ]? ? }? ],// FontSelectfont_formats:` 微軟雅黑=微軟雅黑; 宋體=宋體; 黑體=黑體; 仿宋=仿宋; 楷體=楷體; 隸書=隸書; 幼圓=幼圓; Andale Mono=andale mono,times; Arial=arial, helvetica, sans-serif; Arial Black=arial black, avant garde; Book Antiqua=book antiqua,palatino; Comic Sans MS=comic sans ms,sans-serif; Courier New=courier new,courier; Georgia=georgia,palatino; Helvetica=helvetica; Impact=impact,chicago; Symbol=symbol; Tahoma=tahoma,arial,helvetica,sans-serif; Terminal=terminal,monaco; Times New Roman=times new roman,times; Trebuchet MS=trebuchet ms,geneva; Verdana=verdana,geneva; Webdings=webdings; Wingdings=wingdings,zapf dingbats`,// Tabtabfocus_elements:':prev,:next',object_resizing:true,// Imageimagetools_toolbar:'rotateleft rotateright | flipv fliph | editimage imageoptions'}

因?yàn)楸救吮容^懶,以上配置導(dǎo)出的代碼可能會(huì)有代碼注入的風(fēng)險(xiǎn),建議保存的時(shí)候再前后端都做下注入過(guò)濾,不過(guò)一般數(shù)據(jù)安全問(wèn)題主要還是服務(wù)器那邊的事情。

后面的圖片上傳可以單獨(dú)拆出來(lái)做個(gè)小配置,直接寫到props里好了。

url: {default:'',type:String},accept: {default:'image/jpeg, image/png',type:String},maxSize: {default:2097152,type:Number},withCredentials: {default:false,type:Boolean}

然后把這套東西塞到init配置里

// 圖片上傳images_upload_handler:function(blobInfo, success, failure){if(blobInfo.blob().size >self.maxSize) {? ? ? failure('文件體積過(guò)大')? ? }if(self.accept.indexOf(blobInfo.blob().type) >=0) {? ? ? uploadPic()? ? }else{? ? ? failure('圖片格式錯(cuò)誤')? ? }

function uploadPic() {

let formData =new FormData()

// 服務(wù)端接收文件的參數(shù)名,文件數(shù)據(jù),文件名

formData.append('upfile', blobInfo.blob(), blobInfo.filename())

axios({

method:'POST',

// 這里是你的上傳地址

url:'http://utils.aibaoxian.com/upLoadFileService?systemId=S10000064',

data: formData,

}).then((res) => {

if (res.data.head.errorCode ==='0000') {

let url ='http://utils.aibaoxian.com/file/' + res.data.body.fileCode +'_' + res.data.body.fileInfo[0].saveFileName

success(url)

}

}).catch(() => {

failure('上傳失敗')

})

}

? }

至此, 一個(gè)組件的封裝基本算是完成了

看下初階成果

import'./zh_CN.js'exportdefault{ data () {constId =Date.now()return{Id: Id,Editor:null,DefaultConfig: {// GLOBALheight:500,theme:'modern',menubar:false,toolbar:`styleselect | fontselect | formatselect | fontsizeselect | forecolor backcolor | bold italic underline strikethrough | image media | table | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | preview removeformat hr | paste code link | undo redo | fullscreen `,plugins:` paste importcss image code table advlist fullscreen link media lists textcolor colorpicker hr preview `,// CONFIGforced_root_block:'p',force_p_newlines:true,importcss_append:true,// CONFIG: ContentStyle 這塊很重要, 在最后呈現(xiàn)的頁(yè)面也要寫入這個(gè)基本樣式保證前后一致, `table`和`img`的問(wèn)題基本就靠這個(gè)來(lái)填坑了content_style:` * { padding:0; margin:0; } html, body { height:100%; } img { max-width:100%; display:block;height:auto; } a { text-decoration: none; } iframe { width: 100%; } p { line-height:1.6; margin: 0px; } table { word-wrap:break-word; word-break:break-all; max-width:100%; border:none; border-color:#999; } .mce-object-iframe { width:100%; box-sizing:border-box; margin:0; padding:0; } ul,ol { list-style-position:inside; } `,insert_button_items:'image link | inserttable',// CONFIG: Pastepaste_retain_style_properties:'all',paste_word_valid_elements:'*[*]',// word需要它paste_data_images:true,// 粘貼的同時(shí)能把內(nèi)容里的圖片自動(dòng)上傳,非常強(qiáng)力的功能paste_convert_word_fake_lists:false,// 插入word文檔需要該屬性paste_webkit_styles:'all',paste_merge_formats:true,nonbreaking_force_tab:false,paste_auto_cleanup_on_paste:false,// CONFIG: Fontfontsize_formats:'10px 11px 12px 14px 16px 18px 20px 24px',// CONFIG: StyleSelectstyle_formats: [ {title:'首行縮進(jìn)',block:'p',styles: {'text-indent':'2em'} }, {title:'行高',items: [ {title:'1',styles: {'line-height':'1'},inline:'span'}, {title:'1.5',styles: {'line-height':'1.5'},inline:'span'}, {title:'2',styles: {'line-height':'2'},inline:'span'}, {title:'2.5',styles: {'line-height':'2.5'},inline:'span'}, {title:'3',styles: {'line-height':'3'},inline:'span'} ] } ],// FontSelectfont_formats:` 微軟雅黑=微軟雅黑; 宋體=宋體; 黑體=黑體; 仿宋=仿宋; 楷體=楷體; 隸書=隸書; 幼圓=幼圓; Andale Mono=andale mono,times; Arial=arial, helvetica, sans-serif; Arial Black=arial black, avant garde; Book Antiqua=book antiqua,palatino; Comic Sans MS=comic sans ms,sans-serif; Courier New=courier new,courier; Georgia=georgia,palatino; Helvetica=helvetica; Impact=impact,chicago; Symbol=symbol; Tahoma=tahoma,arial,helvetica,sans-serif; Terminal=terminal,monaco; Times New Roman=times new roman,times; Trebuchet MS=trebuchet ms,geneva; Verdana=verdana,geneva; Webdings=webdings; Wingdings=wingdings,zapf dingbats`,// Tabtabfocus_elements:':prev,:next',object_resizing:true,// Imageimagetools_toolbar:'rotateleft rotateright | flipv fliph | editimage imageoptions'} } },props: {value: {default:'',type:String},config: {type:Object,default:()=>{return{theme:'modern',height:300} } },url: {default:'',type:String},accept: {default:'image/jpeg, image/png',type:String},maxSize: {default:2097152,type:Number},withCredentials: {default:false,type:Boolean} }, mounted () {this.init() }, beforeDestroy () {// 銷毀tinymcethis.$emit('on-destroy')window.tinymce.remove(`$#{this.Id}`) },methods: { init () {constself =thisthis.Editor =window.tinymce.init({// 默認(rèn)配置...this.DefaultConfig,// 圖片上傳images_upload_handler:function(blobInfo, success, failure){if(blobInfo.blob().size > self.maxSize) { failure('文件體積過(guò)大') }if(self.accept.indexOf(blobInfo.blob().type) >=0) { uploadPic() }else{ failure('圖片格式錯(cuò)誤') }functionuploadPic(){constxhr =newXMLHttpRequest()constformData =newFormData() xhr.withCredentials = self.withCredentials xhr.open('POST', self.url) xhr.onload =function(){if(xhr.status !==200) {// 拋出 'on-upload-fail' 鉤子self.$emit('on-upload-fail') failure('上傳失敗: '+ xhr.status)return}constjson =JSON.parse(xhr.responseText)// 拋出 'on-upload-complete' 鉤子self.$emit('on-upload-complete', [ json, success, failure ]) } formData.append('file', blobInfo.blob()) xhr.send(formData) } },// prop內(nèi)傳入的的config...this.config,// 掛載的DOM對(duì)象selector:`#${this.Id}`,setup:(editor) =>{// 拋出 'on-ready' 事件鉤子editor.on('init', () => { self.loading =falseself.$emit('on-ready') editor.setContent(self.value) } )// 拋出 'input' 事件鉤子,同步value數(shù)據(jù)editor.on('input change undo redo', () => { self.$emit('input', editor.getContent()) } ) } }) } } }

直接引入組件調(diào)用就行了

?

塞入webpack

為了加快頁(yè)面載入速度就要首先解決載入文件過(guò)多的問(wèn)題,而大部分時(shí)間用戶并不需要每次打開頁(yè)面都先加載一遍editor的核心文件,而editor本身也要按需加載內(nèi)容,一開始想把每個(gè)plugin都搞成獨(dú)立組件模塊按需載入,但是這就要涉及到修改編輯器本身源碼,或者說(shuō)對(duì)window.tinymce刪掉點(diǎn)特性,這些都太麻煩也都有風(fēng)險(xiǎn),對(duì)后面的代碼維護(hù)影響也大,索性就都先留著。

后面邊做邊改吧

還是以vue-cli為例

把官網(wǎng)下載的包塞到stataic文件夾中

然后刪掉index.html模版中的cdn代碼

當(dāng)然這里有倆選擇

要么做成一個(gè)異步組件,單獨(dú)打包,按需載入

要么直接引入到main.js中將包打成為一個(gè)巨無(wú)霸

所以我選擇前者,

首先老規(guī)矩 引入編輯器主體

import'../../static/tinymce/tinymce.min.js'

然后刷新下頁(yè)面,不出意外應(yīng)該是報(bào)這么個(gè)錯(cuò)Uncaught SyntaxError: Unexpected token <

眼尖的朋友應(yīng)該知道是怎么回事了theme.js:1

在默認(rèn)配置下, tinymce載入的theme的路徑居然是這個(gè)

Request URL:http://localhost:8080/themes/modern/theme.js

然后我跑去官網(wǎng)搜了下api 只搜到一個(gè)叫document_base_url的api,但是根據(jù)多年程序員的直覺(jué)經(jīng)驗(yàn)告訴我 不是這貨(嗯,我在這里卡住了),網(wǎng)上翻了下各地文獻(xiàn),都沒(méi)有啊,

那怎么辦呢

于是我就跑去看源碼...但是4萬(wàn)行...算了...

然后我就在控臺(tái)打印了下tinymce對(duì)象,然后發(fā)現(xiàn)了一個(gè)叫baseURL的string對(duì)象,嗯,有希望了。

在源碼里搜了下baseURL

蹦出來(lái)這段代碼 .... 算了有很多段...

大致思想就是通過(guò)當(dāng)前URI拆出來(lái)個(gè)baseURL,改掉就行了

window.tinymce.baseURL ='/static/tinymce'

如果需要載入的地址是另一個(gè)比如自己公司的cdn的路徑,那改成全路徑就行了

window.tinymce.baseURL ='http://cdn.xxx.com/static/tinymce'

貌似路徑的問(wèn)題解決了

但是新的問(wèn)題又出現(xiàn)了,

插件下過(guò)來(lái)都是帶min的,但默認(rèn)載入的插件都是不帶min的,一定是我源碼沒(méi)看仔細(xì),

然后我又搜了一下代碼

if(!baseURL &&document.currentScript) {? src =document.currentScript.src;if(src.indexOf('.min') !=-1) {? ? suffix ='.min';? }? baseURL = src.substring(0, src.lastIndexOf('/'));}

希望就在眼前,貌似是業(yè)務(wù)我載入的方式是直接導(dǎo)入到模塊的,于是一個(gè)叫suffix的默認(rèn)值為空了,于是我去又加了行代碼:

window.tinymce.suffix ='.min'

成功!

你看嘛,超級(jí)簡(jiǎn)單的是不是,根本不用改源碼,網(wǎng)上說(shuō)的動(dòng)不動(dòng)就去改源碼什么的不要信啊不要信,大部分面向?qū)ο蟮氖虑楦膫€(gè)默認(rèn)值就行了。

對(duì)了,還記得前面的語(yǔ)言包嘛,

下過(guò)來(lái)塞到/static/tinymce/langs文件夾里

然后刪掉

import'./zh_CN.js'

這行代碼

在DefaultConfig中放入一個(gè)新配置項(xiàng)

language:'zh_CN'

好了,后面就是模塊打包的事情了,

打包

前面打的包有一個(gè)問(wèn)題是默認(rèn)配置是載入tinyMce本體,那么就會(huì)造成這個(gè)包大概有500k的體積,如果這個(gè)組件不做異步載入的處理,那么對(duì)于某些業(yè)務(wù)來(lái)說(shuō)就是災(zāi)難。雖然這么做打開只用載入一個(gè)文件,業(yè)務(wù)比較穩(wěn)定。

但我覺(jué)得這樣不優(yōu)雅所以最后還是把它單獨(dú)拎出來(lái)了。

同理,根據(jù)這個(gè)庫(kù)本身的特性,我們完全可以把這么多個(gè)必須的plugin按需要直接統(tǒng)一打成一個(gè)包,直接載入。這樣,我們就又多了一個(gè)幾百k的plugins包。

然后把plugins包和tinyMce主體包在不阻塞頁(yè)面加載的情況下,做個(gè)懶加載提前緩存好文件方便后面使用,而組件本身在掛載前做個(gè)監(jiān)聽window.tinymce全局變量的方法,然后cdn控制下文件的過(guò)期時(shí)間即可。

這樣,在保證了靈活度的前提下也保證了業(yè)務(wù)載入的速度。

完,感謝閱讀。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,197評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,415評(píng)論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,104評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,884評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,647評(píng)論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,130評(píng)論 1 323
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,208評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,366評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,887評(píng)論 1 334
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,737評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,939評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,478評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,174評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,586評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,827評(píng)論 1 283
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,608評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,914評(píng)論 2 372

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