編寫一個非常簡單的 JavaScript 編輯器

2021-03-06 動力節點Java學院

當然,我們已經有可以使用的很好的Web編輯器:你只需下載,並插入頁面即可。我以前習慣於使用CodeMirror和ACE。例如,我為CodeMirror寫了一個插件來支持PlantUML。然而,這些編輯器有一個問題:它們難以擴展和難以理解。

當我看到這些產品的代碼時,有一些我不能輕易理解,有一些我沒有自信可以在上面構建東西。

現在,我的哲學是構建簡單的工具,可以工作,可以理解,可以組合和擴展。所以我想嘗試另一種方法,從頭開始構建一個簡單的Web編輯器。

HTML

讓我們從一些HTML代碼開始:

<html> <head> <link rel="stylesheet" type="text/css" href="css/style.css" media="screen" /> <script src="js/jquery-3.1.1.min.js"></script> <script src="js/webeditor.js"></script> <link href="https://fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet"> </head> <body> <h1>My Simple Web Editor</h1> <div id="editor"> </div> <span class="blinking-cursor">|</span> <body></html>

我們需要做好哪些準備工作?

當然首先是jquery

一些CSS

Google提供的酷字體

一個包含所有代碼的JS文件(wededitor.js)

一個div(編輯器)和一個用於編輯器的跨度(span)

TypeScript

現在,我們要使用的是TypeScript,希望它可以減少使用JavaScript的痛苦。也因為我想嘗試它。對於從未使用過TypeScript的人來說,從根本上說它就是JavaScript的超集,允許可選地指定類型。類型用於檢查錯誤,然後被忘記,因為最終我們生成JavaScript。你可以在TypeScript中使用JavaScript庫,並且當你想要使用JavaScript庫的時候,你可能需要導入該庫中所有類型的描述。這是我們在第一行代碼中所導入的內容。

class Editor { private caretIndex: number; private text: string; constructor() { this.caretIndex = 0; this.text = ""; } textBeforeCaret() { if (this.caretIndex == 0) { return ""; } else { return this.text.substring(0, this.caretIndex); } } textAfterCaret() { if (this.caretIndex == this.text.length) { return ""; } else { return this.text.substring(this.caretIndex ); } } generateHtml() { return this.textBeforeCaret() + "<span class='cursor-placeholder'>|</span>" + this.textAfterCaret(); } type(c:string) { this.text = this.textBeforeCaret() + c + this.textAfterCaret(); this.caretIndex = this.caretIndex + 1; } deleteChar() : boolean { if (this.textBeforeCaret().length > 0) { this.text = this.textBeforeCaret().substring(0, this.textBeforeCaret().length - 1) + this.textAfterCaret(); this.caretIndex--; return true; } else { return false; } } moveLeft() : boolean { if (this.caretIndex == 0) { return false; } else { this.caretIndex--; return true; } } moveRight() : boolean { if (this.caretIndex == this.text.length) { return false; } else { this.caretIndex++; return true; } } } var updateHtml = function() { $("#editor")[0].innerHTML = (window as any).editor.generateHtml(); var cursorPos = $(".cursor-placeholder").position(); var delta = $(".cursor-placeholder").height() / 4.0; $(".blinking-cursor").css({top: cursorPos.top, left: cursorPos.left - delta});}; $( document ).ready(function() { (window as any).editor = new Editor(); updateHtml(); $(document).keypress(function(e){ var c = String.fromCharCode(e.which); (window as any).editor.type(c); updateHtml(); }); $(document).keydown(function(e){ if (e.which == 8 && (window as any).editor.deleteChar()) { updateHtml(); }; if (e.which == 37 && (window as any).editor.moveLeft()) { updateHtml(); }; if (e.which == 39 && (window as any).editor.moveRight()) { updateHtml(); }; });});

好的,讓我們來看看代碼。我們有:

Editor類

函數updateHTML

$(document).ready(…)格式的配線(wiring)

Editor類

Editor類是我們要做文章下功夫的地方。這裡我們存儲兩樣東西:

包含在編輯器中的文本

文本中插入符的位置

TextBeforeCaret和TextAfterCaret顯然允許我們得到所有文本之前或之後的插入符。

那麼,generateHTML做什麼呢?它生成HTML代碼,用於放置跨度以指示插入符位置的文本:此元素是插入符佔位符。為什麼我們不放置插入符本身呢?因為插入符有大小,所以如果我們在文本內部移動插入符,那麼我們將導致所有的文本總是在移動。相反,我們移動大小為零的插入符佔位符,然後我們使用插入符放置在插入符佔位符上方,但在不同的z-index。通過這種方式,基本上我們就可以在我們想要看到的地方看到插入符,而不必左右移動文本就為了給插入符空出地方。

