首先ckeditor中列表與所我目前所工作的列表構(gòu)造不同,ckeditor中列表層級越大斯议,嵌套的層級也越多产捞。而目前工作的列表構(gòu)造中,層級的變化是用CSS來控制的哼御,DOM結(jié)構(gòu)只有一層嵌套坯临。所以在粘貼處理的時(shí)候方便很多。
其實(shí)著重考慮的就是兩點(diǎn)粘貼內(nèi)容和粘貼位置恋昼,我稱這兩項(xiàng)為內(nèi)容和環(huán)境看靠, 內(nèi)容就是一個(gè)字符串,需要整理液肌,從不同位置拷貝過來的內(nèi)容在格式上差別比較大衷笋;環(huán)境也需要整理,列表中我們?nèi)藶橐?guī)定了只能存在文本矩屁,要是粘貼內(nèi)容中有圖片辟宗、表格類似的段落,就需要拆分這個(gè)環(huán)境吝秕,內(nèi)容作為普通段落插入到被拆分后的兩個(gè)列表段落之間泊脐。
重點(diǎn)還是解決以下幾個(gè)問題
1. 先內(nèi)容還是先環(huán)境的問題?
我覺得應(yīng)該烁峭,先規(guī)范內(nèi)容容客,再考慮環(huán)境秕铛。
在最開始實(shí)現(xiàn)這個(gè)功能的時(shí)候,確實(shí)是先考慮了環(huán)境缩挑,把環(huán)境處理明白了但两,再往里加內(nèi)容。
找到光標(biāo)所在段~~》下方插空的li節(jié)點(diǎn)~~》空li節(jié)點(diǎn)處截?cái)鄜~》粘貼內(nèi)容~~》查看是否存在可合并列表
這樣的好處是谨湘,當(dāng)上傳本地圖片到編輯器中時(shí),success異步返回時(shí)芥丧,就可以直接操作DOM讓返回的內(nèi)容直接顯示在正確的位置紧阔。
缺點(diǎn)也顯而易見,要是只是粘貼文本的話续担,截?cái)嗖僮骶惋@得多余了擅耽。
所以,先內(nèi)容物遇,后環(huán)境
上傳本地圖片的異步返回中乖仇,去做替換節(jié)點(diǎn)內(nèi)容的操作,而不是去做插入新節(jié)點(diǎn)的操作询兴。
//自設(shè)binaryFlow屬性記錄剪切板轉(zhuǎn)過來的二進(jìn)制流
if(e.data.binaryFlow){
var id = Math.uuid().replace(/-/g,'');
var imgValue = e.data.binaryFlow;
var imgData = imgValue.split(',');
var data_value = imgData[1];
~
$.ajaxFileUpload({
~
data:{file_id:id,file_name:'png',image_bs64:data_value},
success:function(data,status){
if(data.data != undefined){
var bodyWidth = $('.mnote-document-edit-section .cke_contents[role="presentation"]')
.find(".cke_wysiwyg_frame.cke_reset")
.contents()
.find("body").width(),
imgWidth = data.data.width != undefined && data.data.width != null ? data.data.width : 0,
imgHeight = data.data.height != undefined && data.data.height != null ? data.data.height : 0;
var tmpl = "<img {width} {height} m_width='{m_width}' m_height='{m_height}' image_id='"+ toolHelper.textHandle(data.data.file_id) +"' src='"+ toolHelper.textHandle(data.data.url) +"'/>";
if( bodyWidth > 0 ){
//編輯器寬度小于圖片
if( bodyWidth < imgWidth){
imgWidth = "100%";
imgHeight = "";
}
//替換寬度
if(imgWidth != undefined && imgWidth != null){
tmpl = tmpl.replace(/{width}/g, "width=" + imgWidth).replace(/{m_width}/g, data.data.width);
}else{
tmpl = tmpl.replace(/{width}/g,"").replace(/{m_width}/g, "0");
}
//替換高度
if(imgHeight != undefined && imgHeight != null){
tmpl = tmpl.replace(/{height}/g, imgHeight == "" ? "" : "height=" + imgHeight).replace(/{m_height}/g, data.data.height);
}else{
tmpl = tmpl.replace(/{height}/g,"").replace(/{m_height}/g, "0");
}
//替換虛構(gòu)節(jié)點(diǎn)
var tempPic = element.getDocument().findOne(" .factitiousImg ")
tempPic.removeClass("factitiousImg");
tempPic.getParent().setHtml(tmpl);
var range = that.editor.createRange();
range.moveToElementEditEnd( element );
range.select();
that.editor.fire('change');
}else{
alert("Error 編輯器寬度小于等于0");
}
}
});
}
2. 列表中行首乃沙,行中,行尾的行內(nèi)文本截?cái)鄦栴}
行首粘貼內(nèi)容應(yīng)該在其上蕉朵,行中應(yīng)該此行文本被截?cái)啻尥浚形舱迟N內(nèi)容應(yīng)該在其下
行首行尾比較簡單阳掐,就是增加空行的位置不一樣罷了始衅。行中處理邏輯有點(diǎn)亂,有三個(gè)想法缭保。
(1).光標(biāo)之后的文本做成一個(gè)li節(jié)點(diǎn)汛闸,插入到光標(biāo)所在行之下。中間再插入空段
卡手的位置:不知道怎么做成一個(gè)li節(jié)點(diǎn)艺骂。
關(guān)于range和selection不是很熟練诸老,沒有找到獲取選中域HTML的方法。
(2).復(fù)制行钳恕,上一行刪除光標(biāo)點(diǎn)到末尾别伏,下一行刪除光標(biāo)點(diǎn)到開始
卡手的位置:復(fù)制后生成行的光標(biāo)位置確定不了
首先CKeditor提供了很多設(shè)置range的方法
setStartAt和setEndAt都是在range存在于DOM中的時(shí)候,設(shè)置范圍用的忧额,兩個(gè)方法好像單獨(dú)用更合適厘肮。對于新創(chuàng)建的Range,我覺得用setStart和setEnd更靠譜一些睦番。
var deleteRange = that.editor.createRange();
//deleteRange.setStart(currentElement,cursorRange.startOffset);
deleteRange.moveToRange(that.editor.getSelection().getRanges()[ 0 ]);
deleteRange.setEnd(copyNode.getFirst(),cursorRange.startOffset);
deleteRange.select();
that.editor.getSelection().getRanges()[ 0 ].deleteeContents();
replaceLi.insertAfter(currentElement);
但是這個(gè)setEnd會報(bào)錯类茂,因?yàn)閛ffset是text節(jié)點(diǎn)中的耍属,而被克隆的是element,需要進(jìn)一步去尋找巩检。要是不加BIUS(加粗之類的)樣式厚骗,還是容易找的,但是有了樣式兢哭,節(jié)點(diǎn)就更難找了领舰。
(3).光標(biāo)處插入空白行
有insertNode
這個(gè)方法,真是棒極了厦瓢。提揍。。
cursorRange.insertNode(replaceLi);
var breakLi = replaceLi.getParent();
while(breakLi.getName() != 'li' && breakLi.getName() != 'body'){
breakLi = breakLi.getParent();
}
if(breakLi.getName() == 'li'){
replaceLi.breakParent(breakLi);
}else{
//防范錯誤
replaceLi.breakParent(replaceLi.getParent());
}