前言
对于前端来说,用户体验是至关重要的。一个良好的用户体验不仅可以提高用户的满意度,还能增加用户对平台的忠诚度。B站作为中国领先的年轻人文化社区,一直在不断优化其用户体验,其中一项关键技术就是EditInPlace(就地编辑)。完整的代码实现大家可以去我的github仓库里自取 lesson_hm/JS/editInplace at main · wqlblue/lesson_hm
下面是它的体验效果图
大家可以看到它在没有被点击之前是一个文本标签,我们可以假定他为p标签,在点击之后,明显变成了一个可以输入的输入框,即input标签。在这里我们介绍一下今天的主角 ,EditInPlace。
什么是 EditInPlace
EditInPlace是一种允许用户直接在页面上编辑内容而无需跳转到单独页面或弹出窗口的技术。这种交互方式不仅简化了用户的操作流程,还提供了更直观和即时的反馈,极大地提升了用户体验。B站在许多地方使用了EditInPlace,例如用户的个性签名、评论区等,让用户可以轻松地编辑和保存内容。
知道了它是什么,我们想要实现这个功能,就必须先得了解这个功能的需求。这里我们可以把需求分为两个部分。一个是 显示功能的需求 另一个是 编辑功能的需求
显示功能
- 默认状态:用户看到的是一个静态文本,显示当前的个性签名。
- 编辑状态:当用户点击个性签名时,文本会转换为一个可编辑的输入框,同时出现“保存”和“取消”按钮。
编辑功能
- 切换编辑状态:用户点击个性签名后,系统会自动切换到编辑状态,允许用户修改文本。
- 保存更改:用户输入新内容后点击“保存”,系统会更新个性签名并恢复到默认显示状态。
- 取消编辑:如果用户不想保存更改,可以点击“取消”,系统会恢复到原始内容并退出编辑状态。
知道了需求接下来就是我们的代码实现部分
怎么用JS代码去实现这个EditInPlace?
首先我们需要知道,为了实现EditInPlace,我们需要利用DOM编程来动态地控制元素的显示和隐藏。DOM编程就是指通过JavaScript与HTML文档进行交互的过程。
如何呈现文本和编辑状态
我们可以通过CSS的display属性来控制元素的可见性。默认情况下,文本是可见的,而编辑框和按钮是隐藏的。当用户点击文本时,我们切换这些元素的显示状态。
说白了就是获取元素这个标签,通过CSSdisplay属性来控制元素的可见性。默认情况下,文本是可见的,而编辑框和按钮是隐藏的。当用户点击文本时,我们切换这些元素的显示状态。
隐藏一个标签我们通常可以用 display:none 和 visibility:hidden,这里我们采用 前者 display:none ,他们两个虽然都可以隐藏标签,但他们的效果差别很大!
简单总结一下就是
display: none:完全移除元素,不占空间,不可交互,适合彻底隐藏内容。visibility: hidden:隐藏元素但保留其空间,不影响布局,仍可交互,适合临时隐藏内容而不改变布局。 我们先给一个html结构
<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>
代码效果就是这样。
下面我们来实现默认情况下的样式设置!
#content {
display: inline;
}
#input, #Save, #Cancel {
display: none;
}
我们可以用函数封装如果要转换成默认情况,即静态文本情况。
function convertText() {
input.style.display = 'none';
Save.style.display = 'none';
Cancel.style.display = 'none';
content.style.display = 'inline';
// 点击保存后 把输入框的内容 赋值给 content
content.innerHTML = input.value;
}
呢么相反的就是编辑状态,它的文本是隐藏的,而编辑框和按钮是可见的。一样用函数封装!
function convertToEdit() {
// 保存原始内容
originalContent = content.innerHTML;
input.style.display = 'inline';
Save.style.display = 'inline';
Cancel.style.display = 'inline';
content.style.display = 'none';
// 点击编辑后 把 content 的内容 赋值给 input
input.value = content.innerHTML;
}
到现在我们已经基本完成我们想要的功能了,需要注意上面的一个细节,就是每次都需要把值在content组件和 input组件之间互相传递。 这里我们使用的是 content.innerHTML 其实还可以使用innerText , content.innerHTML 的效果是 如果输入的内容中包含HTML标签(如 <b>、<i> 等),就会正确解析和渲染,但innerText 就是显示是<b> 、<i>
innerText:更安全,适合纯文本内容,防止XSS攻击。innerHTML:支持HTML标签,但需谨慎使用,确保输入内容的安全性。
但是我们还有一个Cancel功能呢,即使你已经输入了内容到input框中,如果点了Cancel按钮,就会直接显示没有input的最初的内容,所以需要在全局中声明一个 原始内容
let originalContent = ''; // 用于保存原始内容
然后在变为编辑状态的时候初始化一下原始内容即可originalContent = content.innerHTML; ,当你取消操作时的代码实现如下。
function convertToEditCancel() {
// 恢复原始内容
content.innerHTML = originalContent;
input.style.display = 'none';
Save.style.display = 'none';
Cancel.style.display = 'none';
content.style.display = 'inline';
}
到这里我们就实现了他们的功能需求,完整代码可以去我的github仓库里自取,我把链接放到前言中了。
优化我们的技巧
输入了数据之后,我们怎么去收集它们呢。最常见的方法就是用我们的 <form>标签,<form> 元素本身不会直接显示内容或结果。
它只是一个容器,用于组织和提交用户输入的数据。当用户提交表单后,浏览器会将表单数据发送到指定的URL(通过 action 属性指定),服务器接收并处理这些数据,然后返回一个新的HTML页面或更新当前页面的部分内容。
这里我们搭建一个基本的框架
<form action="http://www.baidu.com" method="post">
<div>
<!-- label 元素可以通过 for 属性与具有相同 id 的输入元素关联,从而提高可访问性。 -->
<label for="input">签名</label>
<input type="text" name="signature" id="input" required="" placeholder="请输入签名">
<div>
<input type="submit" value="提交">
</div>
</div>
</form>
我们还没有搭建一个服务器去处理这些数据,我们可以发送到 百度 试一下看能不能跳转过去
还是OK的,这里的form标签的属性我们要介绍一下
<form>:定义表单的开始和结束。action:指定表单数据提交的目标URL。method:指定提交数据时使用的HTTP方法(通常是GET或POST)。
这里的input标签我们也加了很多属性去完善我们表单的各种功能
name="signature":指定了表单字段的名称,提交时会作为键值对的一部分发送到服务器。id="input":为输入框指定了一个唯一的ID,方便通过CSS或JavaScript进行选择和操作。required="":标记该字段为必填项,用户必须填写才能提交表单。placeholder="请输入签名":提供了提示文本,帮助用户理解应该输入什么内容。
这里的input的id属性不仅仅是为了方便CSS或JavaScript进行选择和操作,还有一个点是可以与 <label> 元素配合使用,通过将 <label> 的 for 属性与 <input> 的 id 属性关联起来,用户可以在点击标签时自动聚焦到相应的输入框。这对于提高表单的可用性,尤其是对于使用屏幕阅读器的用户来说,非常重要。这就是很多大厂都会去做的网页的关怀模式。
END
EditInPlace 他很简单实现,但它对用户体验的提升却是多方面的,对于前端开发者来说,掌握这一技术不仅可以改善用户体验,还能为项目增添更多的互动性和灵活性。在后面我们还可以将流程代码走向面向对象的封装,一步步完善。如有问题,请在评论区与我沟通!