B站:让我们来了解B站的个性签名

475 阅读2分钟

让我们来了解B站的个性签名

一.前言

B站作为一个广受欢迎的视频分享平台,用户可以通过个性标签来展示自己的特点和兴趣。而这些个性标签可以通过简单的点击进行修改,并且在点击其他位置时自动保存。这种就地编辑功能极大地提升了用户体验,方便快捷。

二.用户体验

  • 平时文本状态 ,显示签名

image.png

  • mouseover 进入编辑状态,显示编辑框

image.png

  • 退出编辑状态 自动保存,切换到文本状态

image.png

三.实现方法

  • 用类的概念来封装与复用,考虑队友
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();
            //对象?
        });

image.png

  • 解决方法,使用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>

  • 效果图

image.png

image.png