bootstrap富文字編輯器的使用
bootstrap-wysiwyg是一款輕量級的富文字編輯外掛,大致長這樣 在此記錄一下我使用它踩過的坑和經驗。
外掛的引入
外掛其實分為兩部分:頂部的一系列編輯按鈕和下方的div編輯框 前臺程式碼如下:
<!--這裡加上是為了讓提示資訊顯示 不然會被遮擋--> <div class="btn-toolbar" data-role="editor-toolbar" data-target="#editor"> <div class="btn-group"> <a class="btn dropdown-toggle" data-toggle="dropdown" title="Font"><i class="icon-font"></i><b class="caret"></b></a> <ul class="dropdown-menu"> </ul> </div> <div class="btn-group"> <a class="btn dropdown-toggle" data-toggle="dropdown" title="Font Size"><i class="icon-text-height"></i> <b class="caret"></b></a> <ul class="dropdown-menu"> <li><a data-edit="fontSize 5"><font size="5">Huge</font></a></li> <li><a data-edit="fontSize 3"><font size="3">Normal</font></a></li> <li><a data-edit="fontSize 1"><font size="1">Small</font></a></li> </ul> </div> <div class="btn-group"> <a class="btn" data-edit="bold" title="Bold (Ctrl/Cmd+B)"><i class="icon-bold"></i></a> <!--加粗--> <a class="btn" data-edit="italic" title="Italic (Ctrl/Cmd+I)"><i class="icon-italic"></i></a> <!-- 斜體--> <a class="btn" data-edit="strikethrough" title="Strikethrough"><i class="icon-strikethrough"></i></a> <!-- 刪除線--> <a class="btn" data-edit="underline" title="Underline (Ctrl/Cmd+U)"><i class="icon-underline"></i></a> <!-- 下劃線--> </div> <div class="btn-group"> <a class="btn" data-edit="insertunorderedlist" title="Bullet list"><i class="icon-list-ul"></i></a> <!-- 加點--> <a class="btn" data-edit="insertorderedlist" title="Number list"><i class="icon-list-ol"></i></a> <!-- 數字排序--> <a class="btn" data-edit="outdent" title="Reduce indent (Shift+Tab)"><i class="icon-indent-left"></i></a> <!-- 減少縮排--> <a class="btn" data-edit="indent" title="Indent (Tab)"><i class="icon-indent-right"></i></a> <!--增加縮排--> </div> <div class="btn-group"> <a class="btn" data-edit="justifyleft" title="Align Left (Ctrl/Cmd+L)"><i class="icon-align-left"></i></a> <!--左對齊--> <a class="btn" data-edit="justifycenter" title="Center (Ctrl/Cmd+E)"><i class="icon-align-center"></i></a> <!--居中--> <a class="btn" data-edit="justifyright" title="Align Right (Ctrl/Cmd+R)"><i class="icon-align-right"></i></a> <!--右對齊--> <a class="btn" data-edit="justifyfull" title="Justify (Ctrl/Cmd+J)"><i class="icon-align-justify"></i></a> <!--垂直對齊--> </div> <div class="btn-group"> <a class="btn dropdown-toggle" data-toggle="dropdown" title="Hyperlink"><i class="icon-link"></i></a> <!-- 連結--> <div class="dropdown-menu input-append"> <input class="span2" placeholder="URL" type="text" data-edit="createLink" /> <button class="btn" type="button">Add</button> </div> <a class="btn" data-edit="unlink" title="Remove Hyperlink"><i class="icon-cut"></i></a> </div> <div class="btn-group"> <a class="btn" title="Insert picture (or just drag & drop)" id="pictureBtn"><i class="icon-picture"></i></a> <input type="file" data-role="magic-overlay" data-target="#pictureBtn" data-edit="insertImage" /> </div> <div class="btn-group"> <a class="btn" data-edit="undo" title="Undo (Ctrl/Cmd+Z)"><i class="icon-undo"></i></a> <!--撤銷--> <a class="btn" data-edit="redo" title="Redo (Ctrl/Cmd+Y)"><i class="icon-repeat"></i></a> <!--恢復--> </div> <input type="text" data-edit="inserttext" id="voiceBtn" x-webkit-speech=""> </div> <div id="editor">${content}</div>
下面需要引入外掛執行所需的css和js
href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.no-icons.min.css" rel="stylesheet"> <link type="text/css" rel="stylesheet" href="${ctxStatic}/editor/index.css" /> <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/font-awesome/3.0.2/css/font-awesome.css"> <link type="text/css" rel="stylesheet" href="${ctxStatic}/editor/prettify.css" /> <link type="text/css" rel="stylesheet" href="${ctxStatic}/bootstrap/2.3.1/css_default/bootstrap-responsive.min.css" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/2.0.0-beta1/js/bootstrap-select.js"></script> <script type="text/javascript" src="${ctxStatic}/editor/bootstrap-wysiwyg.js"></script> <script type="text/javascript" src="${ctxStatic}/editor/jquery.hotkeys.js"></script> <script type="text/javascript" src="${ctxStatic}/bootstrap/2.3.1/js/bootstrap.min.js"></script> <script type="text/javascript" src="${ctxStatic}/bootstrap/2.3.1/js/bootstrap.js"></script>
這裡有一個坑,網上的教程只提到了引入bootstrap.min.js 如果不額外引入bootstrap.js,會無法使用字型切換的js方法。
下面是一些js函式:
$(function() { function initToolbarBootstrapBindings() { var fonts = [ 'Serif', 'Sans', 'Arial', 'Arial Black', 'Courier', 'Courier New', 'Comic Sans MS', 'Helvetica', 'Impact', 'Lucida Grande', 'Lucida Sans', 'Tahoma', 'Times', 'Times New Roman', 'Verdana' ], fontTarget = $('[title=Font]').siblings('.dropdown-menu'); $.each(fonts, function(idx, fontName) { fontTarget.append($('<li><a data-edit="fontName ' + fontName + '" style="font-family:\'' + fontName + '\'">' + fontName + '</a></li>')); }); $('a[title]').tooltip({ container : 'body' }); $('.dropdown-menu input').click(function() { return false; }).change(function() { $(this).parent('.dropdown-menu').siblings('.dropdown-toggle').dropdown('toggle'); }).keydown('esc', function() { this.value = ''; $(this).change(); }); $('[data-role=magic-overlay]').each(function() { var overlay = $(this), target = $(overlay.data('target')); overlay.css('opacity', 0).css('position', 'absolute').offset(target.offset()).width(target.outerWidth()).height(target.outerHeight()); }); $('#voiceBtn').hide(); } ; initToolbarBootstrapBindings(); $('#editor').wysiwyg(); window.prettyPrint && prettyPrint(); });
引入這些之後,頁面應該可以正常顯示富文字編輯器了
實現儲存到資料庫並回顯
接下來我需要實現將富文字編輯器的內容存到資料庫,然後可以再次讀取出來進行回顯,這裡的坑也不少 首先進行儲存,我打算將整個富文字編輯框中的html元素全部儲存到資料庫,因為它本身就是個div。這裡我使用了mysql資料庫,在表中加了一個mediumblob型別的欄位,最大能儲存16m的資料。
寫一個js函式,獲取div中的html元素,並呼叫ajax介面進行儲存。
$(function() {
$("#btnSubmit").click(function() {
var title = document.getElementById("title").value;
var content = document.getElementById("editor").innerHTML;
var id = document.getElementById("hid").value;
$.ajax({
url : '${ctx}/article/articleContent/savearticle',
type : 'post',
async : false,
dataType : 'json',
data : {
title : title,
content : content,
id:id
},
success : function(data) {
if(data==1){
window.location.href="${ctx}/article/articleContent/list"
}
else{
alert("儲存失敗!");
}
},
error : function(){
alert("儲存失敗!");
}
});
});
});
這樣就成功的儲存到了資料庫~ 這裡需要注意:上面這個ajax傳遞的content var content = document.getElementById(“editor”).innerHTML; 已經對html元素做了轉義,直接存入資料庫即可。
回顯資料
在我打算對文章進行修改時,我需要讀取資料庫中儲存的資料,一開始我只是直接讀取資料庫的資料,沒做任何處理,發現一些html標籤顯示為“?”查詢網上資料得知,需要進行反轉義,將資料庫中的資料轉化為html元素。
String contentString = StringEscapeUtils.unescapeHtml4(articleContent.getContent());
這就是反轉義
中文亂碼 之後我又遇到了中文亂碼的問題,輸出一下日誌發現存入的是正常的中文,但讀取出來中文就變成亂碼了,這肯定和blob有關,寫一個處理blob型別的字元轉換工具類
import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
public class MyBlobTypeHandler extends BaseTypeHandler<String> {
//###指定字符集
private static final String DEFAULT_CHARSET = "utf-8";
public void setNonNullParameter(PreparedStatement ps, int i,
String parameter, JdbcType jdbcType) throws SQLException {
ByteArrayInputStream bis;
try {
//###把String轉化成byte流
bis = new ByteArrayInputStream(parameter.getBytes(DEFAULT_CHARSET));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Blob Encoding Error!");
}
ps.setBinaryStream(i, bis, parameter.length());
}
@Override
public String getNullableResult(ResultSet rs, String columnName)
throws SQLException {
Blob blob = (Blob) rs.getBlob(columnName);
byte[] returnValue = null;
if (null != blob) {
returnValue = blob.getBytes(1, (int) blob.length());
}
try {
//###把byte轉化成string
return new String(returnValue, DEFAULT_CHARSET);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Blob Encoding Error!");
}
}
public String getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
Blob blob = (Blob) cs.getBlob(columnIndex);
byte[] returnValue = null;
if (null != blob) {
returnValue = blob.getBytes(1, (int) blob.length());
}
try {
return new String(returnValue, DEFAULT_CHARSET);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Blob Encoding Error!");
}
}
@Override
public String getNullableResult(ResultSet rs, int columnIndex)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
}
然後需要在mapper.xml中顯式的說明content欄位的typeHandler
<result column="content" property="content" typeHandler="com.common.utils.MyBlobTypeHandler" />
發現中文亂碼問題就解決了~