Markdown編輯器Editor.md自動保存插件的開發(fā)靶端。文章編輯器沒有自動保存功能怎么行,萬一不小心忘記保存不就辛苦白費了拄氯,然后就著手給自己的編輯器加了個自動保存功能躲查,分享給有需要的朋友。
原文地址:代碼匯個人博客 http://www.codehui.net/info/40.html
- 此文章代碼僅供參考译柏。用于開發(fā)環(huán)境時可根據(jù)自己需要進行修改镣煮。
自動保存
基于localStorage
開發(fā),請注意瀏覽器兼容鄙麦。(IE7及以下不兼容)典唇。各個瀏覽器對localStorage
的存儲大小支持都是不同的,chrome是5M 胯府,IE10是1630K介衔,其他的可以自行測試,基本保存一篇文章綽綽有余了骂因。
1. 插件運行流程
插件使用方法:在編輯區(qū)輸入內(nèi)容后,會自動保存內(nèi)容到客戶端本地存儲炎咖,頁面關(guān)閉和斷電對保存的內(nèi)容不受影響。保存的內(nèi)容沒有過期時間寒波,直到手動去除乘盼。
2. 創(chuàng)建插件文件
在plugins
目錄下創(chuàng)建 code-auto-save/code-auto-save.js
文件。
3. 頁面使用插件
為更方便使用緩存俄烁,我們在編輯器的工具欄添加一個自定義的按鈕绸栅,就和ueditor
類似,點擊按鈕讀取緩存內(nèi)容到編輯器页屠。頁面代碼如下粹胯,都有注釋的
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8" />
<title>editormd自動保存插件</title>
<link rel="stylesheet" href="css/style.css" />
<link rel="stylesheet" href="../css/editormd.css" />
</head>
<body>
<div id="test-editormd">
<textarea style="display:none;"></textarea>
</div>
<script src="js/jquery.min.js"></script>
<script src="../editormd.js"></script>
<script type="text/javascript">
var testEditor = editormd("test-editormd", {
path: '../lib/',
// 工具欄添加一個自定義方法
toolbarIcons: function() {
// 給工具欄full模式添加一個自定義方法
return editormd.toolbarModes.full.concat(["customIcon"]);
},
// 自定義方法的圖標 指定一個FontAawsome的圖標類
toolbarIconsClass: {
customIcon: "fa-paste"
},
// 沒有圖標可以插入內(nèi)容,字符串或HTML標簽
toolbarIconTexts: {
customIcon: "從草稿箱加載"
},
// 圖標的title
lang: {
toolbar: {
customIcon: "從草稿箱加載"
}
},
// 自定義工具欄按鈕的事件處理
toolbarHandlers: {
customIcon: function(){
// 讀取緩存內(nèi)容
testEditor.CodeAutoSaveGetCache();
}
},
// 自定義工具欄按鈕的事件處理
onload: function() {
// 引入插件 執(zhí)行監(jiān)聽方法
editormd.loadPlugin("../plugins/code-auto-save/code-auto-save", function() {
// 初始化插件 實現(xiàn)監(jiān)聽
testEditor.CodeAutoSave();
});
}
});
// 刪除緩存
testEditor.CodeAutoSaveDelCache();
// 清空緩存的文檔內(nèi)容
testEditor.CodeAutoSaveEmptyCacheContent();
// 自定義設(shè)置緩存
testEditor.CodeAutoSaveSetCache('緩存內(nèi)容');
</script>
</body>
</html>
4. 插件的內(nèi)容
防止緩存沖突辰企,將頁面url作為存儲的key進去區(qū)分风纠。監(jiān)聽編輯器change
事件最好有一小段時間的緩沖,不然操作緩存太頻繁造成性能問題牢贸。
/*!
* editormd圖片粘貼上傳插件
*
* @file code-auto-save.js
* @author codehui
* @date 2018-10-27
* @link https://www.codehui.net
*/
(function() {
var factory = function (exports) {
// 定義插件名稱
var pluginName = "code-auto-save";
// 緩存key
var cacheKey = 'editormd_cache';
// 編輯器內(nèi)容緩存key 替換url中的符號
var cacheContentKey = ( location.protocol + location.host + location.pathname + location.search ).replace( /[.:?=\/-]/g, '_' );
// 定義全局變量
var cm;
exports.fn.CodeAutoSave = function() {
// 初始化系統(tǒng)變量
var _this = this;
cm = _this.cm;
var settings = _this.settings;
var classPrefix = _this.classPrefix;
var id = _this.id; // 編輯器id
// 定時器
var _saveFlag = null;
// 自動保存間隔時間议忽, 單位ms
var saveInterval = 500;
if(typeof(Storage)=="undefined"){
console.log('對不起,您的瀏覽器不支持 web 存儲十减。');
return ;
}
// 設(shè)置編輯器為當前域名+編輯器id
cacheContentKey = cacheContentKey + "_" + id;
console.log('初始化插件成功');
// 注冊change事件
cm.on('change', function(){
//已經(jīng)存在定時器關(guān)閉 重新開始 防止多次執(zhí)行
if(_saveFlag){
window.clearTimeout( _saveFlag );
}
//定時器的作用是加緩沖
_saveFlag = window.setTimeout( function () {
// 執(zhí)行設(shè)置緩存方法 cm.getValue() 是編輯器的源文檔
_this.CodeAutoSaveSetCache(cm.getValue());
}, saveInterval);
})
};
// 設(shè)置緩存
exports.fn.CodeAutoSaveSetCache = function(value) {
value = value || cm.getValue();
console.log('設(shè)置緩存');
var cacheContent = {};
cacheContent[cacheContentKey] = value;
localStorage.setItem(cacheKey, JSON.stringify(cacheContent));
}
// 讀取緩存
exports.fn.CodeAutoSaveGetCache = function() {
// 判斷緩存key
if(localStorage.hasOwnProperty(cacheKey)){
var cacheData = JSON.parse(localStorage.getItem(cacheKey));
if(cacheData[cacheContentKey]){
console.log('讀取緩存 設(shè)置文檔內(nèi)容')
cm.setValue(cacheData[cacheContentKey]);
}
}else{
console.log('緩存中沒有數(shù)據(jù)')
}
}
// 刪除緩存
exports.fn.CodeAutoSaveDelCache = function() {
console.log('刪除緩存')
localStorage.removeItem(cacheKey);
}
// 清空緩存的文檔內(nèi)容
exports.fn.CodeAutoSaveEmptyCacheContent = function() {
console.log('清除緩存文檔內(nèi)容')
_this.CodeAutoSaveSetCache('');
}
};
// CommonJS/Node.js
if (typeof require === "function" && typeof exports === "object" && typeof module === "object")
{
module.exports = factory;
}
else if (typeof define === "function") // AMD/CMD/Sea.js
{
if (define.amd) { // for Require.js
define(["editormd"], function(editormd) {
factory(editormd);
});
} else { // for Sea.js
define(function(require) {
var editormd = require("./../../editormd");
factory(editormd);
});
}
}
else
{
factory(window.editormd);
}
})();