ios富文本編輯器

方案:html+wkwebview,支持加粗、下劃線、斜體、對(duì)齊方式、字體更改顏色、插入圖片、插入視頻、插入鏈接、清除格式、撤回上一個(gè)操作

核心:利用html5新特性contenteditable,當(dāng)div的contenteditable為true時(shí),div進(jìn)入編輯狀態(tài),可以通過執(zhí)行html5的命令對(duì)文本進(jìn)行操作。命令文檔地址:https://developer.mozilla.org/zh-TW/docs/Web/API/Document/execCommand。


具體實(shí)現(xiàn)

一:文件目錄

1.editor.html,該文件實(shí)現(xiàn)了編輯器的節(jié)點(diǎn)骨架,一個(gè)contenteditable為true的div。

<body onLoad="zss_editor.init();">

<div id="zss_editor_content" class="zs_editor_content" contenteditable="true"><p><br></p><!-- defaultContent --></div>

?<div id="zss_editor_placeHolder">請(qǐng)輸入文章內(nèi)容</div>

</body>

2.ZJSTextEditor.js,該文件是編輯器的核心內(nèi)容,主要實(shí)現(xiàn)編輯器的各種操作,以插入視頻為例,外部的wkwebview只需要執(zhí)行js方法evaluateJavaScript:‘zss_editor.insertVideo(...)’,將url帶入

zss_editor.insertVideo =function(videoUrl) {

? ? var poster = videoUrl+'?vframe/jpg/offset/5/w/210';

?? ? var str = '<br name = "deleteBr"><video? controls="controls" src="'+videoUrl+'" poster = "'+poster+'"></video>';

?? ? zss_editor.insertHTML(str);

?? ? zss_editor.insertP();

?? ? zss_editor.deleteNode('deleteBr');

}

zss_editor.insertP = function() {?? ?

var contentDiv = document.getElementById("zss_editor_content");?? ?

var p = document.createElement("p");?? ?

contentDiv.appendChild(p);

}

zss_editor.insertHTML = function(str) {??

var result = document.execCommand('insertHTML', false, str);? ?

if(result == false) {? ? ? ?

$('#zss_editor_content').html(str);? ?

}

}

3.EditorView這個(gè)文件主要是放wkwebview,以及wkwebview調(diào)用ZJSTextEditor.js中js方法的部分。如頁面加載完,設(shè)置占位文字,或者默認(rèn)對(duì)一些標(biāo)簽的處理

- (void)webView:(WKWebView*)webViewdidFinishNavigation:(WKNavigation*)navigation {

? ? NSLog(@"頁面加載完畢");

? ? [[UIApplication sharedApplication].keyWindow? zjs_removeIndicatorWithBackgroundColor];

? ? if(_webView) {

?? ? ? ? NSString *trigger = @"zss_editor.setDefualt();";

?? ? ? ? [self.webViewevaluateJavaScript:triggercompletionHandler:^(id_Nullableres,NSError*_Nullableerror) {

? ? ? ? ? ? ? if(error) {

? ? ? ? ? ? ? DLog(@"===%@",error);

? ? ? ? ? ? ? }

?? ? ? ? }];

?? ? ? ? NSString*setPlaceHolder =@"zss_editor.placeholder();";

?? ? ? ? [self.webViewevaluateJavaScript:setPlaceHoldercompletionHandler:^(id_Nullableres,NSError*_Nullableerror) {

? ? ? ? ? ? ? if(error) {

? ? ? ? ? ? ? DLog(@"===%@",error);

? ? ? ? }

?? ? ? ? }];

?? ? }

}

文件目錄

二:開發(fā)中產(chǎn)品提出的需求和我的設(shè)計(jì)方案

1.web端要求dom結(jié)構(gòu)為<p>...</p>?<p>...</p>?<p>...</p>?<p>...</p>?<p>...</p>,也就是n個(gè)p里包含著你插入的視頻圖片等子節(jié)點(diǎn)?

我的方案:

1.1:在editor.html文件中插入的div中,插入一個(gè)默認(rèn)的空p標(biāo)簽<p><br></p>,這樣會(huì)保證你在文字中間插入圖片、視頻或者換行時(shí),系統(tǒng)給你新增一個(gè)p標(biāo)簽包裹而不是div標(biāo)簽

