一个EditInPlace小组件,了解js面向对象编程
什么叫面向对象呢?
面向对象(Object-Oriented,简称OO)是一种编程思想或范式,它将程序中的数据和对数据的操作封装成对象。对象是程序中的实体,可以是现实世界中的物体或概念。面向对象编程的基本思想是通过创建对象来模拟现实世界中的实体,使程序更容易理解、设计和维护。
关键概念包括:
- 对象(Object): 对象是一个具体实例,具有特定的属性和方法。例如,一辆车可以是一个对象,它具有属性(颜色、型号)和方法(启动、停止)。
- 类(Class): 类是对象的模板或蓝图,定义了对象的结构和行为。一个类可以包含多个对象。使用类可以创建具有相似属性和方法的多个对象。
- 封装(Encapsulation): 封装是将对象的状态(属性)和行为(方法)包装在一起,形成一个独立的单元。这样可以隐藏对象的内部实现细节,只暴露必要的接口。
- 继承(Inheritance): 继承允许一个类(子类)继承另一个类(父类)的属性和方法。这样可以实现代码的重用,子类可以拥有父类的特性,并可以添加或修改自己的特性。
- 多态(Polymorphism): 多态性允许同一个方法在不同的对象中有不同的行为。子类可以覆盖(override)父类的方法,实现自己的特定行为。
面向对象编程的优势在于它提供了一种更加模块化、可维护和可扩展的方式来组织代码。通过将代码组织成对象,可以更好地反映现实世界中的关系和交互。这种编程思想有助于降低复杂性,提高代码的可读性和可维护性,同时促进代码的重用。简单一点来说我可以将很多功能分开来写,然后让对象具有我功能函数里面具有的属性和方法。
一个组件了解js面向对象
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>
<div id="app"></div>
<script src="./editor.js"></script>
<script>
// #app 挂载点 DOM面向对象的封装
//业务代码
new EditInPlace(
'ep1' ,
document.getElementById('app'),
'this is value'
)
</script>
</body>
</html>
在html中,我们new了一个EditInPlace的对象,我们知道,对象能使用js里面的属性和方法,那么那些属性和方法写在哪里呢。那就体现了编程的另一个素养,叫做模块化,另写一个js文件。提高代码的可读性和复用性。
js
/**
* @func EditInPlace组件
* @param {string} id 元素id
* @param {dom} parent 挂载点
* @param {string} value 初始值
* @author ls
* @date 2023/12/4
*/
function EditInPlace(id, parent, value) {
this.id = id;
this.parentElement = parent || document.body;
this.value = value || 'default value';
this.createElement(this.id);
this.attachEvents();
}
EditInPlace.prototype = {
// 创建组件的DOM,并挂载到挂载点上
createElement: function(id) {
// console.log(this, '---')
// 动态创建dom 当前对象的containerElement属性
// DOM 树,
this.containerElement = document.createElement('div');
// span节点的创建
this.staticElement = document.createElement('span');
this.staticElement.innerText = 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.className = 'save';
this.saveButton.value = 'Save'
this.containerElement.appendChild(this.saveButton);
// 取消按钮
this.cancelButton = document.createElement('input');
this.cancelButton.type = 'button';
this.cancelButton.className = 'cancel';
this.cancelButton.value = 'Cancel'
this.containerElement.appendChild(this.cancelButton);
this.parentElement.appendChild(this.containerElement);
this.convertToText();
},
// 切换到文本状态
convertToText: function() {
this.fieldElement.style.display = 'none';
this.saveButton.style.display = 'none';
this.cancelButton.style.display = 'none';
this.staticElement.style.display = 'inline';
},
attachEvents: function() {
// console.log(this)
// let that = this; // 对象实例保存下来了
const fn = this.convertToEditable.bind(this)
this.staticElement.addEventListener('click', fn)
this.cancelButton.addEventListener('click',this.convertToText.bind(this))
this.saveButton.addEventListener(
'click',
this.save.bind(this)
)
// fn();
},
convertToEditable: function() {
// console.log(this, this.cancelButton)
this.fieldElement.style.display = 'inline';
this.saveButton.style.display = 'inline';
this.cancelButton.style.display = 'inline';
this.staticElement.style.display = 'none';
},
save:function(){
let value=this.fieldElement.value;
this.value=value;
this.staticElement.innerText=value;
this.convertToText();
}
}
代码分析
1.构造函数
js
function EditInPlace(id, parent, value) {
this.id = id;
this.parentElement = parent || document.body;
this.value = value || 'default value';
this.createElement(this.id);
this.attachEvents();
}
这个函数是 EditInPlace
组件的构造函数。 它接受三个参数:id
(元素的 ID)、parent
(组件挂载的父 DOM 元素),以及 value
(组件的//初始值)。
构造函数初始化了一些属性,比如 id
、parentElement
(如果未提供则默认为 document.body
),以及 value
(如果未提供则默认为 'default value'
)。
2.createElement 方法:
js
createElement: function(id) {
// ...
}
- 这个方法用于创建组件的 DOM 元素,并将它们附加到指定的父元素上。
- 它创建了一个包含
span
(staticElement
)、input
(fieldElement
)、'Save' 按钮(saveButton
)、'Cancel' 按钮(cancelButton
)的div
(containerElement
)。
3.convertToText 方法:
js
convertToText: function() {
// ...
}
- 这个方法隐藏了输入框和按钮,仅显示静态文本,使其变为不可编辑状态
4.attachEvents 方法:
js
attachEvents: function() { // .
- 这个方法给静态元素(点击事件)、取消按钮(点击事件)和保存按钮(点击事件)添加了事件监听器。
- 点击静态元素触发
convertToEditable
方法,点击取消按钮触发convertToText
方法。
5.convertToEditable 方法:
js
convertToEditable: function() {
// ...
}
这个方法隐藏了静态文本,显示了输入框和按钮,允许用户编辑内容。
6.save 方法:
js
save: function() { // ... }
这个方法保存了编辑后的值,更新了静态文本,然后通过 convertToText
方法将组件转换回不可编辑状态。
注意
- 一定要有this指针,this会指向实例对象,所以我们要引用对象里面的内容就必须要有this指针。
- 方法一定要写在构造函数的原型上,因为实例对象的隐式原型会指向构造函数的显示原型,我们的实例对象需要构造函数的属性和方法必须隐式继承
以上的内容都在《你不知道的javascript》一书中,当然我原来的文章当中也有写,有想了解的宝子们可以去看一下,深刻了解以下原型和this的指向。
实现的效果
点击save保存之后,原先编辑的文字就会保存下来,取代原来的this is value,显示在页面上,点击cancel现在编辑的则不保存,任然显示原先保存de。
小插曲
- "力量只有在面对强大的对手时才能得到提升。"
- "不要认为你已经足够强大,否则你就会败给那些比你更强大的人。"
- "这个世界并不是理所当然地属于任何人的,只有强者才能在这个世界上生存下去。"