一句话爽文引言
你有没有遇过这种时刻:
改个个人简介 → 页面跳转三次 → 心态崩两次。
当用户体验遭遇“跳转地狱”,你就知道——是时候让 就地编辑(Edit In Place) 出场了。
它就像 UI 世界的“变形金刚”:
静态文字 ➜ 一点即变输入框 ➜ 保存又变回文字。
丝滑得像魔术。
今天,我们不但要把它造出来,还要把它从面条代码封成一个“可无限复用的组件工厂”。
准备好开启奇幻之旅了吗?🧙♂️✨
🏕️ 一、认识 EditInPlace:一个会 72 变的小部件
1.1 它是什么?
一句话,它就是:
点一下 → 文字变输入框 → 改完自动变回去
知乎昵称、微博签名、Notion 标题等,都在用这种小组件。
下面是我们要优化与封装的原始(但非常有价值的)核心代码:
function EditInPlace(id, value, parentElement) {
this.id = id;
this.value = value || '这个家伙很懒,什么都没有留下';
this.parentElement = parentElement;
this.containerElement = null;
this.saveButton = null;
this.cancelButton = null;
this.fieldElement = null;
this.staticElement = null;
this.createElement();
this.attachEvent();
}
1.2 最形象的比喻:建筑公司的标准化施工
一个 EditInPlace 实例,就像盖一栋“小别墅”:
- id=门牌号
- value=初始装修方案
- parentElement=地块位置
- createElement() =盖房子
- attachEvent() =安装智能家居
写这段代码就像开启一个“智能别墅制造流水线”。
🏗️ 二、createElement:从 0 到 1 造一栋小别墅
此方法负责 DOM 的 全部结构搭建。
createElement: function() {
this.containerElement = document.createElement('div');
this.containerElement.id = this.id;
this.staticElement = document.createElement('span');
this.staticElement.innerHTML = this.value;
this.containerElement.appendChild(this.staticElement);
this.fieldElement = document.createElement('input');
this.fieldElement.type = 'text';
this.fieldElement.value = this.value;
this.containerElement.appendChild(this.fieldElement);
this.saveButton = document.createElement('input');
this.saveButton.type = 'button';
this.saveButton.value = '保存';
this.containerElement.appendChild(this.saveButton);
this.cancelButton = document.createElement('input');
this.cancelButton.value = '取消';
this.containerElement.appendChild(this.cancelButton);
this.parentElement.appendChild(this.containerElement);
this.convertToText();
}
一个组件 = 一个小房子结构:
🧱 构建总览
| 部件 | 作用 | 比喻 |
|---|---|---|
div | 容器 | ✔ 房子的承重墙 |
span | 只读文字 | ✔ 客厅展示区 |
input | 可编辑输入框 | ✔ 临时施工区 |
| 保存 / 取消按钮 | 操作区 | ✔ 控制面板 |
最妙的一行:
this.convertToText();
相当于交房时说一句:“先以展示模式交付。”
🎬 三、两种模式:展示(Text) vs 编辑(Field)
3.1 convertToText:大幕拉开
convertToText: function() {
this.fieldElement.style.display = 'none';
this.saveButton.style.display = 'none';
this.cancelButton.style.display = 'none';
this.staticElement.style.display = 'inline';
}
展示模式:
只看演员(文字)
后台人员统统藏起来。
3.2 convertToField:后台上线
convertToField: function() {
this.staticElement.style.display = 'none';
this.fieldElement.value = this.value;
this.fieldElement.style.display = 'inline';
this.saveButton.style.display = 'inline';
this.cancelButton.style.display = 'inline';
}
编辑模式:
演员下场,工作人员上台(输入框 + 按钮)
最关键的一句是:
this.fieldElement.value = this.value;
保证每次进入编辑状态看到的都是最新数据。
这是 UI 稳定性的重要保障。
🧲 四、attachEvent:给别墅装“智能家居”
attachEvent: function() {
this.staticElement.addEventListener('click', () => {
this.convertToField();
});
this.saveButton.addEventListener('click', () => {
this.save();
});
this.cancelButton.addEventListener('click', () => {
this.cancel();
});
}
🎯 为什么用箭头函数?
因为普通函数 inside addEventListener,会让 this 指向 DOM 节点,而不是组件实例。
箭头函数就像绑定了“户口本”:
- 写在哪,就永远指向谁。
🧩 五、save 与 cancel:两兄弟的性格
save: function() {
var value = this.fieldElement.value;
this.value = value;
this.staticElement.innerHTML = value;
this.convertToText();
}
cancel: function() {
this.convertToText();
}
保存:
✔ 读取输入值
✔ 更新数据源
✔ 更新 UI
✔ 切回展示模式
取消:
✔ 一键恢复原样
🧬 六、OOP 的价值:你写的不是代码,是“组件生态”
6.1 可复用
你可以轻松创建 10 个、100 个:
new EditInPlace('name', '张三', app);
new EditInPlace('bio', '简介内容', profile);
6.2 封装
使用者根本不需要知道:
- span 是怎么变 input 的
- 事件是如何绑定的
- DOM 是怎么操作的
只需要一句:
new EditInPlace(...)
6.3 模块化
把类丢进一个文件,直接插上即用:
<script src="./edit_in_place.js"></script>
像插 U 盘一样的复用性。
🎨 七、体验层面的“隐藏 buff”
7.1 自动聚焦
this.fieldElement.focus();
7.2 键盘支持
this.fieldElement.addEventListener('keydown', e => {
if (e.key === 'Enter') this.save();
if (e.key === 'Escape') this.cancel();
});
7.3 性能最优策略
- DOM 创建一次
- 后续只是切换 display
🚀 八、未来升级路线:从“毛坯房”到“智能豪宅”
8.1 后端持久化
加入 fetch:
await fetch(`/api/update/${this.id}`, {
method: 'POST',
body: JSON.stringify({ value })
});
8.2 主题皮肤
支持 options:
new EditInPlace(id, value, parent, {
cssClass: 'dark-theme'
});
🧙♂️ 九、总结:OOP 的“道”与“术”
🛠️ 術:写法层面的套路
- 职责分离
- 模块拆分
- 单一职责
- 清晰的 API
🧠 道:思维层面的觉醒
你不再是写代码,而是在“造物”:
- 让代码能复用
- 让代码能协作
- 让代码能成长
一个类 = 一个微型生态系统
而 EditInPlace 就是你迈向 OOP 世界的第一只“宝可梦”。