小鱼大大的Pen好像不少粉的样子,这几天看了看,学习了一下git
编辑的原理依赖 div 上的 contenteditable 属性
开启和关闭功能是下面的destroy rebuild函数github
Pen.prototype.destroy = function(isAJoke) { var destroy = isAJoke ? false : true , attr = isAJoke ? 'setAttribute' : 'removeAttribute'; if(!isAJoke) { this._sel.removeAllRanges(); this._menu.style.display = 'none'; } this._isDestroyed = destroy; this.config.editor[attr]('contenteditable', ''); return this; }; Pen.prototype.rebuild = function() { return this.destroy('it\'s a joke'); };
若是是低端浏览器,兼容方案为设置div.pen.innerHTML = 一个textarea
stay功能的实现数组
window.onbeforeunload = function() { if(!that._isDestroyed) return 'Are you going to leave here?'; };
menu函数使得选中文字后 toolbar 居中显示浏览器
// show menu Pen.prototype.menu = function() { var offset = this._range.getBoundingClientRect() , top = offset.top - 10 , left = offset.left + (offset.width / 2) , menu = this._menu; // display block to caculate it's width & height menu.style.display = 'block'; menu.style.top = top - menu.clientHeight + 'px'; menu.style.left = left - (menu.clientWidth/2) + 'px'; return this; };
好了 正式流程为:markdown
固然他还有markdown插件
1. 每次 keypress 的时候会触发 parse
2. parse 对输入push到数组covertor.stack中
3. 判断为空格按下 则把 stack中的命令取出 执行valid
4. valid经过的,则进入 action环节 渲染输出不一样的格式dom
写的很是粗糙,主要为了记录一下流程
还有我以为Pen大量的时间精力都在处理toolbar highlight和节点查找 判断上
虽然短短300行,依然提供了较好的体验.源码值得一看
附上简短的3个util :D函数
// type detect utils.is = function(obj, type) { return Object.prototype.toString.call(obj).slice(8, -1) === type; }; // 判断类型 // copy props from a obj utils.copy = function(defaults, source) { for(var p in source) { if(source.hasOwnProperty(p)) { var val = source[p]; defaults[p] = this.is(val, 'Object') ? this.copy({}, val) : this.is(val, 'Array') ? this.copy([], val) : val; } // 深层复制 } return defaults; }; // log utils.log = function(message, force) { if(window._pen_debug_mode_on || force) console.log('%cPEN DEBUGGER: %c' + message, 'font-family:arial,sans-serif;color:#1abf89;line-height:2em;', 'font-family:cursor,monospace;color:#333;'); };