实现bilibili个性化签名(就地编辑),猛猛提升你的业务能力

4,210 阅读6分钟

引言

bilibili中,在修改个性签名时,有就地编辑(EditInPlace) 这么一种功能,用户直接在页面上修改内容而无需跳转到单独编辑界面,这种方法即时生效,大大提升了交互效率。今天,我们来使用DOM动态编程完成一个简单的EditInPlace。

1732842546625.gif

传统表单提交

在开始DOM动态编程之前,我们先来使用最原始的传统表单,用户修改个性签名,将修改数据传入后端,再进行修改。但就算使用了比较简单的传统方式,也要注意各种细节,全面优化用户体验。(当然也可以直接使用contenteditable="true" 。 contenteditable 是一个枚举属性,表示元素是否可被用户编辑。)

宗旨:把用户当小白,要为用户考虑一切!!!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 先设置提交到百度 http提交-->
    <form action="https://www.baidu.com" method="post">
        <div>
            <!-- 与input文本框关联 -->
            <label for="input">签名</label>
            <!-- required 用户没有输入时提示 -->
            <!-- placeholder 提示信息 -->
            <input type="text" name="signature" id="input" required placeholder="请输入签名">
        </div>
        <div>
            <!-- 提交按钮 -->
            <input type="submit" value="提交">
        </div>
    </form>
</body>
</html>

优化用户体验:

  1. labelfor 属性将该标签与 id 为 input 的表单元素关联起来。当用户点击该标签时,与之关联的表单元素将获得焦点,方便用户输入。
  2. required:表示该输入字段是必填项,用户必须在提交表单前填写该字段,否则会触发浏览器的验证机制。
  3. placeholder提示词,为输入字段提供一个占位符文本,当输入字段为空时,会显示该文本,提示用户输入相应信息。

1732844064328.gif

DOM动态编程->就地编辑

相比于传统的表单提交方式,就地编辑具有以下明显优势:

  • 减少页面跳转:避免了因打开新页面而导致的时间消耗和用户体验下降。
  • 即时反馈:用户可以看到自己所做的修改立刻反映在界面上,增强了参与感。
  • 简化操作流程:整个过程更加直观流畅,减少了不必要的步骤,提高了工作效率。

下面,我们来正式开始DOM编程

创建html基本骨架

在html中添加两种模式:文本模式编辑模式。实现个性签名是要在文本模式和编辑模式之间切换,并给用户设置保存和取消按钮两个按钮。通常情况下,个性签名等信息会以纯文本形式展示给用户。此时,可以使用HTML中的<p>标签来包裹文本内容。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>EditInPlace 哔哩哔哩用户体验打造</title>
</head>
<body>
    <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>
    <script>
    </script>
</body>
</html>

image.png

通过DOM获取元素

使用document.getElementById('id')通过id获取的方式获取上面创建的四个元素

<script>
        // 业务编程
        // dom js html 节点对象 动态操作html
        const content = document.getElementById('content');
        const input = document.getElementById('input');
        const save = document.getElementById('save');
        const cancel = document.getElementById('cancel');
</script>

分别实现两个模式的页面

实现文本模式编辑模式之间的切换功能。

在开始时,隐藏编辑模式,只显示文本模式。点击文本模式后转为编辑模式,隐藏文本模式,显示编辑模式。隐藏和显示效果我们使用display:nonedisplay:inline来完成。(使用display:block会将几个元素分行显示)

我们将文本模式编辑模式封装成两个函数,把代码模块化,增强了代码的可读性。在接下来的使用中,只需要调用函数,就能实现两个模式之间的切换。

 <script>
        // 文本状态
        function convertToText() {
            // 只显示文本,把其他元素隐藏掉
            input.style.display = 'none';
            save.style.display = 'none';
            cancel.style.display = 'none';
            content.style.display = 'inline';
        }
        // 编辑状态
        function convertToEdit() {
            // 显示文本框和两个按钮,隐藏文本
            input.style.display = 'inline';
            save.style.display = 'inline';
            cancel.style.display = 'inline';
            content.style.display = 'none';
        }
         convertToText();  //开始状态是文本状态
         //convertToEdit();  检查一下编辑状态  
 </script>

