引言
bilibili中,在修改个性签名时,有就地编辑(EditInPlace) 这么一种功能,用户直接在页面上修改内容而无需跳转到单独编辑界面,这种方法即时生效,大大提升了交互效率。今天,我们来使用DOM动态编程完成一个简单的EditInPlace。
传统表单提交
在开始DOM动态编程之前,我们先来使用最原始的传统表单,用户修改个性签名,将修改数据传入后端,再进行修改。但就算使用了比较简单的传统方式,也要注意各种细节,全面优化用户体验。(当然也可以直接使用contenteditable="true" 。 contenteditable 是一个枚举属性,表示元素是否可被用户编辑。)
宗旨:把用户当小白,要为用户考虑一切!!!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 先设置提交到百度 http提交-->
<form action="https://www.baidu.com" method="post">
<div>
<!-- 与input文本框关联 -->
<label for="input">签名</label>
<!-- required 用户没有输入时提示 -->
<!-- placeholder 提示信息 -->
<input type="text" name="signature" id="input" required placeholder="请输入签名">
</div>
<div>
<!-- 提交按钮 -->
<input type="submit" value="提交">
</div>
</form>
</body>
</html>
优化用户体验:
- label:
for
属性将该标签与id
为input
的表单元素关联起来。当用户点击该标签时,与之关联的表单元素将获得焦点,方便用户输入。 - required:表示该输入字段是必填项,用户必须在提交表单前填写该字段,否则会触发浏览器的验证机制。
- placeholder:提示词,为输入字段提供一个占位符文本,当输入字段为空时,会显示该文本,提示用户输入相应信息。
DOM动态编程->就地编辑
相比于传统的表单提交方式,就地编辑具有以下明显优势:
- 减少页面跳转:避免了因打开新页面而导致的时间消耗和用户体验下降。
- 即时反馈:用户可以看到自己所做的修改立刻反映在界面上,增强了参与感。
- 简化操作流程:整个过程更加直观流畅,减少了不必要的步骤,提高了工作效率。
下面,我们来正式开始DOM编程
创建html基本骨架
在html中添加两种模式:文本模式和编辑模式。实现个性签名是要在文本模式和编辑模式之间切换,并给用户设置保存和取消按钮两个按钮。通常情况下,个性签名等信息会以纯文本形式展示给用户。此时,可以使用HTML中的<p>
标签来包裹文本内容。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>EditInPlace 哔哩哔哩用户体验打造</title>
</head>
<body>
<div id="app">
<div id="ep1">
<!-- 文本模式 -->
<span id="content">个性签名???</span>编辑模式
<!-- 编辑模式 -->
<input type="text" id="input" value="个性签名???">
<input type="button" id="save" value="Save">
<input type="button" id="cancel" value="Cancel">
</div>
</div>
<script>
</script>
</body>
</html>
通过DOM获取元素
使用document.getElementById('id')
通过id获取的方式获取上面创建的四个元素
<script>
// 业务编程
// dom js html 节点对象 动态操作html
const content = document.getElementById('content');
const input = document.getElementById('input');
const save = document.getElementById('save');
const cancel = document.getElementById('cancel');
</script>
分别实现两个模式的页面
实现文本模式和编辑模式之间的切换功能。
在开始时,隐藏编辑模式,只显示文本模式。点击文本模式后转为编辑模式,隐藏文本模式,显示编辑模式。隐藏和显示效果我们使用display:none
和display:inline
来完成。(使用display:block
会将几个元素分行显示)
我们将文本模式和编辑模式封装成两个函数,把代码模块化,增强了代码的可读性。在接下来的使用中,只需要调用函数,就能实现两个模式之间的切换。
<script>
// 文本状态
function convertToText() {
// 只显示文本,把其他元素隐藏掉
input.style.display = 'none';
save.style.display = 'none';
cancel.style.display = 'none';
content.style.display = 'inline';
}
// 编辑状态
function convertToEdit() {
// 显示文本框和两个按钮,隐藏文本
input.style.display = 'inline';
save.style.display = 'inline';
cancel.style.display = 'inline';
content.style.display = 'none';
}
convertToText(); //开始状态是文本状态
//convertToEdit(); 检查一下编辑状态
</script>
文本状态:
编辑状态:
添加点击事件
使用addEventListener('click',function(){})
添加点击事件,点击后完成function(){}
中的函数。
完成三件事:
- 需要点击文本转为编辑模式,并将文本内容添加到编辑模式的输入框中。
- 为保存按钮添加点击事件,使用文本框中的内容更新文本,并转换为文本模式。
- 为取消按钮添加点击事件,不做任何处理,切换回文本模式。
input.value:获取用户在输入框中输入的内容
innerText:获取或设置该元素的文本内容。
<script>
// 点击 文本 进入编辑状态
content.addEventListener('click', function () {
convertToEdit();
// 输入框里是最新的签名
input.value = content.innerText;
})
// 点击 save 保存并转换回文本状态
save.addEventListener('click', function () {
content.innerText = input.value;
convertToText();
})
// 点击 cancel 转换回文本状态
cancel.addEventListener('click', function () {
convertToText();
})
</script>
至此,我们已经通过DOM完成了一个简单的个性签名模块 我们来看一下成果:
提升业务能力!!!
上面的设计已经很完美了,但是,在工作上还是远远不够的。我们必须提升我们自己的业务能力。
下面我会给出一个面向对象的EditInPlace模板,走向面向对象封装,我们直接通过代码来分析。大的要来了!!!
html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>面向对象的EditInPlace</title>
</head>
<body>
<!-- 把html结构放在js中 -->
<div id="app">
<!-- <div id='ep1'><span></span></div>-->
</div>
<script src="./editInPlace.js"></script>
<script>
// 流程代码, 走向面向对象封装
// 面向对象封装后 可以使用new快速创建多个实例
new EditInPlace(
'ep1',
document.getElementById('app'),
);
new EditInPlace(
'ep2',
document.getElementById('app'),
'222'
);
new EditInPlace(
'ep3',
document.getElementById('app'),
'333'
);
</script>
</body>
</html>
editInPlace.js文件:
// JSDoc注释 代码规范,写清注释
/**
* @func 就地编辑
* @params {id,parent 父节点,value 默认值} //参数
* @author zzz
* @date 2024-11-28
*/
function EditInPlace(id, parent, value) {
// this指向新创建的对象
this.id = id; // 跨函数共享属性 可以在当前对象的其他方法中被访问和使用,实现了属性在不同函数之间的共享。
// 两手准备 传参数和没有传参数 严谨
this.parent = parent || document.body; // 传递父节点 如果没有参数 页面根节点body
this.value = value || '这个家伙很懒,什么都没有留下'; // 默认值
this.createElement(this.id); // 创建html标签
}
EditInPlace.prototype.createElement = function (id) {
// console.log(id);
// 下面三行相当于 <div ip='ep1'></div> 完成在js中生成html结构
this.containerElement = document.createElement('div'); // 创建div标签
this.containerElement.id = this.id; //设置id
this.parent.appendChild(this.containerElement); // 在父节点中创建该子节点标签
this.staticElement = document.createElement('span');
this.staticElement.innerText = this.value;
this.containerElement.appendChild(this.staticElement); // 再从刚刚创建的div中创建span,并赋值
}
结果展示
你也可以试着将该部分与上面的内容相结合,期待你的结果。
结语
总之,就地编辑技术并不复杂,使用DOM就能很好的完成需求。但对于新手开发者而言,如何提升自己的业务能力,规范代码完成任务,非常重要,这也是在去大厂时必须要有的个人能力。