让我们来了解B站的个性签名
一.前言
B站作为一个广受欢迎的视频分享平台,用户可以通过个性标签来展示自己的特点和兴趣。而这些个性标签可以通过简单的点击进行修改,并且在点击其他位置时自动保存。这种就地编辑功能极大地提升了用户体验,方便快捷。
二.用户体验
- 平时文本状态 ,显示签名
- mouseover 进入编辑状态,显示编辑框
- 退出编辑状态 自动保存,切换到文本状态
三.实现方法
- 用类的概念来封装与复用,考虑队友
function EditInPlace(storageKey,container, value = '这个家伙很懒,什么都没有留下' ) {
// console.log('-----')
this.storageKey = storageKey;
this.container = container;
this.value = value;
// 将动态创建文本和编辑input的dom 封装,代码的管理好
this.createElement();
// console.log(this.value)
this.attachEvents();
}
- 类的方法
-
EditInPlace.prototype = { // 就地编辑需要的动态DOM createElement: function() { // DOM树 // 创建一个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.converToText(); }, //文本状态 converToText:function(){ this.staticElement.style.display = 'inline'; this.fieldElement.style.display = 'none'; this.saveButton.style.display = 'none'; this.cancelButton.style.display = 'none'; }, //编辑状态 converToEdit:function(){ this.staticElement.style.display = 'none'; this.fieldElement.style.display = 'inline'; this.saveButton.style.display = 'inline'; this.cancelButton.style.display = 'inline'; }, //事件监听 attachEvents: function() { // let that = this; // this.saveButton.addEventListener('click', function(){ // //this 指向元素 // //this丢失 // that.converToEdit(); // //对象? // }); //=>没有this this.staticElement.addEventListener('click', ()=>{ this.converToEdit(); }); this.saveButton.addEventListener('click', ()=>{ this.save(); }); this.cancelButton.addEventListener('click', ()=>{ this.converToText; }) }, //保存 save: function() { this.value = this.fieldElement.value; this.staticElement.innerHTML = this.value; this.converToText(); //html5 localStorage存储 localStorage.setItem(this.storageKey, this.value); this.saveData() }, saveData:function(){ let value = this.value; //restfurl=url 定义方式 + Method //GET 读 POST 创建 PUT 更新 PATCH 局部更新 DELETE删除 //看到url 就知道啥资源 //修改资源 GET fetch("http://localhost:3000/users/1",{ method:"PATCH", //请求头 headers:{ 'Content-Type':'application/json' }, //请求体 body: JSON.stringify({ signature: value }), }).then(res =>res.json()) .then(data =>data.json() ) } // //取消 // cancel: function() { // this.converToText(); // } }
-
四.EditInplace 类里的事件监听,内部this丢失 self/that=this 暂存
this.saveButton.addEventListener('click', function(){
//this 指向元素
//this丢失
this.converToEdit();
//对象?
});
- 解决方法,使用that
attachEvents: function() {
let that = this;
this.saveButton.addEventListener('click', function(){
//this 指向元素
//this丢失
that.converToEdit();
//对象?
});
五.所以正好利用 箭头函数 没有this直接从拿外层的this来实现对象方法实现调用
this.staticElement.addEventListener('click', ()=>{
this.converToEdit();
});
六.最后使用html5 localStorage 本地存储 getItem
<!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>
// 封装能力 函数, 类 ,复用,
// js是单线程的
//碰到耗时性任务,先放入 event loop
//setTimeout 事件监听 耗时性任务(fetch) 查数据库
const STORGAEKEY ='signature'
fetch("http://localhost:3000/users/1")
.then(res => res.json())
.then(data =>{
// console.log(data,'//////')
const{signature}=data
const stoSignature = localStorage.getItem(STORGAEKEY)
if(signature !== stoSignature){
localStorage.setItem(STORGAEKEY,signature)}
new EditInPlace(STORGAEKEY,
document.getElementById('signature'),signature)
})
</body>
</html>
- 效果图