文本状态:

image.png

编辑状态:

image.png

添加点击事件

使用addEventListener('click',function(){})添加点击事件,点击后完成function(){}中的函数。

完成三件事:

  1. 需要点击文本转为编辑模式,并将文本内容添加到编辑模式的输入框中。
  2. 为保存按钮添加点击事件,使用文本框中的内容更新文本,并转换为文本模式。
  3. 为取消按钮添加点击事件,不做任何处理,切换回文本模式。

input.value:获取用户在输入框中输入的内容

innerText:获取或设置该元素的文本内容。

  <script>
        // 点击 文本 进入编辑状态
        content.addEventListener('click', function () {
            convertToEdit();
            // 输入框里是最新的签名
            input.value = content.innerText;
        })
        // 点击 save 保存并转换回文本状态
        save.addEventListener('click', function () {
            content.innerText = input.value;
            convertToText();
        })
        // 点击 cancel 转换回文本状态
        cancel.addEventListener('click', function () {
            convertToText();
        })
    </script>

至此,我们已经通过DOM完成了一个简单的个性签名模块 我们来看一下成果:

1732846929969.gif

提升业务能力!!!

上面的设计已经很完美了,但是,在工作上还是远远不够的。我们必须提升我们自己的业务能力。

下面我会给出一个面向对象的EditInPlace模板,走向面向对象封装,我们直接通过代码来分析。大的要来了!!!

html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>面向对象的EditInPlace</title>
</head>
<body>
    <!-- 把html结构放在js中 -->
    <div id="app">
        <!-- <div id='ep1'><span></span></div>-->
    </div>
    <script src="./editInPlace.js"></script>
    <script>
        // 流程代码, 走向面向对象封装
        // 面向对象封装后 可以使用new快速创建多个实例
        new EditInPlace(
            'ep1',
            document.getElementById('app'),
        );
        new EditInPlace(
            'ep2',
            document.getElementById('app'),
            '222'
        );
        new EditInPlace(
            'ep3',
            document.getElementById('app'),
            '333'
        );
    </script>
</body>
</html>

editInPlace.js文件:

// JSDoc注释 代码规范,写清注释
/**
 * @func 就地编辑
 * @params {id,parent 父节点,value 默认值}    //参数
 * @author zzz
 * @date 2024-11-28
 */
function EditInPlace(id, parent, value) {
    // this指向新创建的对象
    this.id = id;   // 跨函数共享属性 可以在当前对象的其他方法中被访问和使用,实现了属性在不同函数之间的共享。
    // 两手准备  传参数和没有传参数  严谨
    this.parent = parent || document.body;   // 传递父节点  如果没有参数 页面根节点body
    this.value = value || '这个家伙很懒,什么都没有留下'; // 默认值
    this.createElement(this.id);  // 创建html标签
}
EditInPlace.prototype.createElement = function (id) {
    // console.log(id);
    
    //  下面三行相当于 <div ip='ep1'></div>  完成在js中生成html结构
    this.containerElement = document.createElement('div');  // 创建div标签
    this.containerElement.id = this.id;    //设置id
    this.parent.appendChild(this.containerElement);  // 在父节点中创建该子节点标签
    
    this.staticElement = document.createElement('span');  
    this.staticElement.innerText = this.value;
    this.containerElement.appendChild(this.staticElement);  // 再从刚刚创建的div中创建span,并赋值
}

结果展示

image.png 你也可以试着将该部分与上面的内容相结合,期待你的结果。

结语

总之,就地编辑技术并不复杂,使用DOM就能很好的完成需求。但对于新手开发者而言,如何提升自己的业务能力,规范代码完成任务,非常重要,这也是在去大厂时必须要有的个人能力。