在现代网页开发中,用户体验(UX)是至关重要的。B站的就地编辑(EditInPlace)功能是一个典型的例子,它允许用户在不离开当前页面的情况下,直接编辑和保存内容。这种功能在很多平台上都很常见,可以显著提升用户的交互体验。本文将详细讨论如何实现这一功能。
用户体验
就地编辑的用户体验包括以下几个方面:
- 平时文本状态:默认情况下显示签名等静态文本。
- 编辑状态:鼠标悬停或点击时进入编辑状态,显示编辑框。
- 退出编辑状态:自动保存修改并切换回文本状态。
这种交互模式可以让用户在不离开当前页面的情况下,快速编辑和保存信息,提高用户的操作效率和满意度。
实现思路
实现就地编辑功能需要考虑以下几个技术点:
- 事件处理:通过事件监听来切换编辑和文本状态。
- 类的封装:使用类来封装功能,以便复用和维护。
- 本地存储:利用
localStorage
保存编辑内容。 - 异步请求:模拟后端数据,通过
fetch
获取和更新数据。
代码实现
HTML结构
首先,我们需要一个简单的HTML结构来挂载我们的就地编辑功能:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>就地编辑</title>
</head>
<body>
<div id="signature"></div>
<script src="./edit_in_place.js"></script>
<script>
// 初始化就地编辑功能
const STORAGEKEY = 'signature';
fetch("http://localhost:3000/users/1")
.then(res => res.json())
.then(data => {
const { signature } = data;
const stoSignature = localStorage.getItem(STORAGEKEY);
if (signature !== stoSignature) {
localStorage.setItem(STORAGEKEY, signature);
}
new EditInPlace(STORAGEKEY, document.getElementById('signature'), signature);
});
</script>
</body>
</html>
EditInPlace 类
我们使用ES5的构造函数来创建EditInPlace类,并定义其方法:
function EditInPlace(storageKey, container, value = '编辑个性签名') {
this.storageKey = storageKey;
this.container = container;
this.value = value;
this.createElement();
this.attachEvents();
}
EditInPlace.prototype = {
createElement: function() {
//创建一个div
this.editElement = document.createElement('div');
//添加一个子元素
this.container.appendChild(this.editElement);
// signature 文本值
this.staticElement = document.createElement('span');
this.staticElement.innerHTML = this.value;
this.editElement.appendChild(this.staticElement);
//input
this.fieldElement = document.createElement('input');
this.fieldElement.type = 'text';
this.fieldElement.value = this.value;
this.editElement.appendChild(this.fieldElement);
//确定按钮
this.saveButton = document.createElement('input');
this.saveButton.type = 'button';
this.saveButton.value = '保存';
this.editElement.appendChild(this.saveButton);
//取消按钮
this.cancelButton = document.createElement('input');
this.cancelButton.type = 'button';
this.cancelButton.value = '取消';
this.editElement.appendChild(this.cancelButton);
//初始化文本状态
this.convertToText();
},
//文本状态
convertToText: function() {
this.staticElement.style.display = 'inline';
this.fieldElement.style.display = 'none';
this.saveButton.style.display = 'none';
this.cancelButton.style.display = 'none';
},
//编辑状态
convertToEdit: function() {
this.staticElement.style.display = 'none';
this.fieldElement.style.display = 'inline';
this.saveButton.style.display = 'inline';
this.cancelButton.style.display = 'inline';
},
//事件监听
attachEvents: function() {
const self = this;
this.staticElement.addEventListener('click', function() {
self.convertToEdit();
});
this.saveButton.addEventListener('click', function() {
self.save();
});
this.cancelButton.addEventListener('click', function() {
self.cancel();
});
},
save: function() {
this.value = this.fieldElement.value;
this.staticElement.innerHTML = this.value;
localStorage.setItem(this.storageKey, this.value);
this.convertToText();
this.saveData();
},
};
使用箭头函数优化
注意在上述代码中的attachEvents函数中的回调函数我们使用了传统的函数表达式,因此this会丢失,所以我们要通过self
保存this
的引用。实际上,使用箭头函数可以更简洁地处理this
指向问题,因为箭头函数不会创建自己的this
,而是会捕获其所在上下文的this
值。
EditInPlace.prototype.attachEvents = function() {
this.staticElement.addEventListener('click', () => {
this.convertToEdit();
});
this.saveButton.addEventListener('click', () => {
this.save();
});
this.cancelButton.addEventListener('click', () => {
this.coverToText();
});
};
本地存储
利用localStorage
可以将用户的编辑内容保存在本地,当用户刷新页面时,仍然可以看到已保存的内容。
save: function() {
this.value = this.fieldElement.value;
this.staticElement.innerHTML = this.value;
localStorage.setItem(this.storageKey, this.value);
this.convertToText();
},
模拟后端
为了模拟后端数据,我们可以使用json-server
。首先初始化项目:
npm init -y
npm install json-server
在package.json
中添加脚本:
"scripts": {
"dev": "json-server --watch db.json"
}
然后创建db.json
文件:
{
"users": [
{
"id": 1,
"signature": "这个家伙很懒,什么也没有留下"
}
]
}
运行json-server
:
npm run dev
这会启动一个本地服务器,可以通过http://localhost:3000/users/1
访问用户数据。
我们也可以再写一个saveData函数来将更新的数据同步保存到后端数据库。
saveData: function(){
let value = this.value
//修改资源
fetch('http://localhost:3000/users/1',{
method:'PATCH',
//请求头,发送的内容 格式是json
headers: {
'Content-Type': 'application/json'
},
//请求体
body: JSON.stringify({
signature: value
})
})
.then(res => res.json())
.then(data => {
console.log(data,'保存成功');
})
}
总结
通过本文的介绍,我们详细讲解了如何在网页中实现B站的就地编辑功能。我们不仅探讨了用户体验的设计,还涉及了JavaScript的高级技巧,如事件处理、类的封装和本地存储。希望通过本文的讲解,你能够更好地理解和应用这些技术,提升网页开发的效率和用户体验。