当半夜睡不着,翻出qq的历史个性签名

当半夜睡不着,翻出qq的历史个性签名,我想起了十年前自己那些qq个性签名,如“不要迷恋哥,哥只是个传说。”、“你若安好,便是晴天”等,尬的我脚趾抠出三室一厅。

描述文字

那么本次要给大家带来的就是如何实现个性签名的就地编辑 ,如哔哩哔哩的个性签名

image.png

前言

在网络社交的舞台上,个性签名如同一张精心设计的名片,不仅展现了个人的独特性格与审美情趣,还悄然透露出持有人当下的心境、生活哲学或是对世界的独特见解。它可能是几句诗词,隐含着对美好生活的向往;或许是电影台词,折射出个人的价值观念与精神追求;亦或是一段简洁有力的独白,直抒胸臆,表达着当前的情绪状态。

实战解析

存储知识

首先我们需要掌握一些存储知识:

HTML5 Local Storage(本地存储)

HTML5 Local Storage 是一种在客户端(即用户的浏览器)存储数据的技术,它允许web应用在用户的浏览器上保存数据,即使在关闭浏览器窗口或重启浏览器之后,这些数据依然存在。这对于提升用户体验非常有用,因为它可以帮助应用记住用户的偏好设置、登录状态或其他信息,而无需频繁地向服务器请求数据。

  • setItem方法:用于存储数据到本地存储中。它接受两个参数,第一个是键名(key),第二个是值(value)。例如:localStorage.setItem('username', 'John Doe')

  • getItem方法:用于从本地存储中获取数据。它接受一个参数,即要获取的键名。如果该键存在于存储中,它会返回对应的值;否则,返回null。例如:let username = localStorage.getItem('username')

RESTful API 和资源的概念

RESTful(Representational State Transfer)是一种网络应用程序的设计风格和开发方式,基于HTTP协议,利用URI(Uniform Resource Identifier)来定位资源,通过HTTP的GET、POST、PUT、DELETE等方法来操作资源。这里的“一切皆资源”理念意味着Web服务中的所有内容都可以被看作资源,而RESTful API则是访问和操作这些资源的一套规则。

  • db.jsonusers: 在这个上下文中,db.json可能是一个存放数据的文件,其中包含了比如用户信息这样的资源集合。在RESTful架构中,users可以被视为一个资源集合。

  • 访问方式示例:

    • http://localhost:3000/users 表示用户资源的集合,通常使用GET方法来获取所有用户的信息。
    • http://localhost:3000/users/1 表示集合中特定用户(如ID为1的用户)的资源,你可以通过GET、PUT、PATCH或DELETE方法来读取、更新或删除这个特定资源。
两者的区别
  • 存储位置与范围:HTML5 Local Storage的数据存储在用户的浏览器上,仅对该用户可见,不同用户之间不会共享这些数据。而RESTful API操作的资源存储在服务器上,可以被网络中的任何有权限的客户端访问。

  • 数据持久性:Local Storage的存储空间更大,数据在用户清除浏览器数据之前会一直保留。RESTful API中的资源持久性取决于服务器的策略,如数据库备份和恢复策略等。

  • 交互方式:Local Storage是客户端技术,不涉及与服务器的实时通信。RESTful API则是基于网络的,需要客户端发起HTTP请求到服务器,服务器响应处理后再返回结果给客户端。

  • 应用场景:Local Storage适用于存储不敏感的用户界面状态、用户偏好设置等数据。RESTful API则用于实现客户端与服务器之间的数据交换,适用于需要在服务器端持久化数据、多用户共享数据或需要复杂业务逻辑处理的场景。

前端部分

index.html
  1. html部分
    我们只需要在html部分放入一个挂载点作为容器去实现功能
<div id="signature"></div>
  1. js部分

这里我通过引入外部脚本edit_in_place.js,把EditInPlace类放在外部脚本,独立开发和测试EditInPlace类,可以提高开发效率。

    <script src="./edit_in_place.js"></script>
    <script>
        const STORAGEKEY = 'signature';

        fetch("http://localhost:3000/users/1")
            .then(res => res.json())
            .then(data => {
                // console.log(data, '//');
                const { signature } = data
                const signatureDom = localStorage.getItem(STORAGEKEY) || signature; 
                if(signature !== signatureDom) {
                    localStorage.setItem(STORAGEKEY, signature);
                    new EditInPlace(STORAGEKEY, 
                    document.getElementById("signature"), signature);   
                }
            })
    </script>

