五分鐘 -- 從零開始搭建屬於本身的網頁編輯器

固然是不可能的。。。
若是你還有興趣繼續看的話,想和你們交流一下我最近作的一個能夠顯示行數的textarea。只是一個不到300行代碼的小玩具啦。演示代碼
圖片描述css

(專業的wysiwyg或者代碼編輯器,請看quilljs, ace editor等)git

最近接到這麼一個需求,要對一個textarea的數據進行格式驗證。用戶會輸入幾十個幾百個IP地址,一行一個。驗證是很容易,可是若是出錯的話,用戶並不知道是哪裏出的錯。textarea是不能加style的,因此我想能不能顯示行數,這樣就能夠反饋給用戶是哪裏出錯了。github

HTML 結構

<div>
  <div>
    <p>1</p>
    <p>2</p>
    <p>3</p>
    <p>4</p>
  </di>
  <textarea></textarea>
</div>

幾個實現上要考慮的問題

左邊顯示行數的DIV要和右邊的textarea保持相同的高度。

圖片描述

css的flexbox能夠很好的解決這個問題。(不用寫js代碼啦)chrome

支持滾輪(scroll,兩邊要同步)

圖片描述

右邊textarea若是滾動了,左邊的div也要跟着滾。瀏覽器

聽scroll事件,更新左邊div的transform: translateY()值。這個聽說是比topbottom快。編輯器

左邊div寬度更新

圖片描述

由於用了position: abosolute,因此這一塊要手動處理。首先算最長的長度,再更新div的padding-left的值。flex

檢測何時換行了

圖片描述

圖中紅叉的地方是不應顯示行數的,由於是在同一個句子內。這就須要計算一個句子會佔多少行。這就麻煩了,這一塊我寫的很差。ui

首先要算一行能放多少的字符。我用的方法是新建一個div,不斷往裏面加字符,測寬度,而後和textarea的寬度做比較。若是正好能被容納,那麼那個div裏的字符數就是咱們要求的值。這個方法不光聽起來就蠢,還不許確。請看下圖。
圖片描述flexbox

實際可用寬度是36.534,實際文字寬度是36.6477,因此是放不下的。可是clientWidth的精度只到整數,測下來是37,按這個結果看的話,那段文字是能夠放得下的。[掀桌子](爲何要用clientWidth?由於滾動條會佔空間。)這就麻煩了。spa

而後就是要算每個句子都佔多少行。(在white-space: pre-wrap的狀況下)這也很麻煩,這個換不換行是瀏覽器決定的,要精確地還原彷佛也不大容易。對空格,減號的處理都有特殊狀況。這個我也就作了一個大概。

更新可用寬度

三種狀況須要更新textarea的可用寬度:

  1. 左邊div寬度改變
  2. 滾動條的出現/消失
  3. 拖拽改變textarea的大小

對於1,咱們以前就處理過,好改。
對於2,聽一下input事件,看textarea的clientHeight有沒有變。滾動條是會佔用clientHeight的。
對於3,textarea沒有resize事件,又要手動弄了。查了一下是要聽鼠標點擊和鬆開事件。因而我作了下面的試驗:

圖片描述

圖片描述圖片描述圖片描述

相同的操做:在textarea上按下鼠標,移開到textarea以外放開。結果三個瀏覽器的結果全不同!不過至少都能聽到mousedown事件,總算有切入的地方。具體實現能夠看代碼,文字敘述不大容易。要注意的是mousemove也要聽,不然這樣:

圖片描述

還有一個寫代碼時我遇到的問題是若是把textarea縮到很小,瀏覽器就卡住了。直覺是遇到無限循環了。果真,是由於一行內一個字符也容不下的時候,那麼就須要無限行。加了一個特殊條件處理的if以後解決了。

不換行

這個firefox和edge還不同(我只試了三個瀏覽器,外加chrome)。一個要用white-space: pre,一個要用white-space: nowrap。(chrome均可以)

結束

固然,真正要作網頁編輯器的話是不可能用textarea的,個人這個東西在有限的場景裏多是會有用的。想了解實際的編輯器能夠看這個文章

第一次發文章,不是教程,算是經驗交流吧。歡迎你們討論。

相關文章
相關標籤/搜索