首页 > 技术文章 > 简单html行内编辑插件

viewts 2019-05-07 15:53 原文

当我们要修改h5页面上的一个表格或者段落的文本时候,通常的方法弹出一个模态对话框来提示用户输入,点击确认后根据输入的内容来修改文本节点,但这样用户体验肯定不是很好。之前看到有x-editable插件可以很好的进行行内编辑,拿来使用却发现和我用的bootstrap4不太兼容,无奈自己动手实现一个吧。

首先,理清行内编辑的基本原理:选中要编辑的DOM节点,先保存文本节点值然后插入一个文本输入框,当按下回车键的时候保存文本框输入的值同时移除文本输入框。是不是很简单?不过需要注意的是和文件重命名一样,不要默认选中文件后缀名,也不允许输入空文本。editText.js如下:

 1 // 行内文本编辑
 2 function editText(id, callback = null) {
 3     let node = document.getElementById(id);
 4     let text = node.innerText;
 5     // 插入文本框
 6     let input = document.createElement('input');
 7     input.type = 'text';
 8     input.placeholder = '输入文本不能为空';
 9     input.spellcheck = false;
10     input.value = text;
11     node.innerText = '';
12     node.append(input);
13     // 选中文本
14     let end = text.search(/\.\w+$/);
15     input.focus();
16     input.selectionStart = 0;
17     input.selectionEnd = (end == -1) ? text.length : end;
18     // 按键事件
19     input.onkeydown = function(e) {
20         // 按下回车键
21         if (e.keyCode == 13) {
22             let data = this.value;
23             if (data == '') {
24                 return;
25             } else {
26                 input.onblur = false;
27                 this.remove();
28                 node.innerText = data;
29                 if (callback) {
30                     callback(data);
31                 }
32             }
33         // 按下ESC键
34         } else if (e.keyCode == 27) {
35             input.onblur = false;
36             this.remove();
37             node.innerText = text;
38         }
39     }
40     // 失去焦点默认完成编辑
41     input.onblur = function() {
42         let data = this.value;
43         this.remove();
44         if (data == '') {
45             node.innerText = text;
46         } else {
47             node.innerText = data;
48             if (callback) {
49                 callback(data);
50             }
51         }
52     }
53 }

这里使用id选中元素,然后插入文本输入框编辑,可以传入一个回调函数来处理编辑后的数据。需要注意的是当编辑完成remove输入框的时候会触发blur事件,所以我添加了input.onblur = false来取消该事件,以防止重复移除,这句写成this.onblur = false也行,不过vscode编辑器会提示你“此构造函数可能会转换为类声明”,因为我们以前就是用函数来申明类型的。该函数调用过程也非常简单:

 1 <body>
 2     <p id="text">hello.txt</p>
 3     <button onclick="edit()">编辑</button>
 4     <script src="./editText.js"></script>
 5     <script>
 6         function edit() {
 7             editText('text', function(data) {
 8                 console.log('新文本:' + data);
 9             });
10         }
11     </script>
12 </body>

演示一下行内编辑效果:

最后我们可以把它封装成jquery插件,方便以后调用,改名为jquery.editText.js:

 1 $.fn.extend({
 2     editText: function(callback = null) {
 3         let $node = $(this);
 4         let text = $node.text();
 5         $node.text('').append($('<input>').attr({type:'text', placeholder:'输入文本不能为空', spellcheck:false}).val(text).on({
 6             keydown: function(e) {
 7                 if (e.keyCode == 13) {
 8                     let data = $(this).val();
 9                     if (data == '') {
10                         return;
11                     } else {
12                         $(this).remove();
13                         $node.text(data);
14                         if (callback) {
15                             callback(data);
16                         }
17                     }
18                 } else if (e.keyCode == 27) {
19                     $(this).remove();
20                     $node.text(text);
21                 }
22             },
23             blur: function() {
24                 let data = $(this).val();
25                 $(this).remove();
26                 if (data == '') {
27                     $node.text(text);
28                 } else {
29                     $node.text(data);
30                     if (callback) {
31                         callback(data);
32                     }
33                 }
34             },
35             focus: function() {
36                 let end = text.search(/\.\w+$/);
37                 this.setSelectionRange(0, end == -1 ? text.length : end);
38             }
39         })).children('input:first').focus();
40     }
41 });

引入jquery后即可使用:

 1 <body>
 2     <p id="text">hello.txt</p>
 3     <button onclick="edit()">编辑</button>
 4     <script src="./jquery-3.4.1.min.js"></script>
 5     <script src="./jquery.editText.js"></script>
 6     <script>
 7         function edit() {
 8             $('#text').editText();//可以不带回调函数
 9         }
10     </script>
11 </body>

 

推荐阅读