代码解释:

  1. 数据获取:
    使用fetch函数从http://localhost:3000/users/1这个API地址获取用户信息。这是一个异步操作,数据获取后通过一系列的.then方法处理。
    .then(res => res.json()) 将响应体转化为JSON格式。
    在下一个.then中,从返回的JSON数据中解构出signature字段,这是用户当前的签名。
  2. 状态检查与更新:
    • const signatureDom = localStorage.getItem(STORAGEKEY) || signature; 这行代码尝试从本地存储中获取签名,如果不存在,则使用刚从服务器获取的签名。
    • 接下来的if(signature !== signatureDom)判断服务器的签名是否与本地存储中的签名不同。
    • 如果两者不同,说明签名有更新,于是执行:localStorage.setItem(STORAGEKEY, signature); 更新本地存储中的签名信息。
  3. new EditInPlace(STORAGEKEY, document.getElementById("signature"), signature); 实例化EditInPlace类,传入存储键名、页面上的挂载点(通过ID “signature” 获取的<div>元素)以及签名内容,开始在页面上构建并启用签名的就地编辑界面。
edit_in_place.js

我在这个文件中 模块化封装了EditInPlace类,让代码更具可读性和复用性。

首先,封装了EditInPlace,并且初始化要封装的函数,并且给它加上了函数签名,使它具有可读性

/**
 * @func  就地编辑
 * @param { ele } container  挂载点 
 * @author bba
 * @date  2024/6/25
 */
function EditInPlace(storageKey, container, value = '这个家伙很懒,什么都没有留下') {
    // console.log('-----')
    this.container = container;
    this.storageKey = storageKey;
    this.value = value;
    this.createElement();
    // console.log(this.value)
    this.attachEvent();
}

代码解释:

  • 函数签名function EditInPlace(storageKey, container, value = '这个家伙很懒,什么都没有留下') 定义了构造函数,接受三个参数:

    • storageKey:字符串,用于在本地存储(如localStorage)中标识存储的键名。
    • container:DOM元素,组件将被插入的容器。
    • value:默认值,当没有提供初始签名内容时使用,默认签名文本为“这个家伙很懒,什么都没有留下”。
  • 初始化属性

    • this.container = container;:将传入的容器元素引用赋值给实例的container属性。
    • this.storageKey = storageKey;:将存储键名赋值给实例的storageKey属性。
    • this.value = value;:设置初始签名值,如果没有传入,则使用默认值。
  • 创建DOM元素

    • this.createElement(); 调用实例方法createElement,这个方法虽然没有在代码片段中展示,但根据注释推测,它的作用是动态创建文本展示(span)、编辑框(input)以及可能的控制按钮(如保存和取消按钮),并将这些元素添加到指定的容器中。
  • 事件绑定

    • this.attachEvent(); 调用实例方法attachEvent,用于为新创建的DOM元素绑定必要的事件监听器,如监听点击事件以切换编辑状态、保存更改等。同样,此方法的具体实现未在代码片段中给出。

我们继续代码的实现

  1. createElement():
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.fieldElement.className = 'edit-mode'
        this.editElement.appendChild(this.fieldElement);

        // 确定按钮
        this.saveButton = document.createElement('input');
        this.saveButton.className = 'btn'
        this.saveButton.type = 'button';
        this.saveButton.value = '保存';
        this.editElement.appendChild(this.saveButton);

        // 取消按钮
        this.cancelButton = document.createElement('input');
        this.cancelButton.className = 'btn'
        this.cancelButton.type = 'button';
        this.cancelButton.value = '取消';
        this.editElement.appendChild(this.cancelButton);

        // 初始文本状态
        this.converToText();

        // 监听事件
        this.attachEvent();
    },

代码解释:

  • 创建主容器Div: 首先,通过 document.createElement(‘div’) 创建一个新的 <div> 元素,并将其引用存储在 this.editElement 中。这个 <div> 将作为编辑组件的根容器。

  • 将主容器添加到页面: 通过 this.container.appendChild(this.editElement) 将刚创建的 <div> 添加到类初始化时传入的容器元素 (this.container) 内。

  • 创建静态文本Span: 接着,创建一个 <span> 元素 (this.staticElement) 用于显示签名的初始文本值,并通过 innerHTML 属性设置其内容为 this.value,最后将这个 <span> 添加到主容器 (this.editElement) 中。

  • 创建输入框Input: 创建一个类型为 ‘text’ 的 <input> 元素 (this.fieldElement),用于用户编辑签名,其初始值同样设为 this.value,然后将其添加到主容器中。
    创建按钮:分别创建“保存”和“取消”两个按钮,类型均为 ‘button’,并通过 value 属性设置按钮上的文字,随后也将这两个按钮添加到主容器中。

  • 初始化文本状态: 调用 this.converToText() 方法,确保组件初次渲染时处于文本展示状态,而非编辑状态。

  • 事件监听: 最后,调用 this.attachEvent() 方法来为创建的各个元素(特别是按钮)添加必要的事件监听器,以实现编辑、保存和取消等功能。

