TypeScript 笔记
参考
官方文档:https://www.typescriptlang.org
参考作者:https://www.yuque.com/zyzhao/as2bfc
TypeScript 优点
- 程序更容易理解
- 效率更高
- 更少的错误
- 非常好的兼容性
一些缺点
- 增加了一些学习成本
- 短期内会增加开发成本
使用到的工具
- 下载Node
nodejs官网地址:https://nodejs.cn - 安装TypeScript
npm install -g typescript - npm install -g typescript
tsc -v - 下载VSCode
vscode官网 https://code.visualstudio.com/
Basic Types
boolean
let isBool: Boolean = true;
isBool = false;
console.log(isBool)
number
let num1: number = 123;
let num2:number = 0xffff;
let num3: number = 0b10010100;
string
let str1: string = "abc";
let str2: string = `hello ${str1}`;
console.log(str1)
console.log(str2)
any
但是用第三方的类库的时候,不确定参数的类型可以使用any类型
let noSure: any = 1;
noSure = "abc";
noSure = true;
使用any类型的时候,变量不会有代码智能提示。
联合类型
当一个变量可能为多种类型时可以使用联合类型
let numOrStr: number | string = 'abc';
numOrStr = 123
enum
enum Dirction{
Up,
Down,
Left,
Right = "RIGHT"
}
let dirc: Dirction = Dirction.Right
if (dirc == Dirction.Right){
console.log("right: ", Dirction.Right)
}
array
let nums: number[] = [1, 2, 3];
nums.push(4)
console.log(nums[3]) // 输入:4
let strarray: string[] = ['abc', 'ijk'];
strarray.push('uvw')
console.log(strarray[2]) // 输入:vuw
let bools: Array<boolean> = [false, true]
bools.push(true)
console.log(bools[1]) // 输入:true
Tuple
元组中的数类类型时被定义的
let numTuple: [number, string] = [123, "abc"];
// numTuple.push([456, 'ijk']); // 元组不能使用push方法
numTuple = [0, "456"];
console.log(numTuple[0], numTuple[1]); // 输出结果为:0 456
numTuple[0] = 133;
console.log(numTuple[0], numTuple[1]); // 输出结果为:133 456
void
void通常用在定义一个函数或方法的时候使用void,使用void表示这个函数或方法没有返回值。
function say_hello(name:string):void{
console.log(`hello ${name}`)
}
say_hello("xiaoming")
Null and Undefine
let u: undefined = undefined
let n: null = null
// 方法1 需要将tsconfig.json文件中:"strictNullChecks": false
let n1: number = 0;
n1 = undefined;
console.log(n1)
n1 = null
console.log(n1)
// 方法2 使用联合类型
let n2: string | undefined | null;
n2 = "123";
n2 = undefined;
n2 = null;
类型断言
类型断言通常使用在你不知TypeScript变量数据的是时候,类实数据类型转换
let anystr: any = "hello wrold"
let strLength: number = (anystr as string).length
// (anystr as string) 解释:将变量anystr的数据类型转为string类型
console.log("len", strLength)
let strLen: number = (<string>anystr).length
// (<string>anystr) 解释:将变量anystr的数据类型转为string类型
console.log("strLen", strLen)
Interface
接口类型时声明对象类型的一种方法。
作为函数参数
interface Point{
x: number;
y: number;
}
function printCoord(pt: Point){
console.log("The coordinate's x value is " + pt.x);
console.log("The coordinate's y value is " + pt.y);
console.log("The coordinate object value is " , pt);
}
printCoord({x: 100, y: 200});
调用可选参数
可选参数使用 ?
// interface
interface Point{
x: number;
y: number;
absX?: number; // 可选参数使用 ?
absY?: number; // 可选参数使用 ?
}
function printCoord(pt: Point){
console.log("The coordinate's x value is " + pt.x);
console.log("The coordinate's y value is " + pt.y);
if(pt.absX != undefined){
console.log("The coordinate's absX value is " + pt.absX);
}
if(pt.absY != undefined){
console.log("The coordinate's absY value is " + pt.absY);
}
console.log("The coordinate object value is " , pt);
}
printCoord({x: 100, y: 200});
console.log("-----------------------分界线------------------------")
printCoord({x: 100, y: 200, absX: 300, absY: 400});
Readonly properties
// interface
interface Point {
readonly x: number;
y: number;
}
let pt: Point = {x: 100, y: 200};
console.log(pt.x)
console.log(pt.y)
// pt.x = 300; // readonly类型在定义时设置好之后是不可修改的
pt.y = 400;
console.log(pt.y)
Function Types
// interface
interface searchFunc {
(source: string, substr?: string): boolean;
// () :小括号表示传入函数的参数
// : :冒号后面boolean表示函数返回的类型
}
let sf: searchFunc = function(sr: string, sb?: string){
return sr.length > (sb.length || 0);
}
let sf2: searchFunc = function(sr: string, sb: string){
return sr.length > sb.length;
}
Indexable Types
数组数据类型
// interface
interface StringArray {
[index: number]: string | number;
// [] :中括号来表示索引
// string | number :表示数组内可以string类型和number类型的变量
}
let strarray: StringArray = ['a', 'b', 'v', 1, 2];
class Types
// 对类进行创建interface
interface ClockInterface {
currentDate: Date
tick(): void
}
// 对构造器进行创建interface
interface ClockContructor {
new (hour: number, minute: number): any;
}
let Clock: ClockContructor = class Colck implements ClockInterface {
currentDate: Date;
currentHour: number;
currentMinute: number;
constructor(h:number, m:number){
this.currentDate = new Date;
this.currentHour = h;
this.currentMinute = m;
}
tick(): void {
console.log(`${this.currentDate} ${this.currentHour} ${this.currentMinute}`)
}
}
let clock = new Clock(10, 0);
clock.tick()
Extending Interface
单继承
interface Shape {
color: string;
}
interface Square extends Shape {
sideLength: number
}
let quare = {} as Square;
quare.color = "red";
quare.sideLength = 3;
多继承
多继承是使用 逗号(,)
interface Shape {
color: string;
}
interface PenStroke {
penWdith: number;
}
interface Square extends Shape, PenStroke {
sideLength: number;
}
let quare = {} as Square;
quare.color = "red";
quare.sideLength = 3;
quare.penWdith = 4;
Generics
interface identifyFn<T> {
(arg: T): T;
}
let fn1: identifyFn<number> = (arg:number) => {
return arg + 100;
}
console.log(fn1(100))
let fn2:identifyFn<string> = (srg: string) => {
return "test" + srg;
}
console.log(fn2("hello world"))
Function
函数定义
函数声明法
function add(x: number, y: number): number {
return x+y;
}
let num = add(1, 2);
console.log(num);
函数声明法定义函数解释器会首先在代码解释阶段执行函数声明,即函数声明法可以在本文件的所有位置可调用。
函数直接量表达式
let add = function(x: number, y: number): number {
return x+y;
}
let num = add(1, 2);
console.log(num);
let greetUnnamed: (name: string) => string;
greetUnnamed = function(name: string): string {
return 'Hi ' + name;
}
箭头函数
箭头函数常用写法
let add2 = (x: number, y: number): number => {
return x+y
}
let num2 = add2(1, 2);
console.log(num2);
箭头函数应用扩展
- 在Typescript中,我们可以使用function表达式或箭头函数定义一个函数。箭头函数是function表达式的缩写,箭头函数这种词法会在作用域绑定this操作
举例:
class Person {
name: string;
constructor(name: string) {
this.name = name;
}
greet() {
console.log(`Hi! My name is ${this.name}`);
}
greetDelay(time: number) {
// 使用 function定义函数就不能使用 this 关键字
// setTimeout(function () {
// console.log(`Hi! My name is ${this.name}`);
// }, time)
//
setTimeout(() => {
console.log(`Hi! My name is ${this.name}`);
}, time)
}
}
let remo = new Person("Remo");
remo.greet(); // ""
remo.greetDelay(3333)
通过箭头函数,我们可以保证 this 操作符指向的 Person 的示例而不是 setTimeout 的回调函数。
立即调用函数
立即调用函数表达式(IIFE)是一种设计模式,使用函数作用域作为一个词法作用域。IIFE 可以被用于防止全局作用域中的变量提升导致污染。
let bar = 0;
(function() {
var foo: number = 0; // 在函数作用域中
bar = 1; // 在全局作用域中
console.log(foo); // 0
console.log(bar); // 1
})();
console.log(bar);
console.log(foo); // 错误
Optional and Default Parameter
function printUserInfo(name: string, sex: string="男", age?: number): void {
// sex 为默认参数
// age 为可选参数, 可选参数后面加 ?
console.log(`${name}, ${age}, ${sex}`)
}
printUserInfo("xiaoming", "man")
printUserInfo("xiaoming", "man", 22)
Rest Parameters
function buildName(firstName: string, ...restOfName: string[]): string {
return firstName + " " + restOfName.join(" ")
}
let fullName:string = buildName("xiaoming", "xiaoming", "xiaoming")
console.log(fullName)
生成器
如果在Typescript 中调用一个函数,我们可以可定一旦这个函数开始运行,在它运行完成之间其他代码都不能运行。然而,一种新的函数可能会在函数执行过程中将这个函数暂停一次或多次,并在随后回复它的运行,而且可以让其它代码暂停的过程中运行,在Typescript和ES6中即实现了该功能。这种新型函数被称为生成器。
一个生成器代表一个值的序列。生成器对象的接口是一个迭代器,可以使用 next() 函数使它产出结果。
可以使用function 关键字后面跟着一个(*)定义一个生成器的构造函数。yield关键字被用来暂停函数的执行和返回值。以下举个例子:
function *foo() {
yield 1;
yield 2;
yield 3;
yield 4;
return 5;
}
let bar = foo();
console.log(bar.next())
console.log(bar.next())
console.log(bar.next())
console.log(bar.next())
console.log(bar.next())
异步函数 async 和 await
一个异步函数是在异步操作中被调用的函数。开发者可以使用 await 关键字等待异步结束的到来而不会阻塞程序的执行。
示例:
async function fn() {
await console.log("执行结束");
}
fn();
Clssses
readonly
字段前缀加上readonly关键字表示只读,放置在创建对象修改字段
class Greeter {
readonly name: string = "world";
constructor(otherName?: string){
if(otherName !== undefined) {
this.name = otherName // 如果 执行到该语句 将会报错
}
}
err() {
// this.name = "not ok";
// Cannot assign to 'name' because it is a read-only property.
}
}
const g = new Greeter();
// g.name = "also not ok"; Cannot assign to 'name' because it is a read-only property.
constructor
// 创建类
class Point {
x: number;
y: number;
absX: number;
absY: number;
// 创建构造方法
constructor(x = 0, y = 0, absX?: number, absY?: number) {
this.x = x;
this.y = y;
this.absX = absX;
this.absY = absY;
}
// 创建类方法
printCoord(){
console.log("The coordinate's x value is " + this.x);
console.log("The coordinate's y value is " + this.y);
if(this.absX != undefined){
console.log("The coordinate's absX value is " + this.absX);
}
if(this.absX != undefined){
console.log("The coordinate's absX value is " + this.absX);
}
}
}
// 创建类对象并实例化对象
let point = new Point(10, 20);
point.printCoord();
console.log("-----------------------分界线------------------------")
let point2 = new Point(100, 200, 300);
point.printCoord();
extends Classes
使用extends实现类的显示继承
Typeccript不支持类的多继承
class Animal {
move() {
console.log("Moving along!");
}
}
// 使用关键字extends实现继承
class Dog extends Animal {
woof(times: number) {
for (let i = 0; i < times; i++) {
console.log("woof!");
}
}
}
const d = new Dog();
// 使用基类下的方法
d.move();
// 使用衍生类下的方法
d.woof(3);
调用父类中的属性和方法;
class Father {
protected name: string = "Father";
getName() {
return this.name
}
}
class Son extends Father {
name: string = "Son"; // 将name设置为public
getName() { //重写父类中的属性
return this.name
}
fatherName() {
return super.getName()
}
}
const person1 = new Father();
console.log(person1.getName);
// console.log(person1.name); // Father类中不能直接访问 name属性
const person2 = new Son();
console.log(person2.getName())
console.log(person2.fatherName())
console.log(person2.name) // Son类中可以直接访问 name属性
public
Typescript 类中默认访问权限是public
class Animal {
name: string;
constructor(theName: string){
this.name = theName
}
run() {
console.log(`${this.name} is running...`);
}
}
const dog = new Animal("wangcai");
dog.run()
console.log(dog.name) // 访问name属性
private
private修饰的变量或方法只能在类中访问
class Animal {
private name: string;
constructor(theName: string){
this.name = theName
}
run() {
console.log(`${this.name} is running...`);
}
}
const dog = new Animal("wangcai");
dog.run()
// console.log(dog.name) // 只能在类中访问
protected
类中的变量或方法前添加protected关键字,在外部是不可以访问的,只能在衍生类或自身内部访问。
class Animal {
protected name: string;
constructor(theName: string){
this.name = theName
}
run() {
console.log(`${this.name} is running...`);
}
}
class Dog extends Animal {
constructor(dogName: string) {
super(dogName); // 调用父类的构造器
}
wangwang() {
console.log(`${this.name} is wangwang...`);
}
}
const dog = new Dog("wangcai");
dog.wangwang()
// console.log(dog.name)
// Property 'name' is protected and only accessible through an instance of class 'Derived2'. This is an instance of class 'Base'.
类的多态
class Iphone {
password:string;
constructor(thePassword: string) {
this.password = thePassword;
}
unlock(...resstParameter: string[]) {
console.log(`using the password ${this.password} unlock`);
}
}
class Iphone5s extends Iphone {
constructor(thePasswrod: string) {
super(thePasswrod);
}
unlockByFinger(fingerPrin?: string) {
if(fingerPrin){
console.log(`iphone5s using ${fingerPrin} finger unlock`);
return true;
}
}
unlock(fingerPrin?: string) {
if(fingerPrin) {
return this.unlockByFinger(fingerPrin);
}
super.unlock();
}
}
class Iphonex extends Iphone {
constructor(faceId: string) {
super(faceId);
}
unlockByFaceID(faceID?: string) {
if(faceID){
console.log(`iphone5s using ${faceID} fingerPrint unlock`);
return true;
}
}
unlock(faceID?: string) {
if(faceID) {
return this.unlockByFaceID(faceID);
}
super.unlock();
}
}
function testUnlock(iphone: Iphone, arg?: string) {
arg ? iphone.unlock(arg) : iphone.unlock(arg);
}
const iphone5s = new Iphone5s("555555");
testUnlock(iphone5s);
testUnlock(iphone5s, "666666");
console.log("-----------------------分界线------------------------");
const iphonex = new Iphone5s("xxxxxx");
testUnlock(iphonex);
testUnlock(iphonex, "222222");
输出结果:
using the password 555555 unlock
iphone5s using 666666 finger unlock
-----------------------分界线------------------------
using the password xxxxxx unlock
iphone5s using 222222 finger unlock
Abstract Classes
抽象类不能通过new的方法创建实例,抽象类智能被继承。
抽象类中的抽象方法不需要在父类中实现,抽象方法需要在子类中实现。
abstract class Base {
abstract getName(): string;
printName() {
console.log("Hello, " + this.getName());
}
}
class Derived extends Base {
getName() { // 实现父类中的抽象方法
return "world";
}
}
const a = new Derived()
a.printName() // 输出 Hello, world
Generic Classes
使用泛型在class 后用 来表示
class Box<T> {
contents: T;
constructor(value: T) {
this.contents = value;
}
}
const b = new Box("hello!")
// b.contents.length
const c = new Box(123)
// c.contents.toString()
类的单例模式
class Demo {
private static instace: Demo;
private constructor() {
}
static getInstance() {
if(!this.instace) {
return this.instace = new Demo()
}
return this.instace;
}
}
const demo1 = Demo.getInstance();
const demo2 = Demo.getInstance();
if (demo1 === demo2) {
console.log("相同对象")
}
else {
console.log("不相同对象")
}
For 语句
以下通过一个加法函数来了解for循环和遍历列表
for
function add1(...list: number[]) :number {
let result = 0;
// 遍历列表方法 1
let len = list.length;
for(let i=0; i<len; i++) {
result += list[i];
}
return result;
}
console.log(add1(1, 2, 3, 4, 5)) // 输出 15
for in
对于普通对象,没有部署原生的 iterator 接口,直接使用 for…of 会报错
遍历列表
for…in 循环:只能获得对象的键名,不能获得键值
function add2(...list: number[]) :number {
let result = 0;
// 遍历列表方法 2
for(let index in list){
result += list[index];
}
return result;
}
console.log(add2(1, 2, 3, 4, 5)) // 输出 15
遍历字典
for…of 循环:允许遍历获得键值
let dict:{[key: string]: string| number} = {
"a": "1",
"b": 2,
"c": 3
}
for(let k in dict){
console.log(dict[k]);
}
for of
function add3(...list: number[]) :number {
let result = 0;
// 遍历列表方法 3
for(let value of list){
result += value;
}
return result;
}
console.log(add3(1, 2, 3, 4, 5)) // 输出 15
forEach
forEach 循环无法中途跳出,break 命令或 return 命令都不能奏效
function add4(...list: number[]) :number {
let result = 0;
// 遍历列表方法 4
list.forEach((val, index, array) => {
// val: list 中的值 val = list[index]
// index: 列表索引
// 第二个列表是一个可选参数
result += val;
console.log(index + ":", val)
console.log(array)
})
return result;
}
console.log(add4(1, 2, 3, 4, 5)) // 输出 15
CSS的使用方式:
使用style属性
使用style属性:在HTML标签中,通过style属性来添加样式。
<p style="color: blue; font-size: 40px;">越走越漫长的道路</p>
使用style标签
在head标签中创建style标签
<style>
p {
color: chartreuse;
font-size: 80px;
background-color: darkslateblue;
}
</style>
CSS文件
CSS文件:创建css文件,将样式放在文件中,然后在head中通过link标签引入该文件。
index.cs文件
p {
color: chartreuse;
font-size: 20px;
background-color:darkslateblue;
}
.cls {
color: chartreuse;
font-size: 80px;
background-color:darkslateblue;
}
#myid {
color: chartreuse;
font-size: 40px;
background-color:darkslateblue;
}
html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>display title</title>
<link rel="stylesheet" href="./index.css">
</head>
<body>
<H1 class="cls">html</H1>
<p id="myid">路灯下黄昏的剪影</p>
<p class="cls">越走越漫长的道路</p>
</body>
</html>
浏览器中使用Javascript
Javascript(简称js),负责让页面"动"起来,为页面添加动态效果。
使用JS的两种方式
script标签
script标签:在body标签的最后面,创建script标签。
<body>
<H1 class="cls">在浏览器中使用 JS</H1>
<script>
// js代码
let age = 18
console.log(age)
</script>
</body>
注意:html文件中的console.log()语句输出内容需要在浏览器控制台的console面板查看
独立js文件
独立js文件:创建index.js文件,在body标签的最后面,通过script标签引入
- 创建index.js文件
let person = {
name: 'xiaoming000',
age: 20
}
console.log(person)
- 在html文件中引入index.js文件
<body>
<H1 class="cls">在浏览器中使用 JS</H1>
<script src="./index.js"></script>
</body>
自动刷新浏览器
使用CSCode的Live Server插件,实现自动刷线浏览器。
作用:监视html或引入的css、js的变化,在保存文件时,该插件就会帮助我们自动刷新浏览器。
打开监视方式:在html文件上右键使用 Open with Live Server 方式打开
浏览器中运行Typescript
注意:浏览器中智能运行JS,无法直接运行TS,因此需要将TS转化为JS然后才能运行。
DOM操作
概述
DOM(Document Object Modal):文档对象模型。
DOM是浏览器提供的(浏览器特有),专门用来操作网页对象内容的一些JS对象。
目的:让我们可以使用JS/TS代码来操作页面(HTML)内容,让页面”动“起来,从而实现Web开发。
HTML:超文本标记语言,用来创建网页结构。
两者关系:浏览器根据HTML内容创建响应的DOM对象,也就是:每个HTML标签都应对应的DOM对象。
学习常用的DOM操作:
- 获取DOM元素(DOM对象)
- 设置样式
- 设置内容
- 绑定(解绑)事件
DOM操作的套路(技巧):先找人 后做事。
找人:获取DOM元素。
做事:设置样式、内容、绑定(解绑)实践。
获取元素
常用方法有两个:
- querySelect(selector)
作用:获取某一个DOM元素。 - querySelectAll(selector)
作用:同时获取多个DOM元素。
获取一个DOM元素:
document.querySelector(selector)
document对象:文档对象(整个页面),是操作页面内容的入口对象。
selector参数:是一个CSS选择器(标签、类、ID选择器等)。
作用:查询(获取)与选择器参数匹配的DOM元素,但是,只能获取第一个!
示例:
let title = document.querySelector('#title')
// 解释:获取页面中id为title的DOM元素
index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>浏览器中运行Ts</title>
</head>
<body>
<h1 id="title">青花瓷</h1>
<p class="c1">天青色等烟雨</p>
<p class="c1">而我在等你</p>
<script src="./index.js"></script>
</body>
</html>
index.ts文件
// 实例: 获取id为title的DOM元素
let title = document.querySelector('#title')
console.log(title)
let title1 = document.querySelector('.c1')
console.log(title1)
输出结果:
类型断言
问题:调用querySelector() 通过id选择器获取DOM元素时,拿到的元素类型都是Element.
因为无法确定id来去顶元素的类型,所以,该方法就返回了一个宽泛的类型:元素(Element)类型。不管是h1还是img都是元素。
导致问题:无法访问img元素的src属性。
原因:因为Element类型只是包含所有元素共有的属性和方法(比如:id属性、class属性等)。
解决方式:使用类型断言,来手动指定更加具体的类型(比如,此处应该比Element类型更加具体)。
语法
值 as 更加具体的类型
index.ts文件
// 实例: 获取id为title的DOM元素
let title = document.querySelector('#title')
console.log(title)
let img = document.querySelector('#image') as HTMLImageElement;
img.src = "./image2.png"
总结:
类型断言:手动指定**更加具体(精确)**的类型.
使用场景:当你比TS更加了解某个值的类型,并且需要执行具体的类型时。
技巧:通过 console.dir() 打印DOM对象,来查看该元素的类型。
获取多个元素
获取多个元素语法:
document.querySelectorAll(select);
作用:获取所有与选择器参数匹配的DOM元素,返回值时一个列表。
推荐:使用class选择器。
实例:
let list = document.querySelectorAll('.a');
解释:获取页面中所有class元素包含 a 的元素。
操作文本内容
读取:
dom.innerText
设置:
dom.innerText = "设置DOM文本"
注意:需要通过类型断言来指定DOM元素的具体类型,才可以使用innerText属性
注意:设置内容时,会覆盖原来的内容。如何实现追加内容?
dom.innerText += 'append text';
操作样式
DOM操作样式有两种操作方式:
- dom.sytle 属性:行内样式操作,可设置每个样式属性(比如:字体大小、文本颜色等)。
- dom。classList 属性:样式操作,也就是操作类名,比如,添加类名、移除类名等。
行内样式操作 style 属性
- 读取:
dom.style.样式名称;
- 设置:
dom.style.样式名称 = 样式值;
- 示例:
dom.style.color= read;
dom.style.fontSize = 40px;
dom.style.display = "None"; // 隐藏元素
dom.style.display = "block"; // 显示元素
console.log(dom.style.fontSize); // 读取dom元素字体大小属性
类样式操作 classList 属性
类样式操作包含三种方法添加类名、移除类名、判断类名是否存在。
- 添加类名:
dom.classList.add(类名1, 类名2, ...);
- 移除类样式:
dom.classList.remove(类名1, 类名2, ...);
-
判断类名是否存在:
如果当前DOM元素中存在指定的类名返回true,反之则返回false -
示例:
title.classList.add("a", "b"); // 添加类样式
if(title.classList.contains("a")) { // 判断dom元素中是否存在类样式 "a"
title.classList.remove("a"); // 移除类样式
}
事件操作
在浏览器页面我们经常会通过鼠标悬停、点击或敲击键盘等操作,来操作元素提供的功能。
如果让我们自己实现这样的功能,就需要通过事件操作来实现。
实际上,移入鼠标、敲击键盘等,都是常见的DOM操作事件。
操作事件的两种方法:
- addEventListener 添加(绑定)事件。
- removeEventListener 移除(绑定)事件。
添加事件
作用:给DOM元素添加事件。
dom.addEventListener(事件名称, 事件处理程序)
事件名称:字符串,比如 ‘click’ (鼠标点击事件)、 ‘mouseenter’ (鼠标进入事件)。
时间处理程序:回调函数,指定要实现的功能,该函数会在出发时间时调用。
示例:
- index.html 文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>浏览器中运行Ts</title>
</head>
<body>
<button name="btn">来打我呀!</button>
<script src="./index.js"></script>
</body>
</html>
- index.ts 文件
// 实例: 实现鼠标点击操作
let myBtn = document.querySelector("[name=btn]") as HTMLButtonElement
myBtn.addEventListener('click', function () {
console.log("打不着打不着...");
})
myBtn.addEventListener('mouseenter', function () {
console.log("你来啦")
})
事件对象
事件对象(event),是事件处理程序(回调函数)的参数。
表示:与当前事件相关的信息。
比如:事件类型(type)、出发事件的DOM元素(target)等。
示例:
// 实例: 实现鼠标点击操作来操作事件对象
let myBtn = document.querySelector("[name=btn]") as HTMLButtonElement
myBtn.addEventListener('click', function (event) {
console.log(event.type)
let btn = event.target as HTMLButtonElement
btn.style.fontSize = "40px"; // 修改btn按钮字体大小
})
移除事件
removeEventListener 移除事件
作用移除给DOM元素添加的事件,移除后事件就不会再出发了。
dom.removeEventListener(事件名称, 事件处理程序)
事件名称:同添加事件的第一参数。
事件处理程序:必须要跟添加事件的事件处理程序是同一个,否则无法移除
示例:
// 实例: 实现除click事件
let myBtn = document.querySelector("[name=btn]") as HTMLButtonElement
function handleClick(event: MouseEvent) {
console.log(event.type)
let btn = event.target as HTMLButtonElement
btn.style.fontSize = "40px";
}
myBtn.addEventListener('click', handleClick) // 添加 click 事件
myBtn.removeEventListener('click', handleClick) // 移除 click 事件
单次出发事件
如果事件只需要出发一次,可以添加事件处理。
处理方式:传入第三个参数,将once属性设置为true。
btn.addEventListener('click', function () {}, { once: true})
once: 如果值为true, 会出发时间后自动将事件移除,达到只出发一次的目的。
示例:
// 实例: 实现单次出发事件
let myBtn = document.querySelector("[name=btn]") as HTMLButtonElement
function handleClick(event: MouseEvent) {
console.log(event.type)
let btn = event.target as HTMLButtonElement
btn.style.fontSize = "40px";
}
myBtn.addEventListener('click', handleClick, {once: true}) // 添加 click 事件