小魚大大的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;'); };