1.1 converToText()

     converToText: function () {
        this.staticElement.style.display = 'inline'
        this.fieldElement.style.display = 'none'
        this.saveButton.style.display = 'none'
        this.cancelButton.style.display = 'none'
    },

1.2 converToEdit()

     converToEdit: function () {
        this.staticElement.style.display = 'none'
        this.fieldElement.style.display = 'inline'
        this.saveButton.style.display = 'inline'
        this.cancelButton.style.display = 'inline'
    },
  1. attachEvent()

这段事件监听是为了实例在页面上创建的几个DOM元素绑定相应的事件处理函数,以便实现就地编辑功能的交互逻辑。

    attachEvent: function () {
        // let that = this;    
        // this.staticElement.addEventListener('click',() => {
        // this 指向元素
        // this丢失了
        //     that.converToEdit();
        // }); 


        this.staticElement.addEventListener('click', () => this.converToEdit());
        this.saveButton.addEventListener('click', () => {
            this.save()
        });
        this.cancelButton.addEventListener('click', () => {
            this.converToText();
        });
    },
  1. 保存按钮save():
    save: function () {
        this.value = this.fieldElement.value;
        // html5 localStorage 
        // 将数据存储到本地,下次打开页面的时候,从本地获取数据
        localStorage.setItem(this.storageKey, this.value);
        this.staticElement.innerHTML = this.value;
        this.converToText();
        this.saveData();
    },
  1. saveData():

这个方法功能是使用Fetch API向服务器发送一个HTTP PATCH请求,以便更新指定资源的数据。

saveData: function () {
        let value = this.value
        // resfull = url 定义的方式 + METHOD
        // get 是读 Post 创建 PUT 修改 PATCH 局部更新 DELETE 删除
        // 看到这个url 就知道啥资源?
        // 修改db.json里的数据 GET
        fetch('http://localhost:3000/users/1', {
            method: 'PATCH',
            headers: {
                'Content-Type': 'application/json'
            },  // 请求头信息,告诉服务器,发送的参数是json格式
            body: JSON.stringify({
                signature: value
            })  // 请求体
        })
        .then(res => res.json())
        .then(data => {
            console.log(data, "保存成功")
        })
    }

代码解释:

  1. 数据准备: 方法首先将当前对象的value属性赋值给局部变量value,这个值通常是在编辑模式下用户输入的内容。

  2. 发起PATCH请求: 使用fetch函数向http://localhost:3000/users/1这个URL发起一个PATCH类型的HTTP请求。这个请求的目标是更新ID为1的用户资源中的数据。PATCH请求常用于局部更新已有资源,而不是替换整个资源。

  3. 配置请求选项:

    • Method: 设置为PATCH,表明这是一个局部更新请求。
    • Headers: 设置请求头,特别是Content-Typeapplication/json,告知服务器发送的数据格式是JSON。
    • Body: 包含一个JSON字符串,该字符串由用户的输入(value)经过JSON.stringify处理后得到,结构为{signature: value}。这里假设我们要更新的是用户签名(signature)字段。
  4. 处理响应:

    • 第一个.then处理函数会等待fetch的响应,并将其转化为JSON格式。
    • 第二个.then处理函数接收转化后的JSON数据,并打印到控制台,附带消息"保存成功",表明更新操作完成且服务器返回了响应。

那么大致的效果就完成了

image.png

image.png

改了value然后点击保存之后

image.png

总结

通过本次实战解析,我们不仅回顾了十年前那些充满个性色彩的QQ签名,还深入学习并实践了如何在现代Web开发中实现一个实用的个性签名就地编辑功能。我们从理论到实践,逐步构建了一个结合前端技术和后端交互的完整解决方案,涵盖了HTML5 Local Storage的使用、RESTful API的基本理解和应用,以及如何通过JavaScript ES6的Class和模块化编程提升代码的组织与可维护性。
那么这次的分享到这里就结束了

  • 16
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值