本篇为 JavaScript 进阶 ES6 系列笔记第一篇,将陆续更新后续内容。参考:JavaScript 进阶面向对象 ES6
「一」面向对象编程介绍
- 面向过程编程 POP
分析出解决问题的步骤,按步骤逐步实现
- 面向对象编程 OOP
将事务分解成对象,由对象间进行分工与合作
面向对象具有特性:
- 封装性
- 继承性
- 多态性
「二」ES6 中的类与对象
- 创建类
class Name {
// class body
}
类名习惯性定义为首字母大写
- 实例化
var x = new Name();
- 类构造函数 constructor
constructor()
方法是类的构造函数(默认)。用于传递参数,返回实例对象。通过 new
命令生成对象实例时,自动调用该方法。如果没有显式定义,类内部会自动创建 constructor()
。
- 类添加方法
class Name {
方法名() {
// function body
}
}
「三」类的继承
- 基本语法
class Father {
// 父类
}
class Son extends Father {
// 子类
}
- super 关键字
super
用于访问和调用对象父类构造函数、普通函数
- 调用父类构造函数
- 调用父类普通函数
子类调用时采取 就近原则,先执行子类函数,若子类中无此函数,再执行父类中函数
注意:
子类在构造函数中使用 super
,必须放到 this
前面。必须先调用父类的构造方法,在调用子类的构造方法。
- 三个注意点
- 在 ES6 中类没有变量提升,所以必须先定义类,才能通过类实例化对象
- 类里面的共有属性和方法一定要加
this
使用 - 类里面
this
指向问题 constructor
里面的this
指向实例对象,方法里面的this
指向这个方法的调用者
「四」面向对象案例
- 面向对象的 Tab 栏切换
因为实现代码过长,这里先分析一下大体框架,具体实现代码后文给出
- 主要 HTML代码
<main>
<h4>
动态添加标签页
</h4>
<div class="tabsbox" id="tab">
<!-- tab 标签 -->
<nav class="firstnav">
<ul>
<li class="liactive"><span>测试1</span><span class="iconfont icon-guanbi"></span></li>
<li><span>测试2</span><span class="iconfont icon-guanbi"></span></li>
<li><span>测试3</span><span class="iconfont icon-guanbi"></span></li>
</ul>
<div class="tabadd">
<span>+</span>
</div>
</nav>
<!-- tab 内容 -->
<div class="tabscon">
<section class="conactive">测试1</section>
<section>测试2</section>
<section>测试3</section>
</div>
</div>
</main>
<script src="tab.js"></script>
-
由于篇幅问题,css 代码不再给出
-
JS 代码
var that;
class Tab {
constructor(id) {
that = this;
this.main = document.querySelector(id);
this.add = this.main.querySelector('.tabadd');
// li 的父元素
this.ul = this.main.querySelector('.firstnav ul:first-child'); // .firstnav 下第一个 ul
// section 的父元素
this.fsection = this.main.querySelector('.tabscon');
this.init();
}
// 初始化操作
init() {
this.updateNode();
this.add.onclick = this.addTab; // no ()
for (var i = 0; i < this.lis.length; i++) {
this.lis[i].index = i;
this.lis[i].onclick = this.toggleTab; // no ()
// 点击删除按钮,调用删除函数
this.remove[i].onclick = this.removeTab;
// 双击 span ,调用编辑函数
this.spans[i].ondblclick = this.editTab;
this.sections[i].ondblclick = this.editTab;
}
}
// 1. 切换功能
toggleTab() {
that.clearClass();
// 去除底侧边框
this.className = 'liactive';
that.sections[this.index].className = 'conactive';
}
// 2. 添加功能
addTab() {
that.clearClass();
var random = Math.random();
var li = '<li class="liactive"><span>新选项卡</span><span class="iconfont icon-guanbi"></span></li>';
var section = '<section class="conactive">测试' + random + '</section>';
that.ul.insertAdjacentHTML('beforeend', li);
that.fsection.insertAdjacentHTML('beforeend', section);
that.init();
}
// 3. 删除功能
removeTab(e) {
// 防止触发父类 li 点击事件,应该阻止冒泡
e.stopPropagation();
// 获取索引号
var index = this.parentNode.index;
// 利用索引直接删除元素, 直接利用 remove()
that.lis[index].remove();
that.sections[index].remove();
that.init();
// 删除非选定状态
if (document.querySelector('.liactive')) return;
// 删除选定状态,手动调用点击事件,使得前一个被选中
index == 0 ? index : index--;
that.lis[index] && that.lis[index].click(); // 妙啊
}
// 4. 修改功能
editTab() {
var str = this.innerHTML;
// 双击禁止选定文字
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
this.innerHTML = '<input type="text" />';
var input = this.children[0];
input.value = str;
// 使得文本框中文字处于选定状态
input.select();
// 失去焦点,文本赋值给 span
input.onblur = function () {
this.parentNode.innerHTML = this.value;
}
// 点击回车,也可赋值
input.onkeyup = function (e) {
if (e.keyCode === 13) { // 13 回车键
this.blur();
}
}
}
// 清除样式
clearClass() {
for (var i = 0; i < this.lis.length; i++) {
this.lis[i].className = '';
this.sections[i].className = '';
}
}
// 动态更新所有 li 和 section
updateNode() {
this.lis = this.main.querySelectorAll('li');
this.sections = this.main.querySelectorAll('section');
// 删除 ✖
this.remove = this.main.querySelectorAll('.icon-guanbi');
// 获取 span
this.spans = this.main.querySelectorAll('.firstnav li span:first-child');
}
}
new Tab('#tab');
补充 1
insertAdjacentHTML()
可以直接把字符串格式元素添加到父元素中- 语法:
element.insertAdjacentHTML(position, text);
- 注意:
appendChild
不支持追加字符串的子元素,insertAdjacentHTML()
支持
补充 2
- 双击事件:
ondblclick
- 双击会默认选定文字,若要禁止选中文字,需要代码
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();