其餘的方法允許:

插入字符

刪除字符

向左移動插入符

向右移動插入符

函數updateHTML

函數updateHTML實現了插入符的把戲:

var updateHtml = function() { $("#editor")[0].innerHTML = (window as any).editor.generateHtml(); var cursorPos = $(".cursor-placeholder").position(); var delta = $(".cursor-placeholder").height() / 4.0; $(".blinking-cursor").css({top: cursorPos.top, left: cursorPos.left - delta});};

首先我們更新編輯器的內容,然後我們找到插入符佔位符的位置,然後我們移動位於佔位符上方的閃爍光標(即佔位符)。我們實際上會稍微向左移動一點佔位符,因為這樣看起來更好。

配線(wiring)

配線包括附加事件處理程序到:

當我們鍵入字符的時候獲取

當我們刪除字符的時候獲取

當我們使用左箭頭和右箭頭的時候獲取

然後我們從Editor類中調用方法。

結論

好的,讓我們先簡單的開始:一個非常小的編輯器,在這個編輯器中我們可以鍵入、刪除和使用箭頭移動。這不是最令人印象深刻的編輯器。但它簡單,也可以工作。我們可以在此基礎上建立一些機智的東西,去做我們要它做的事情,並且可理解和可擴展。

相關焦點

  • 不可不知的 5 種 JavaScript 代碼編輯器
    代碼編輯器對於程式設計師來說是不可或缺的,其中JavaScript是一款非常熱門的程式語言。
  • 編輯器聖戰之Emacs篇
    你可以通過編寫自己的配置文件來配置你的專屬Emacs。另外,像Emacs和VIM這類鍵綁定編輯器,使得你在Emacs或VIM區域內的任何操作都可以使用鍵盤完成,鍵盤黨必備,滑鼠去死吧。誠然,這有一定的學習曲線,但絕對不至於難以掌握,一旦掌握,樂趣無窮。Editor最大的優點是,當你開始使用一種新語言或是一種新框架開始編程之旅時,你可以十分簡單的加載相關的plugin來幫助你開發。
  • WEB編輯器哪家強
    作為一名coder,像VS Code這樣的代碼編輯器自然是必不可少的,你還可以使用類似CodeSandbox這樣的online編輯器開發demo程序。編輯器更多是作為工具方便我們進行日常的代碼開發工作,倘若將編輯器視作產品的一部分為其提供可擴展的能力,我們該如何應對。答案是:web編輯器,現在熱門的可視化頁面搭建系統便是一個典型的案例。
  • 2019年最受國外程式設計師青睞的6款文本編輯器
    文本編輯器的選擇是很多初學編程者在學習編程時需要考慮的問題之一,現在文本編輯器的種類很多,但並不是每一款都那麼好用,那麼適合自己,選擇一個好的文本編輯器能夠提高程序工作的效率,達到事半功倍的效果。今天圈兒整理了2019年國外程式設計師最喜歡使用的6款文本編輯器給大家分享一下,希望大家喜歡。
  • 10個優化代碼的CSS和JavaScript工具
    檢查和測試代碼來發現任何潛在錯誤,從而在放到網站上之前及時消除錯誤是一個非常重要的過程。
  • 所見即所得富文本編輯器實現原理
    ,富文本編輯器常用於編輯博客、用戶交互,富文本編輯器分為兩種:所見即所得和非所見即所得兩種富文本編輯器的實現原理是不相同的。非所見即所得編輯器這種編輯器的實現原理很簡單,用textarea元素就可以實現,假如要實現粗體、斜體、下劃線、顏色字、圖片的效果,只需在字的中間加上自定義標籤即可,例如: [b]富文本編輯器[b] ,[img]src=」http://www.google.com.hk/intl/zh-CN/images/logo_cn.png」[img]當然這些規則你得自己通過js進行定製
  • 如何在 Ubuntu/Debian Linux 上編寫、編譯和運行一個 C 程序
    你是如何在 Linux 上使用 C 編寫你的程序的?它確實是非常簡單的,由三個簡單的步驟組成。步驟 1: 編寫你的 C 程序,並使用一個 .c 的擴展名進行保存。例如,my_program.c 。
  • 推薦十大最受歡迎的markdown編輯器!
    自2004年以來,基於文本的標記語言就出現了,當時John Gruber將其發布為HTML的簡單替代品。儘管Markdown年代久遠,但它的受歡迎程度一直在增長,從GitHub到Reddit和Medium,它都無處不在,並且已成為在網絡上的編寫東西的最喜歡的方式。隨著它的普及,出現了許多Markdown編輯器,使製作內容變得更加簡單。下面,我們看一下最受用戶喜愛的10個編輯器。1.
  • 打造一個優雅的微信文章編輯器
    之前訪問了下百度和404搜尋引擎,總結一下大家提供的方法,無非是三種:下載Chrome瀏覽器插件 MarkdownHere,在上面先自定義好自己想要的css樣式,然後再微信富文本編輯器上用 markdown語法寫好文章內容,再一鍵轉換,但你會發現,效果差強人意;使用第三方平臺的微信排版器,如下圖:  非常蛋疼是,基本上是卡片式寫作,每寫一段就要拖動出來一個新的卡片容器
  • 讓medit 成為你的下一個 Linux 代碼編輯器
    讓 medit 成為你的下一個 Linux 代碼編輯器 這款經典的文本編輯器提供了所有的基本功能和一些讓你自定義你的體驗的令人興奮的功能。在我開始搜索我還沒有嘗試過的編輯器之前,我還沒有聽說過 medit,但我很高興發現了它。如果你正在尋找經典的 gedit 體驗(大約是 Gnome 2 上),那麼 medit 可能無意間提供了一種出色且現代的近似體驗。它也有許多額外的功能,比如可以使用 Python、Lua 或 C 語言編寫插件,以及甚至可以將 shell 腳本集成到菜單系統。
  • 幾個非常有意思的javascript知識點總結
    移除script標籤後事件仍然能執行的原因這個問題主要是之前有朋友問過我,當時的想法就是簡單的認為script內的代碼執行完之後以及與dom綁定了,存放在了瀏覽器內存中,最近查了很多資料發現有一個有點意思的解釋,放出來大家可以感受一下:JavaScript解釋器在執行腳本時,是按塊來執行的,也就是說瀏覽器在解析
  • 如何在javascript中創建一個對象?
    javascript是一門基於對象而不是面向對象的語言,由於它的這個缺陷,在javascript中實現面向對象時十分彆扭,就比如創建對象,由於在ES6之前沒有class關鍵字,想要創建對象必須依賴以下幾種間接方式。
  • 5款最受Python開發者歡迎的Python IDE和代碼編輯器
    5個Python IDE和文本編輯器的比較在本文中,我們將介紹5個熱門的Python IDE和5個Python文本編輯器。根據您的領域,價格和功能-您將看到最適合您的Python IDE和代碼編輯器。分不清是使用Eclipse這樣的IDE,還是應該使用Sublime文本這樣簡單的東西?那麼本文就為你詳細介紹這些知識。
  • 教你用十行代碼編寫一個Python小遊戲!不信?來看看!
    可以去Python官網下載最新的安裝包進行安裝,然後便可以使用Python提供的IDLE編輯器來編寫代碼了。且慢,你是否覺得使用IDLE編輯器來編寫程序不是那麼方便呢?對於簡單的小程序當然無所謂了,但是遊戲程序相對來說還是比較複雜的,而且遊戲中需要調用一些圖片或聲音資源,我們還要對所有的遊戲資源進行統一管理。因此我們還得尋找一個更加靈活方便的遊戲編寫工具,在這裡我採用的是Mu編輯器。
  • 程式設計師最愛用的10款JavaScript編輯器
    對於一名JavaScript程式設計師來說,目前有很多很好的代碼編輯器工具可以去選擇。
  • MarkDown編輯器
    WORD或者富文本編輯器,But,當我們辛辛苦苦寫了一篇文章,但因為格式,顏色等因素給人不舒服的感覺,就想換一個編輯器了,所以,查看網際網路各個便器器,發現MarkDown編寫最為簡單、好看,所以就整理了各個MarkDown編輯器,如果小夥伴們需要編輯軟體,都可以去官網下載哦。
  • 推薦幾個文檔編輯器
    對於從事網絡編輯工作的人員來說,一款功能強大的文本編輯器是必不可少的,一般自帶的記事本,功能相對比較簡單,對於一些特殊的功能,例如:編輯文本、
  • 20個常用的JavaScript簡寫技巧
    任何程式語言的簡寫技巧都能夠幫助你編寫更簡練的代碼,讓你用更少的代碼實現你的目標。讓我們一個個來看看 JavaScript 的簡寫技巧吧。 1. 聲明變量 2.
  • 使用Mu 編輯器教授 Python
    IDLE 是一個很大的改進,但在克利夫蘭的 PyConUS 2019 上,我看到了Nicholas Tollervey的演講,這改變了我學習和教授 Python 的方式。Nick 是一位教育家,他創建了Mu,一個專門為年輕程式設計師(甚至像我這樣的老程式設計師)設計的 Python 編輯器。Mu 可以安裝在 Linux、macOS 和 Windows 上。