我相信目前國內富文本編輯器中KindEditor 屬於前列,詳細的中文幫助文檔,簡單的加載方式,可以定制的輕量級。都是系統的首選
很多文章教程有kindeditor的使用,但本文比較特別可能帶有,上傳文件的縮略圖和水印的源碼!這塊也是比較復雜和備受關注的功能
一、下載編輯器
KindEditor 4.1.10 (2013-11-23) [1143KB] 官方最新版 或者: http://www.kindsoft.net/down.php
二、添加到項目
解壓 kindeditor-x.x.x.zip 文件,將所有文件上傳到您的網站程序目錄里
我放在Scripts下
里面有很多例子,你都可以刪掉,比如說asp ,asp.net ,jsp ,php,examples
themes是主題,共4個
三、了解常用方法
我們不需要很深入和學習這個富文本編輯器,用到什么到官方查什么就可以,或者google一下,下面是最受關注的幾個方法了
- 加載編輯器
- 設置編輯器的值
- 獲取編輯器的值
- 上傳圖片和文件
- 上傳圖片加水印、縮略圖
現在我們一個一個來了解
1.加載編輯器
引入JS(前要引入jquery)
<script src="@Url.Content("~/Scripts/kindeditor/kindeditor-min.js")" type="text/javascript"></script>
編輯器需要textarea標簽的支持,所以
<textarea id="BodyConetent" name="BodyContent" style="width:700px;height:300px;">HTML內容</textarea>
或者在MVC
@Html.TextAreaFor(model => model.BodyContent, new { style = "width:675px; height:225px;" })
style的寬高是編輯器的寬高
最后代碼是
<script src="@Url.Content("~/Scripts/kindeditor/kindeditor-min.js")" type="text/javascript"></script> <script type="text/javascript"> $(function () { //加載編輯器 var editor = KindEditor.create('textarea[name="BodyContent"]', { resizeType: 1, uploadJson: '/Core/upload_ajax.ashx?action=EditorFile&IsWater=1', fileManagerJson: '/Core/upload_ajax.ashx?action=ManagerFile', allowFileManager: false, items: ['source', 'undo', 'redo', 'wordpaste', 'justifyleft', 'justifycenter', 'justifyright', 'insertorderedlist', 'formatblock', 'fontname', 'fontsize', 'forecolor', 'bold', 'italic', 'table', 'link', 'unlink', 'image', 'fullscreen'] }); }); </script> <textarea id="BodyConetent" name="BodyContent" style="width:700px;height:300px;">HTML內容</textarea>
有必要解釋一下上面的方法
uploadJson:上傳文件地址
fileManagerJson:文件管理
allowFileManager:是否啟用管理器 false不啟動(管理器可以看到以前上傳的文件)
(之前分享過一個上傳例子)轉到 swfupload多文件上傳[附源碼] 下載這里的源碼。並提取upload_ajax.ashx這個文件所相關的類
替換upload_ajax.ashx這個文件,里面添加了幾個kindeditor上傳和文件管理的方法

using System; using System.Collections; using System.IO; using System.Collections.Generic; using System.Web.SessionState; using System.Web; using System.Text.RegularExpressions; using App.Common; using LitJson; using App.Core; namespace App.Admin { /// <summary> /// 文件上傳處理頁 /// </summary> public class upload_ajax : IHttpHandler, IRequiresSessionState { public void ProcessRequest(HttpContext context) { //取得處事類型 string action = ContextRequest.GetQueryString("action"); switch (action) { case "SingleFile": //單文件 SingleFile(context); break; case "MultipleFile": //多文件 MultipleFile(context); break; case "EditorFile": //編輯器文件 EditorFile(context); break; case "ManagerFile": //管理文件 ManagerFile(context); break; } } #region 上傳單文件處理=================================== private void SingleFile(HttpContext context) { string _refilepath = ContextRequest.GetQueryString("ReFilePath"); //取得返回的對象名稱 string _upfilepath = ContextRequest.GetQueryString("UpFilePath"); //取得上傳的對象名稱 string _delfile = ContextRequest.GetString(_refilepath); HttpPostedFile _upfile = context.Request.Files[_upfilepath]; bool _iswater = false; //默認不打水印 bool _isthumbnail = false; //默認不生成縮略圖 bool _isimage = false; if (ContextRequest.GetQueryString("IsWater") == "1") _iswater = true; if (ContextRequest.GetQueryString("IsThumbnail") == "1") _isthumbnail = true; if (ContextRequest.GetQueryString("IsImage") == "1") _isimage = true; if (_upfile == null) { context.Response.Write("{\"msg\": 0, \"msgbox\": \"請選擇要上傳文件!\"}"); return; } UpLoad upFiles = new UpLoad(); string msg = upFiles.fileSaveAs(_upfile, _isthumbnail, _iswater, _isimage); //刪除已存在的舊文件 Utils.DeleteUpFile(_delfile); //返回成功信息 context.Response.Write(msg); context.Response.End(); } #endregion #region 上傳多文件處理=================================== private void MultipleFile(HttpContext context) { string _upfilepath = context.Request.QueryString["UpFilePath"]; //取得上傳的對象名稱 HttpPostedFile _upfile = context.Request.Files[_upfilepath]; bool _iswater = false; //默認不打水印 bool _isthumbnail = false; //默認不生成縮略圖 if (ContextRequest.GetQueryString("IsWater") == "1") _iswater = true; if (ContextRequest.GetQueryString("IsThumbnail") == "1") _isthumbnail = true; if (_upfile == null) { context.Response.Write("{\"msg\": 0, \"msgbox\": \"請選擇要上傳文件!\"}"); return; } UpLoad upFiles = new UpLoad(); string msg = upFiles.fileSaveAs(_upfile, _isthumbnail, _iswater); //返回成功信息 context.Response.Write(msg); context.Response.End(); } #endregion #region 編輯器上傳處理=================================== private void EditorFile(HttpContext context) { bool _iswater = false; //默認不打水印 if (context.Request.QueryString["IsWater"] == "1") _iswater = true; HttpPostedFile imgFile = context.Request.Files["imgFile"]; if (imgFile == null) { showError(context, "請選擇要上傳文件!"); return; } UpLoad upFiles = new UpLoad(); string remsg = upFiles.fileSaveAs(imgFile, false, _iswater); //string pattern = @"^{\s*msg:\s*(.*)\s*,\s*msgbox:\s*\""(.*)\""\s*}$"; //鍵名前和鍵值前后都允許出現空白字符 //Regex r = new Regex(pattern, RegexOptions.IgnoreCase); //正則表達式實例,不區分大小寫 //Match m = r.Match(remsg); //搜索匹配項 //string msg = m.Groups[1].Value; //msg的值,正則表達式中第1個圓括號捕獲的值 //string msgbox = m.Groups[2].Value; //msgbox的值,正則表達式中第2個圓括號捕獲的值 JsonData jd = JsonMapper.ToObject(remsg); string msg = jd["msg"].ToString(); string msgbox = jd["msgbox"].ToString(); if (msg == "0") { showError(context, msgbox); return; } Hashtable hash = new Hashtable(); hash["error"] = 0; hash["url"] = msgbox; context.Response.AddHeader("Content-Type", "text/html; charset=UTF-8"); context.Response.Write(JsonMapper.ToJson(hash)); context.Response.End(); } //顯示錯誤 private void showError(HttpContext context, string message) { Hashtable hash = new Hashtable(); hash["error"] = 1; hash["message"] = message; context.Response.AddHeader("Content-Type", "text/html; charset=UTF-8"); context.Response.Write(JsonMapper.ToJson(hash)); context.Response.End(); } #endregion #region 瀏覽文件處理===================================== private void ManagerFile(HttpContext context) { App.Models.Sys.SysConfig siteConfig = new App.BLL.SysConfigBLL().loadConfig(Utils.GetXmlMapPath("Configpath")); //String aspxUrl = context.Request.Path.Substring(0, context.Request.Path.LastIndexOf("/") + 1); //根目錄路徑,相對路徑 String rootPath = siteConfig.webpath + siteConfig.attachpath + "/"; //站點目錄+上傳目錄 //根目錄URL,可以指定絕對路徑,比如 http://www.App.com/attached/ String rootUrl = siteConfig.webpath + siteConfig.attachpath + "/"; //圖片擴展名 String fileTypes = "gif,jpg,jpeg,png,bmp"; String currentPath = ""; String currentUrl = ""; String currentDirPath = ""; String moveupDirPath = ""; String dirPath = Utils.GetMapPath(rootPath); String dirName = context.Request.QueryString["dir"]; //if (!String.IsNullOrEmpty(dirName)) //{ // if (Array.IndexOf("image,flash,media,file".Split(','), dirName) == -1) // { // context.Response.Write("Invalid Directory name."); // context.Response.End(); // } // dirPath += dirName + "/"; // rootUrl += dirName + "/"; // if (!Directory.Exists(dirPath)) // { // Directory.CreateDirectory(dirPath); // } //} //根據path參數,設置各路徑和URL String path = context.Request.QueryString["path"]; path = String.IsNullOrEmpty(path) ? "" : path; if (path == "") { currentPath = dirPath; currentUrl = rootUrl; currentDirPath = ""; moveupDirPath = ""; } else { currentPath = dirPath + path; currentUrl = rootUrl + path; currentDirPath = path; moveupDirPath = Regex.Replace(currentDirPath, @"(.*?)[^\/]+\/$", "$1"); } //排序形式,name or size or type String order = context.Request.QueryString["order"]; order = String.IsNullOrEmpty(order) ? "" : order.ToLower(); //不允許使用..移動到上一級目錄 if (Regex.IsMatch(path, @"\.\.")) { context.Response.Write("Access is not allowed."); context.Response.End(); } //最后一個字符不是/ if (path != "" && !path.EndsWith("/")) { context.Response.Write("Parameter is not valid."); context.Response.End(); } //目錄不存在或不是目錄 if (!Directory.Exists(currentPath)) { context.Response.Write("Directory does not exist."); context.Response.End(); } //遍歷目錄取得文件信息 string[] dirList = Directory.GetDirectories(currentPath); string[] fileList = Directory.GetFiles(currentPath); switch (order) { case "size": Array.Sort(dirList, new NameSorter()); Array.Sort(fileList, new SizeSorter()); break; case "type": Array.Sort(dirList, new NameSorter()); Array.Sort(fileList, new TypeSorter()); break; case "name": default: Array.Sort(dirList, new NameSorter()); Array.Sort(fileList, new NameSorter()); break; } Hashtable result = new Hashtable(); result["moveup_dir_path"] = moveupDirPath; result["current_dir_path"] = currentDirPath; result["current_url"] = currentUrl; result["total_count"] = dirList.Length + fileList.Length; List<Hashtable> dirFileList = new List<Hashtable>(); result["file_list"] = dirFileList; for (int i = 0; i < dirList.Length; i++) { DirectoryInfo dir = new DirectoryInfo(dirList[i]); Hashtable hash = new Hashtable(); hash["is_dir"] = true; hash["has_file"] = (dir.GetFileSystemInfos().Length > 0); hash["filesize"] = 0; hash["is_photo"] = false; hash["filetype"] = ""; hash["filename"] = dir.Name; hash["datetime"] = dir.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss"); dirFileList.Add(hash); } for (int i = 0; i < fileList.Length; i++) { FileInfo file = new FileInfo(fileList[i]); Hashtable hash = new Hashtable(); hash["is_dir"] = false; hash["has_file"] = false; hash["filesize"] = file.Length; hash["is_photo"] = (Array.IndexOf(fileTypes.Split(','), file.Extension.Substring(1).ToLower()) >= 0); hash["filetype"] = file.Extension.Substring(1); hash["filename"] = file.Name; hash["datetime"] = file.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss"); dirFileList.Add(hash); } context.Response.AddHeader("Content-Type", "application/json; charset=UTF-8"); context.Response.Write(JsonMapper.ToJson(result)); context.Response.End(); } #region Helper public class NameSorter : IComparer { public int Compare(object x, object y) { if (x == null && y == null) { return 0; } if (x == null) { return -1; } if (y == null) { return 1; } FileInfo xInfo = new FileInfo(x.ToString()); FileInfo yInfo = new FileInfo(y.ToString()); return xInfo.FullName.CompareTo(yInfo.FullName); } } public class SizeSorter : IComparer { public int Compare(object x, object y) { if (x == null && y == null) { return 0; } if (x == null) { return -1; } if (y == null) { return 1; } FileInfo xInfo = new FileInfo(x.ToString()); FileInfo yInfo = new FileInfo(y.ToString()); return xInfo.Length.CompareTo(yInfo.Length); } } public class TypeSorter : IComparer { public int Compare(object x, object y) { if (x == null && y == null) { return 0; } if (x == null) { return -1; } if (y == null) { return 1; } FileInfo xInfo = new FileInfo(x.ToString()); FileInfo yInfo = new FileInfo(y.ToString()); return xInfo.Extension.CompareTo(yInfo.Extension); } } #endregion #endregion public bool IsReusable { get { return false; } } } }
(由於上傳圖片涉及到水印,縮略圖之類)導致類比較多所以從swf這個實例中提取並合並
下載LitJson並引入 http://pan.baidu.com/share/link?shareid=2964341274&uk=3624026355 里面需要用到序列化json這個類可以幫助,這個類是開源的,大家可以百度源碼
items:代表自定義工具欄
http://kindeditor.net/ke4/examples/custom-plugin.html 可以參考官方例子,將不需要的去掉,比如縮進功能
無設置items的完整模式
設置后的模式
水印可以是文字和圖片
請大家到swfupload例子源碼中獲取到UpLoad.cs這個類,這個類寫了生成縮略圖、打水印等信息,是本次上傳的核心類之一
2.設置編輯器的值和初始化編輯器的值
初始化值值需要一開始賦值給textarea就可以了
設置值editor.html('<h3>Hello KindEditor</h3>');
3.獲取編輯器的值
editor.html()
看到官方的http://kindeditor.net/ke4/examples/default.html例子
很簡單的一次使用編輯器,比以前的很流行的CKEditor好用