最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

编写一个非常简单的JavaScript编辑器

来源:懂视网 责编:小采 时间:2020-11-27 20:24:30
文档

编写一个非常简单的JavaScript编辑器

编写一个非常简单的JavaScript编辑器:当然,我们已经有可以使用的很好的Web编辑器:你只需下载,并插入页面即可。我以前习惯于使用CodeMirror和ACE。例如,我为CodeMirror写了一个插件来支持PlantUML。然而,这些编辑器有一个问题:它们难以扩展和难以理解。当我看到这些产品的代码时,有一些我不
推荐度:
导读编写一个非常简单的JavaScript编辑器:当然,我们已经有可以使用的很好的Web编辑器:你只需下载,并插入页面即可。我以前习惯于使用CodeMirror和ACE。例如,我为CodeMirror写了一个插件来支持PlantUML。然而,这些编辑器有一个问题:它们难以扩展和难以理解。当我看到这些产品的代码时,有一些我不

当然,我们已经有可以使用的很好的Web编辑器:你只需下载,并插入页面即可。我以前习惯于使用CodeMirror和ACE。例如,我为CodeMirror写了一个插件来支持PlantUML。然而,这些编辑器有一个问题:它们难以扩展和难以理解。

当我看到这些产品的代码时,有一些我不能轻易理解,有一些我没有自信可以在上面构建东西。

现在,我的哲学是构建简单的工具,可以工作,可以理解,可以组合和扩展。所以我想尝试另一种方法,从头开始构建一个简单的Web编辑器。

遵循用代码说明一切的原则,请看GitHub repo:https://github.com/ftomassetti/simple-web-editor

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>
 <p id="editor">
 </p>
 <span class="blinking-cursor">|</span>
 <body>
</html>

我们需要做好哪些准备工作?

  • 当然首先是jquery

  • 一些CSS

  • Google提供的酷字体

  • 一个包含所有代码的JS文件(wededitor.js)

  • 一个p(编辑器)和一个用于编辑器的跨度(span)

  • TypeScript

    现在,我们要使用的是TypeScript,希望它可以减少使用JavaScript的痛苦。也因为我想尝试它。对于从未使用过TypeScript的人来说,从根本上说它就是JavaScript的超集,允许可选地指定类型。类型用于检查错误,然后被忘记,因为最终我们生成JavaScript。你可以在TypeScript中使用JavaScript库,并且当你想要使用JavaScript库的时候,你可能需要导入该库中所有类型的描述。这是我们在第一行代码中所导入的内容。

    /// <reference path="defs/jquery.d.ts" /> 
    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类中调用方法。

    结论

    好的,让我们先简单的开始:一个非常小的编辑器,在这个编辑器中我们可以键入、删除和使用箭头移动。这不是最令人印象深刻的编辑器。但它简单,也可以工作。我们可以在此基础上建立一些机智的东西,去做我们要它做的事情,并且可理解和可扩展。

    声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文档

    编写一个非常简单的JavaScript编辑器

    编写一个非常简单的JavaScript编辑器:当然,我们已经有可以使用的很好的Web编辑器:你只需下载,并插入页面即可。我以前习惯于使用CodeMirror和ACE。例如,我为CodeMirror写了一个插件来支持PlantUML。然而,这些编辑器有一个问题:它们难以扩展和难以理解。当我看到这些产品的代码时,有一些我不
    推荐度:
    标签: 一个 js 简单的
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top