自动保存基于localStorage开发,请注意浏览器兼容。(IE7及以下不兼容)。各个浏览器对localStorage的存储大小支持都是不同的,chrome是5M ,IE10是1630K,其他的可以自行测试,基本保存一篇文章绰绰有余了。

1. 插件运行流程

插件使用方法:在编辑区输入内容后,会自动保存内容到客户端本地存储,页面关闭和断电对保存的内容不受影响。保存的内容没有过期时间,直到手动去除。

Created with Raphaël 2.1.2引入插件监听用户输入用户输入自动设置缓存关闭、刷新页面/断电加载缓存提交成功删除缓存yesno

2. 创建插件文件

plugins目录下创建 code-auto-save/code-auto-save.js文件。

3. 页面使用插件

为更方便使用缓存,我们在编辑器的工具栏添加一个自定义的按钮,就和ueditor类似,点击按钮读取缓存内容到编辑器。页面代码如下,都有注释的

  1. <!DOCTYPE html>
  2. <html lang="zh">
  3. <head>
  4. <meta charset="utf-8" />
  5. <title>editormd自动保存插件</title>
  6. <link rel="stylesheet" href="css/style.css" />
  7. <link rel="stylesheet" href="../css/editormd.css" />
  8. </head>
  9. <body>
  10. <div id="test-editormd">
  11. <textarea style="display:none;"></textarea>
  12. </div>
  13. <script src="js/jquery.min.js"></script>
  14. <script src="../editormd.js"></script>
  15. <script type="text/javascript">
  16. var testEditor = editormd("test-editormd", {
  17. path: '../lib/',
  18. // 工具栏添加一个自定义方法
  19. toolbarIcons: function() {
  20. // 给工具栏full模式添加一个自定义方法
  21. return editormd.toolbarModes.full.concat(["customIcon"]);
  22. },
  23. // 自定义方法的图标 指定一个FontAawsome的图标类
  24. toolbarIconsClass: {
  25. customIcon: "fa-paste"
  26. },
  27. // 没有图标可以插入内容,字符串或HTML标签
  28. toolbarIconTexts: {
  29. customIcon: "从草稿箱加载"
  30. },
  31. // 图标的title
  32. lang: {
  33. toolbar: {
  34. customIcon: "从草稿箱加载"
  35. }
  36. },
  37. // 自定义工具栏按钮的事件处理
  38. toolbarHandlers: {
  39. customIcon: function(){
  40. // 读取缓存内容
  41. testEditor.CodeAutoSaveGetCache();
  42. }
  43. },
  44. // 自定义工具栏按钮的事件处理
  45. onload: function() {
  46. // 引入插件 执行监听方法
  47. editormd.loadPlugin("../plugins/code-auto-save/code-auto-save", function() {
  48. // 初始化插件 实现监听
  49. testEditor.CodeAutoSave();
  50. });
  51. }
  52. });
  53. // 删除缓存
  54. testEditor.CodeAutoSaveDelCache();
  55. // 清空缓存的文档内容
  56. testEditor.CodeAutoSaveEmptyCacheContent();
  57. // 自定义设置缓存
  58. testEditor.CodeAutoSaveSetCache('缓存内容');
  59. </script>
  60. </body>
  61. </html>

4. 插件的内容

防止缓存冲突,将页面url作为存储的key进去区分。监听编辑器change事件最好有一小段时间的缓冲,不然操作缓存太频繁造成性能问题。

  1. /*!
  2. * editormd图片粘贴上传插件
  3. *
  4. * @file code-auto-save.js
  5. * @author codehui
  6. * @date 2018-10-27
  7. * @link https://www.codehui.net
  8. */
  9. (function() {
  10. var factory = function (exports) {
  11. // 定义插件名称
  12. var pluginName = "code-auto-save";
  13. // 缓存key
  14. var cacheKey = 'editormd_cache';
  15. // 编辑器内容缓存key 替换url中的符号
  16. var cacheContentKey = ( location.protocol + location.host + location.pathname + location.search ).replace( /[.:?=\/-]/g, '_' );
  17. // 定义全局变量
  18. var cm;
  19. exports.fn.CodeAutoSave = function() {
  20. // 初始化系统变量
  21. var _this = this;
  22. cm = _this.cm;
  23. var settings = _this.settings;
  24. var classPrefix = _this.classPrefix;
  25. var id = _this.id; // 编辑器id
  26. // 定时器
  27. var _saveFlag = null;
  28. // 自动保存间隔时间, 单位ms
  29. var saveInterval = 500;
  30. if(typeof(Storage)=="undefined"){
  31. console.log('对不起,您的浏览器不支持 web 存储。');
  32. return ;
  33. }
  34. // 设置编辑器为当前域名+编辑器id
  35. cacheContentKey = cacheContentKey + "_" + id;
  36. console.log('初始化插件成功');
  37. // 注册change事件
  38. cm.on('change', function(){
  39. //已经存在定时器关闭 重新开始 防止多次执行
  40. if(_saveFlag){
  41. window.clearTimeout( _saveFlag );
  42. }
  43. //定时器的作用是加缓冲
  44. _saveFlag = window.setTimeout( function () {
  45. // 执行设置缓存方法 cm.getValue() 是编辑器的源文档
  46. _this.CodeAutoSaveSetCache(cm.getValue());
  47. }, saveInterval);
  48. })
  49. };
  50. // 设置缓存
  51. exports.fn.CodeAutoSaveSetCache = function(value) {
  52. value = value || cm.getValue();
  53. console.log('设置缓存');
  54. var cacheContent = {};
  55. cacheContent[cacheContentKey] = value;
  56. localStorage.setItem(cacheKey, JSON.stringify(cacheContent));
  57. }
  58. // 读取缓存
  59. exports.fn.CodeAutoSaveGetCache = function() {
  60. // 判断缓存key
  61. if(localStorage.hasOwnProperty(cacheKey)){
  62. var cacheData = JSON.parse(localStorage.getItem(cacheKey));
  63. if(cacheData[cacheContentKey]){
  64. console.log('读取缓存 设置文档内容')
  65. cm.setValue(cacheData[cacheContentKey]);
  66. }
  67. }else{
  68. console.log('缓存中没有数据')
  69. }
  70. }
  71. // 删除缓存
  72. exports.fn.CodeAutoSaveDelCache = function() {
  73. console.log('删除缓存')
  74. localStorage.removeItem(cacheKey);
  75. }
  76. // 清空缓存的文档内容
  77. exports.fn.CodeAutoSaveEmptyCacheContent = function() {
  78. console.log('清除缓存文档内容')
  79. _this.CodeAutoSaveSetCache('');
  80. }
  81. };
  82. // CommonJS/Node.js
  83. if (typeof require === "function" && typeof exports === "object" && typeof module === "object")
  84. {
  85. module.exports = factory;
  86. }
  87. else if (typeof define === "function") // AMD/CMD/Sea.js
  88. {
  89. if (define.amd) { // for Require.js
  90. define(["editormd"], function(editormd) {
  91. factory(editormd);
  92. });
  93. } else { // for Sea.js
  94. define(function(require) {
  95. var editormd = require("./../../editormd");
  96. factory(editormd);
  97. });
  98. }
  99. }
  100. else
  101. {
  102. factory(window.editormd);
  103. }
  104. })();