当我们要修改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
2 hello.txt
3 编辑
4
5
6 functionedit() {7 editText('text',function(data) {8 console.log('新文本:' +data);9 });10 }11
12
演示一下行内编辑效果:
最后我们可以把它封装成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($('').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
2 hello.txt
3 编辑
4
5
6
7 functionedit() {8 $('#text').editText();//可以不带回调函数
9 }10
11