1.2:在插入圖片后加入一個(gè)空p,在文字中間插入視頻后加入一個(gè)空的p和br再刪除br,插入br是為了在文字中間插入視頻時(shí),讓系統(tǒng)自動(dòng)給你補(bǔ)全p標(biāo)簽,否則視頻會(huì)被加在該文字的下一行。


2.每個(gè)圖片要緊緊跟隨一個(gè)圖片輸入框,且圖片輸入框支持粘貼,且圖片和圖片輸入框可以通過某個(gè)按鈕同時(shí)被刪除?

我的方案:

圖片有三個(gè)途徑添加,第一個(gè)是粘貼來的新聞中帶有圖片,第二個(gè)是自己插入的圖片,第三個(gè)是從html剛剛開始加載時(shí)自帶圖片(從web端發(fā)布的文章,在ios端編輯)。

2.1:每個(gè)圖片要緊緊跟著一個(gè)圖片輸入框,我在三個(gè)途徑處分別做了圖片的處理,首先是自己插入的圖片,我在插入圖片時(shí),緊接著插入一個(gè)textarea標(biāo)簽和一個(gè)p標(biāo)簽。插入一個(gè)p標(biāo)簽的目的是滿足需求1,其次是粘貼來的新聞和html剛剛加載自帶的圖片,我選擇遍歷所有的圖片標(biāo)簽,首先檢查img標(biāo)簽的name屬性是否有值,若沒有值,新增textarea標(biāo)簽,并設(shè)置img標(biāo)簽和textarea標(biāo)簽的name屬性為同一個(gè)UUID,若name屬性有值,檢查它的后一個(gè)兄弟節(jié)點(diǎn)是否跟隨一個(gè)同name的dom,如果有且是i標(biāo)簽(提交數(shù)據(jù)時(shí),要將所有的輸入框變成i標(biāo)簽,此刻要從i標(biāo)簽變回輸入框),將它轉(zhuǎn)化成輸入框,如果沒有,添加默認(rèn)輸入框。

2.2:圖片輸入框支持粘貼,textarea自帶粘貼

2.3:圖片和圖片輸入框可以通過某個(gè)按鈕同時(shí)被刪除,設(shè)置img標(biāo)簽和textarea標(biāo)簽的name屬性為同一個(gè)UUID,用name的原因是document.getElementsByName給的是該name的一組標(biāo)簽,刪除時(shí),只需要根據(jù)name刪除即可


3.從微信或者頭條粘貼過來的文章格式有誤,文字偏大或者偏???

我的解決方案:

由于拿不到原文章的js,所以只能在粘貼時(shí)去除標(biāo)簽內(nèi)的所有內(nèi)聯(lián)樣式。當(dāng)然這個(gè)地方有個(gè)特殊情況要處理,比如用戶在編輯時(shí),設(shè)置了對(duì)齊方式,系統(tǒng)會(huì)自動(dòng)給標(biāo)簽加上內(nèi)聯(lián)樣式,這個(gè)樣式我們不應(yīng)該去掉。我的處理方案時(shí)自定義一個(gè)屬性名zjs-style,在用戶設(shè)置對(duì)齊方式時(shí),將標(biāo)簽的style值賦值給zjs-style,我們?cè)诤线m的時(shí)機(jī),根據(jù)zjs-style復(fù)原其style

4.輸入框在提交后變成不可輸入的展示區(qū)域?

我的解決方案:

在提交時(shí),遍歷所有的textarea,若textarea沒有值,去掉該textarea,若有值的話,將該textarea替換成i標(biāo)簽,且name值賦值給新的i。

5.從web端來的數(shù)據(jù)支持展示和再編輯?

我的解決方案:

在editor.html的div中加入默認(rèn)占位文字<!-- defaultContent -->,在html資源加載前,將占位文字替換為后臺(tái)給的html內(nèi)容,并在網(wǎng)頁加載完后,做相關(guān)處理

調(diào)試工具

<!--用于打印日志-->

<!--<script src="https://cdn.bootcss.com/vConsole/3.3.2/vconsole.min.js"></script>-->

<!--<script>-->

<!--new VConsole()-->;

<!--</script>-->


調(diào)試工具
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容