JavaScript基础语法ECMAScript和Web APIs

JavaScript基础

一、基础语法 ECMAScript

JavaScript是一门脚本语言,有以下特点:

  • 解释性语言,支持跨平台
  • 类C,Java风格的编程语言
  • 动态语言,动态数据类型,可以动态执行
  • 基于原型的面向对象编程语言(针对ES6之前的版本)

主要应用场景:

  • 浏览器端,表单校验,用户交互

  • 网页特效

  • 服务端开发:NodeJS

  • 桌面开发:ElectronJS

  • 移动端开发:Cordova、ReactNative、Weex

  • 游戏开发 cocos2d

游戏的引擎 unity 3d/虚幻和cocos2d

浏览器包含两个核心组件:渲染引擎(成网页)JS引擎(解释执行代码)

谷歌浏览器提供了V8引擎,是现在最前

NodeJS本身是做服务端开发的,但是很多前端组件是基于NodeJS开发的。

1.1 JS代码的书写位置

行内

js代码可以写在标签的属性当中,常见的属性有:onclickonchageonkeydown

内嵌

js代码可以写在 script 标签内部,script 自己的属性有:type=“text/javascript"或者“application/javascript” 只能是这两个,不能写错。

  • text/javascript : 代表浏览器端的JS代码
  • application/javascript : 代表服务端的JS代码

但是,我们一般不写 type 属性。

整个内嵌js代码可以放在 任意位置(甚至div里面),一般情况放在 head 标签里面,或者放在 body 标签末尾(优先让用户看到页面再看样式,再看行为)。

外部

可以通过 script 标签引入外部js文件,通过设置 src 属性值来指定外部js文件位置。注意 此时,开始标签和结束标签不要添加任何代码,因为不会被执行。

​ 在开发过程中,不要用内嵌的方式写 JS 代码;项目上线是,需要将 JS 代码独立出去;浏览器是有缓存的,

1.2 注释

​ 注释主要是给程序员看的 , JS 支持单行注释和多行注释,但是不支持文档注释

//这是单行注释:以两个斜杠开头

/*
	这是多行注释: 以斜杠星号开始,以外星号斜杠结束
*/
console.log('这是普通消息传出到控制台');
    JS  注释和java一样但是没有文档注释
    

1.3 常量、变量

​ 常量分两种: ①字面常量,②定义的常量

​ 在程序中有些客观的字面常量,有具体的含义,他们的值能改变。数字,字符,布尔值。

可以使用 const 关键字定义常量,注释:需要ES6或更高版本。

   //console  是一个对象
    console.log('这是普通消息传出到控制台');
    console.warn('这是警告信息');
    console.error('这是错误信息');
    //分号可以丢掉;
    const PI = 3.1415926;
    console.log('PI = ' + PI);  可以用加号链接,也可以用逗号链接

1.4 变量

​ 变量来源于数学术语,在计算机中其实就是一块内存空间。这块内存空间可以存放数据。变量的内存空间中存放的值可以修改(重复赋值)。常量的内存空间一旦赋值,则不再允许修改。

​ 变量的内存空间,可以通过变量名访问.

变量的声明和赋值(赋值之前是undefined)

​ 通过 varlet 关键字声明变量;

	var a;老语法来定义
    a = 66;
	console.log('a = ',a); 
	let b;  ES6提供的新语法才可以定义局部变量
    b = 77;
    console.log('b = ',b) 

变量初始化

var name = '张三'
let gender = '男'

特殊情况

  1. 声明一个变量,但没有赋值,此时他的值是: undefined
  2. 没有声明变量,但进行赋值操作,此时会默认创建一个全局变量(不会报错)。
  3. 没有声明变量,也没有赋值操作,则会报错;

变量必须先声明后使用。

1.5 标识符

​ 标识符就会说我们自己取得名称,我们可以使对变量、函数、属性、参数命名。标识符需要满足以下规则:

  1. 必须有数字、字母、下划线、美元符号组成,不能包含其他特殊符号;
  2. 不能以数字开头,也不推荐用下划线、美元符号开头,尽量用字母开头;
  3. 命名尽量使用驼峰规则,注意:JavaScript对大小写是敏感的, abcABC 是不同的;
  4. 不要使用关键字和保留字;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
​ javaScript是基于Unicode编码的,所以他支持多国语言和表情图标 var 李四 = "aa" emoji表情可以当做值不可以当做变量名。

1.6 数据类型

java八大基本数据类型有哪些。

  1. 字符串(string) 字符和字符串都是字符串类型

  2. 数值型(number) 数字就是数值型

  3. 布尔型(boolean) 两个值 (非零,非空的值可以代表true)

  4. null型(null) 空就是object

  5. undefined型(undefined)

  6. 除此以外都是object类型,通过 console.log(typeof v); 可以查看变量的字符类型。注意,null型一会返回object类型。

数据类型详解
数据类型说明示例
Number数字型(数值型)123,12.4
Boolean布尔型,取值只能是:true、falsetrue
String字符串型‘abc’
Undefined未定义,数据类型未知undefined
Null空值null
  • 数字型

    • 在数字前补0,代表八进制;
    • 在数字前补0x,代表十六进制;
    • 不要使用intfloat 等修饰;
    • 可以通过Number.MAX_VALUE、Number.MIN_VLUE来查看数字的最大最小取值范围;
    • 取值超出最大区域是Infinity 代表正无穷,-Infinity代表负无穷;
    • Nan(Not a Number)代表不是一个数字 eg:字符串减十;
    • 判断变量是否是一个数字isNaN(变量)是数字返回false不是数字返回true
  • 字符串型

    • 在 JS 中,字符串需要用单引号或双引号包围起来引号没有区别尽量用单引号 onclick = "console.log("Error")"出错,两个引号可以互相嵌套;或者用转义符外斜杠单引号或外斜杠双引号;
    • 换行外斜杠n;空格可以直接敲空格;空格外斜杠b;
    • 查看字符的个数长度 、'abc'.length;
    • 字符串拼接 a = ‘abc’ +10;
  • 布尔型

    • 布尔型变量的值,只能为truefalse
    • 如果参与算数运算,true会自动转换为1,false转换为0;
  • Null

    • 空值 null ,可以用于对变量赋值;
    • null 可以参与算数运算,但是会被忽略;

数据类型转换

1.字符串转换为数字

转换方式说明示例
parseInt(str)将字符串转换为整型值parseInt(‘123’)
parseFloat(str)将字符串转换为浮点型值parseFloat(‘123’)
Number(str)强制转换Number(‘str’)
隐式转换算数运算会自动转换str - 0(或者直接减掉一个数字也可以直接减乘除取余取整)

由于二进制无法精确表示0.1所以浮点数参与运算会有误差(解决办法,把单位调小了之后运算完再转换成原先的单位大小)

对于parseInt、parseFloat,如果传递的参数是以数值开头,但包含了特殊字符,JS依然会解析,但会忽略特殊字符,及其后的内容部分,相对于java则是只解析数字不解析字母出现字母会报错

2.数字转字符串

转换方式说明示例
拼接转成字符串123+’‘
toString()调用对象的方法a=a.toString();
String()强转String(123);

3.转布尔型

通过 Boolean 强转

a = Boolean( 0 )、undefinednull ’ ‘NaN 都是false

其他全都是true

1.7 运算符

运算符也称为操作符(Operator),用于一个以上操作数进行操作的符号。

  • 赋值运算符
  • 算术运算符
  • 关系运算符
  • 逻辑运算符
1.7.1 赋值运算符
运算符说明示例
=将等号右边的值赋给等号左边a=3;
+=、-=、/=先运算,然后进行赋值
1.7.2 算术运算符
运算符说明示例
+1+3
-3-2
*2*3
/3/2
%取余(取模)5/2
++递增a++和–a
递减
1.7.3 关系运算符

​ 关系运算符也称为比较运算符,其结果为布尔型。

运算符说明示例结果
>大于3 > 4false
>=大于或等于3 >= 4false
<小于3 < 4true
<=小于或等于3 <= 4true
==等于3 == 4false
!=不等于3 != 4true
===全等(也称为恒值)3 === 4false
!==不全等3 !==4true
1.7.4 逻辑运算符

​ 逻辑运算符用于布尔型变量的运算,也就是说参与逻辑运算的变量必须是布尔型,其结果也是布尔型。

运算符说明表达式结果
&&逻辑与true&&falsefalse找假
||逻辑或true&&falsetrue找真
逻辑非truefalse找相反

​ 逻辑与,逻辑或操作,存在短路操作,需要注意!

1.7.5 运算符的优先级
优先级运算符顺序
1括号()
2一元运算符++、–、!
3算术运算符先乘、除、取余、然后加、减
4关系运算符>、<、<=、>=、等值判断(== 、!= 、=、!、)优先级较低
5逻辑运算符先与后或
6赋值运算符=
7逗号运算符,

1.8 流程控制

​ 流程控制,就是控制我们的程序语句按照什么样的结构执行,常见结构有:顺序结构,分支结构,循环结构。

​ **语句(Statement):**是程序执行的最小单位, 以分号结尾

代码块: 一组相关语句,用 { } 包围起来。

1.8.1 顺序结构

​ JavaScript中,默认情况下,语句都是从上到下逐行解释执行的。

在这里插入图片描述

1.8.2 分支结构

if判断语句

if(关系运算表达式){
    //满足条件执行代码块中的语句
}

在这里插入图片描述

if-else判断语句

if(关系运算表达式){
    //满足条件执行代码块中的语句
}else{
	//不满足时---
}

在这里插入图片描述

if-else-if判断

if(关系运算表达式){
    //满足条件执行代码块中的语句
}else if(关系运算表达式){
	//满足1不满足2时---
}else{
	//都不满足时---
}

在这里插入图片描述
switch分组

switch(){
	case1:
       语句块1break;
    case2:
       语句块2break;
    ...
    default:
       break;
}

在这里插入图片描述
注意:

​ 对于 if-else-ifswitch 都可以进行多个值得判断,但是if-else-if一般用于范围判断,switch一般用于固定值判断。

三元运算符

var gender="女"var name=gender=="女"?"女士":"男士";

关系运算表达式?结果1:结果2

1.8.3 循环结构

​ while循环

while(true){
    //循环的语句块
}

​ 说明:要注意设置循环终止条件,否则会出现死循环。

​ 退出循环的关键字:

continue ,用于退出当前这一次循环语句,进入下一次循环;

break , 用于结束循环,不再参与下一次的循环;
在这里插入图片描述

var i = 0;
while(true){
  if(i >= 100){
    break;
  }

  if(i % 2 != 0){
    i++;
    continue;
  }
  console.log(i++);
}

do-while循环

do{
    //循环语句
}while(关系运算表达式);

​ 至少会执行一次循环体中的语句
在这里插入图片描述

for循环

for(初始化变量;关系运算表达式;递增或递减表达式){
    //循环语句
}

while 和 for 循环结构的选择

​ 如果明确地知道要执行多少次,此时最好用for循环。

​ 如果不确定要执行多少次,推荐使用while循环。

1.9 数组

​ 数组是一组有序的元素序列,在JavaScript中,数组可以存放不同数据类型的元素。

1.9.1 创建数组
  • ​ 创建数组对象 var a= new array[]
  • ​ 通过自变量创建数组 var b = [23,'abc',false,undefined,null]

数组长度是动态的可以改变可以添加数组元素 : b.push(44);

1.9.2 访问数组

​ 可以通过索引访问数组中的元素:a[1]

1.10 函数

定义:

​ 函数是指一段可以直接被另一段程序引用的程序。也叫做子程序、方法。

​ 函数就是一组代码,可以被重复调用。

不再类和对象里面定义的就叫函数 js在ES6之前不能自主创建类

在类和对象里面定义的就可以叫做方法

1.10.1 创建函数

​ 1.创建函数对象(不推荐使用)没有花括号

//语法
var	函数名 = new Function ("......需要执行的代码......");

//调用函数
函数名();

​ 2.函数表达式 (匿名函数)没有new

//语法
var	函数名	= function(形参1,形参2...){
    代码语句  同时使用参数
    ...
};
//调用函数
函数名(实参1,实参2...);

​ 3.函数关键字(命名函数,具名函数); 没有等于号

//语法
function fun3(形参1,形参2...) {
        代码语句
        ...
}
//调用
fun3(实参1,实参2...);

注意:

  • 函数声明并不会执行函数,必须调用之后才会执行。
  • 如果没有函数声明,直接调用会报错。
  • 函数调用,可以写在函数声明之前,之后。(存在预解析)。
1.10.2 函数的参数

形参与实参个数不匹配:

1. 实参数量比形参数量少:逐个匹配,没有传值的默认undefined
2. 实参数量多于形参数量:多余的实参将会被忽略

当不确定用户会传递多少参数时,可以通过arguments获取所有实参列表。arguments在任何函数中都可以直接使用。

function sum() {
    console.log(arguments);
    var sum = 0;
    for(var i = 0; i < arguments.length; i++){
        sum += arguments[i];
    }
    console.log(sum);
}
sum(1,2,3,4,5);

注意: 函数形参不需要加 var 关键字

1.10.3 函数的返回值 return

​ 函数通过return语句返回执行结果,原则上函数最多返回一个返回值。

​ 1. 如果没有return 语句,函数的返回值是undefined

​ 2. 语法上可以返回多个值以逗号隔开,但是只以最后一个返回值作为返回值,其他返回值全部无效。

​ 3.**return;**可以直接终止执行用来处理判断之后发现的无意义的操作。

​ 4.可以返回数组或者对象,变相的实现返回多个值。

1.11 作用域

​ 作用域(scope),通常来说,一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域增强了程序的可靠性,减少了命名冲突。

1.11.1作用域类型

全局作用域

  1. 如果js代码写在html文档中,那么全局作用域就是

块级作用域

​ 块级作用域值得是代码块级别的作用域。

​ 在JavaScript中,在ES6之前不存在块级作用域,函数内部任何地方定义的变量都可以在函数作用域内自由访问。**注意:**想反在java程序中的局部变量只能在同一个花括号内访问到。

​ 在ES6之后添加了块级作用域,此时需要用 let 关键字来声明变量。

​ 由于 let 声明的变量用于块级作用域,更符合java、 c、 c++语言的编程习惯,所以尽量用 let,逐步抛弃 var 关键字。

function fun() {
    if (true){
        let  ss = 33;//  一般此处使用更加符合java作用域范围的let来定义局部变量
    }
    console.log('内部访问块级----',ss);//此处访问ss访问不到,如果ss换成var关键字定义则可以访问到。
}
fun();

注意:在函数作用域中,如果不声明变量,而直接进行赋值操作,那么这个变量将自动提升为全局变量。

1.11.2 作用域链

​ 1. 在JavaScript中,函数是嵌套声明、调用的。函数也是一个对象。

​ 2. 函数可以当做参数进行传值,函数也可以作为返回值。

//---------------把函数当值传递,或者当成返回值返回
function parent() {
    console.log('父函数...');

    function child() {
        console.log('子函数...');
    }
    child();
    //return child();
}
parent();

​ 3. 在函数内部访问变量时,会依据就近原则,从内到外逐级寻找变量的声明。如果在全局作用域中依然无法找到变量的声明,就会报错。

//-------------作用链---依次注释parent、child、global定义的变量
var name = 'global';
function parent() {
    var name = 'parent';

    function child() {
        var name = 'child';
        console.log(name);
    }
    child();
}
parent();
  1. 全局作用域量的生命周期较长,只有当浏览器关闭的时候才会释放内存;局部变量生命周期较短,脱离函数作用域后就会失效,并释放内存;块级作用域生命周期最短,所以建议大家多使用块级作用域,函数作用域,也即局部变量。

1.12 预解析

​ JavaScript 代码在执行过程中,分两步:预解析和代码执行。

预解析: JS引擎会将变量的声明以及函数的声明提升到当前作用域的最前面,但是不会进行赋值操作,不会调用函数。

代码执行:从上到下依次执行代码语句。

1.13 对象

​ 类: 是一类事物的泛称,并不真实存在;

​ 对象: 是真实存在的个体,是类的实例。

​ 在JavaScript中,在ES6以前不能创建类,但是可以创建对象。在ES6之后,引入了class关键字,也可以通过类创建对象了。

1.13.1 创建对象

​ 对象包含:属性和方法。

​ ① 通过自变量创建对象

//var user = {}; //创建空对象
//创建对象的语法规则: {属性名:属性值;方法名:匿名函数;}
//属性名如username在json对象时要加双引号把属性名引起来。
var user = {
    username: '张三',
    password: '123456'
    age: 22,
    login:function(){
        console.log('用户登录');
    }
};
//可以通过小数点操作符访问对象的属性和方法。
console.log(user.username)
console.log(user['age']);
user.login();
user['login'];
//    其中的['username']方括号内可以存放“字符串”,便于通过变量的方法来传递参数。

​ ②通过Object创建对象

//  一、   通过Object创建对象
var user = new Object();
    user.username = '李四';
    user.password = '654312';
    user.age = 33;
    user.login = function () {
        console.log('李四登录...');
    };
    console.log(user.username)
    console.log(user['age']);
    user.login();
    user['login'];

​ 可以通过new Object() 创建一个空对象,然后通过小数点操作符动态地为对象添加属性和方法。

​ ③通过构造函数创建对象 一般对象名首字母大写。

function User(username,password,age) {
    this.username = username;
    this.password = password;
    this.age = age;
    this.login = function () {
        console.log('这是通过构造函数创建的对象。');
    };
}
var user1 = new User('王五',1111111,44);
console.log(user1);

注意

  1. 构造函数的函数名,一般首字母大写;

     2. 构造函数通过  `this`  关键字添加属性、赋值;
     3. 构造函数不需要写 `return`  语句。
    
1.13.2 遍历对象的属性

​ 可以通过 for in 语句遍历对象的属性:

for(let key in user){
    console.log(key);
    if(typeof user[key] == 'function'){
        user[key]();
    }else{
        console.log(user[key]);
    }
}

1.14 内置对象

​ JavaScript为了方便开发者,提供了一些全局的内置对象。JavaScript中对象有三种:自定义对象、内置对象、浏览器内置对象(Web APIs)。

1.14.1 Math对象

Math是一个内置对象,它具有数学常数和函数的属性和方法。不是一个函数对象。

  • ​ 最大数:max()

    • 如果不传任何参数,返回结果为:-Infinity
    • 如果参数中包含了不可以转化为数字的参数,则结果为NaN;否则会进行类型转换
  • ​ 最小数:

    • 如果不传任何参数,返回结果为:Infinity
    • 如果参数中包含了不可以转化为数字的参数,则结果为NaN;否则会进行类型转换
  • 四舍五入:round()

    • 如果不传参数,结果为:NaN
    • 对.5数字,会进行特殊操作,他的结果总是会偏大
  • 向上取整:ceil()

  • 向下取整floor()

  • 随机数:random()

    • return Math.floor(Math.random() * (max - min) ) + min;
1.14.2 书序

​ JavaScript中提供了多个Date构造函数,用来穿件Date对象。

  • new Date(); 将返回系统当前时间 (注意:是客户端)
  • new Date('2020-12-12 10:10:10'); 带参构造,用来展示特定的时间。
  • new Date(2020,12,12,10,10,10); 注意月份是从零开始计数0~11月,数字前面不可以补零否则会变成八进制。

long记录时间戳 一个bug2038年时间戳会失效

日期格式化

方法功能说明
getFullyYear();获取年份
getMonth();获取不同时区的月份从零开始计数,一般在后面加1
getUTCMonth();获取国际月份(不用一般)
getDay()获取一周之内的天数(不用一般)
getDate()获取当前月中的天数
getHours()获取当天小时
getMinutes()获取分钟
getSeconds()获取秒时
getMilliseconds()获取毫秒时
//-----格式化日期的函数,参数为Date对象,返回值为time字符串
function formatDate(date) {
    if(date === undefined){
         date = new Date();
    }
    var year = date.getFullYear();

    var month = date.getMonth();
    month = month > 9 ? month : '0' + month;

    var day = date.getDate();
    day = day > 9 ? day : '0' + day;

    var hours = date.getHours();
    hours = hours > 9 ? hours : '0' + hours;

    var minutes = date.getMinutes();
    minutes = minutes > 9 ? minutes : '0' + minutes;

    var seconds = date.getSeconds();
    seconds = seconds > 9 ? seconds : '0' + seconds;

    var time = year + '-' + month + '-' + day + '   ' +
            hours + '点' +minutes + '分' + seconds + '秒';
    return time;
}
var date1 = new Date(1998,9,12,10,10,10);
var nowtime = formatDate(date1 );//不带参则返回电脑当前时间
console.log('当前时间:',nowtime)
1.14.3 Array

**注意:**为了在控制台中显示数组的内容,你可以使用 console.table() 来展示经过格式化的数组。下面的例子则是另一种使用 forEach() 的格式化的方法。

添加元素

方法功能说明
push()后面添加元素返回值就是数组的长度
unshif()前面添加元素返回值也是数组的长度

删除元素

方法功能说明
pop()删除数组中最后一个元素返回值就是删除掉的元素
shift()删除数组中第一个元素返回值也是删除掉的元素

插入元素

方法功能说明
splice(3,0,6)插入元素位置[1]代表从索引为三的位置开始,零代表删除元素的个数,六代表需要插入的元素
splice(3,1,6)替换元素三代表的是开始位置,一指的是删除元素的个数,六代表删掉之后要插入的元素
splice(3,1)删除元素三指的是开始位置,一指的是删除元素的个数

筛选元素 过滤器filter

filter() 方法接收函数作为参数,用于筛选数组中的元素。通过函数的返回值确定是否保留元素。true 保留,false 则忽略。

​ eg:arr.filter( function(n){ return n > 3;} );

反转数组

reverse() 方法可以快速实现反转数组的功能。

树组排序

sort() 方法可以快速实现数组排序。注意:sort方法是按照数组中的元素的第一位的大小排序不是按照元素大小排序。通过对象名点方法调用方法。

​ 可以通过如下方式进行排序:

  • sort()方法可以接受一个比较函数,以自定义排序规则,根据返回值确定元素的先后顺序。

    • eg:arr.sort(function(a,b){ return a - b;});
  • sort()方法可以接受拉姆达表式,排序

    • eg:sort( (a-b) => a-b ) ; sort ( (a,b =>b-a );
1.14.4 String

​ JavaScript 提供了:StringNumberBoolean 等基本数据类型包装类。会自动提升为包装类的对象,数字不可以直接掉用需要转换成变量之后再调用。

自动装箱,拆箱

int a = 22;

Integer b = 22;

b = a;

二、 Web APIs

​ ECMAScript 是JavaScript的基础语法,有ECMA阻止负责维护

​ Web APIs 浏览器操作接口,由W3C阻止负责维护,主要包含两大部分:DOM和BOM。

​ DOM 是 Document Object Model(文档对象模型)的缩写。

“W3C 文档对象模型 (DOM) 是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。”

  • HTML DOM - 针对 HTML 文档的标准模型

在这里插入图片描述

名词解释

  • 文档:一个HTML页面就是一个文档,用document表示;
  • 元素:页面中,所有的标签都是元素,用 element 表示;
  • 节点:页面中所有的内容都称为节点(元素,文本,属性,注释),用node表示。

2.1.1 选择元素

方式功能说明
getElementById根据id值获取的元素只会返回第一个访问的内容
getElementsByTagName根据标签名获取元素会返回多个元素
getElementsByClassName根据类的名称获取,只要包含即可会返回多个元素
querySelector根据选择器获取元素只返回第一个匹配的元素
querySelectorAll根据选择器获取元素会返回所有匹配的元素
let  ul  = document.querySelector('ul');
let li = ul.querySelector('li:last-child');
console.log(li);
2.1.2 事件

​ 浏览器端的JavaScript程序,是基于事件驱动模型的。

​ 事件三要素:

  • 事件源:触发事件的对象;
  • 事件类型:鼠标点击(单击,双击)、键盘按下、获得焦点、失去焦点等;
  • 事件处理:JavaScript处理程序
//结构和表现分离之后:
//1 获取事件源
let btn = document.getElementById('btn');
//2 注册事件类型
btn.onclick = function () {
    //3 添加事件处理程序
    alert('干嘛点我,你好讨厌啊');
};
2.1.3 修改元素内容哦
方法功能说明
innerText修改元素只可以修改文字内容
innerHTML修改元素兼容性干好,可以同时修改网页的一部分样式
//1 获取事件源
    let p = document.getElementById('p');
    //2 注册事件类型
    btn.onclick = function () {
        //3 添加事件处理程序
        let p  = document.querySelector('p');
//        p.innerText = '修改后的内容';
        p.innerHTML = '<i>修改后的内容兼顾样式。。。</i>'//此处的i标签可以在html文档的中发挥作用。
    };

练习: 刷新页面时间

var now = formatDate();
let el = document.querySelector('h1');
el.innerHTML = now;

<!--格式化日期的函数,参数为Date对象,返回值为time-->
function formatDate(date) {
    if(date === undefined){
        date = new Date();
    }
    var year = date.getFullYear();

    var month = date.getMonth();
    month = month > 9 ? month : '0' + month;

    var day = date.getDate();
    day = day > 9 ? day : '0' + day;

    var hours = date.getHours();
    hours = hours > 9 ? hours : '0' + hours;

    var minutes = date.getMinutes();
    minutes = minutes > 9 ? minutes : '0' + minutes;

    var seconds = date.getSeconds();
    seconds = seconds > 9 ? seconds : '0' + seconds;

    var time = year + '-' + month + '-' + day + '   ' +
            hours + '点' +minutes + '分' + seconds + '秒';
    return time;
}
2.1.4 操作元素属性

读取元素属性

​ 标准属性通过 点 操作符直接读取。

​ 通过元素对象的 getAttribute() 方法可以获取标准属性以及自定义属性

2020年3月4日09:54:20

修改元素属性

​ 标准属性可以通过过 点 操作符获取属性后进行操作。

​ 通过元素对象的 setAttribute() 方法可以修改标准属性,自定义属性。

删除属性

​ 通过元素对象的 removeAttribute() 方法可以删除标准属性、自定义属性

2.1.5 层级操作
  1. 获取父节点

    //后续声明: child 代表子节点,parent代表父节点
    
    parent = child.parentNode;
    
  2. 获取子节点

    // 方式1: 通过父节点的children属性,可以获取所有元素节点
    let childList = parent.children;
    
    // 方式2:通过父节点的childNodes属性,可以获取所有子节点
    let c2  = parent.childNodes;
    
    //推荐使用第一种方式
    
  3. 获取指定的子节点

    //获取第一个元素节点
    let c1 = parent.firstElementChild;
    
    //获取最后一个元素节点
    let c2 = parent.lastElementChild;
    
    //先获取所有子元素及诶点,然后通过所以获取指定节点
    console.log(ul.children[3]);
    
    let c1 = ul.querySelector('li:nth-child(4)');
    console.log(c1);
    
    
    //获取所有子节点中的第一个
    let cc1 = parent.firstChild;
    //获取所有子节点中的第一个
    let cc2 = parent.lastChild;
    
    
    
  4. 获取兄弟节点

    //获取后面的兄弟元素节点
    let nextNode = child.nextElementSibling;
    
    //获取前面的兄弟元素节点
    let preNode = child.previousElementSiblings;
    
    //如果前面或者后面没有兄弟节点,返回Null
    
2.1.6 创建元素节点
let btn = document.querySelector('button');
let ul = document.querySelector('ul');
let count = 0;

btn.onclick = function () {
    //1.创建元素节点
    let li = document.createElement('li');

    //2.设置元素属性内容
    li.innerHTML = '这是测试标签'+count++;
    li.class = 'box';

    //3.添加到页面中去 点击一次添加一次
    ul.appendChild(li);
}
2.1.7 删除元素节点
ul.removeChild(ul.firstElementChild);
//通过父节点removeChild()方法可以删除子节点

live Server 自动刷新插件

1.1.8 元素操作高级
let ul = document.querySelector('ul');
let btn = document.querySelector('button');

btn.onclick = function(){
    //在指定位置插入元素
let li = document.createElement('li');
li.innerHTML = '3.5';

//在末尾追加
// ul.appendChild(li);

//在指定位置追加
// let l4=ul.querySelector('li:nth-child(4)');
// ul.insertBefore(li,l4);

//替换指定的元素节点
    let l3 = ul.querySelector('li:nth-child(3)');
    ul.replaceChild(li, l3);

};

节点属性

​ 节点对象中包含了三个重要属性:nodeTypenodeNamenodeValue 分别代表节点类型,节点名称(大写),节点值(元素节点的值都是null)

节点类型
元素1
属性2
文本3
注释8
文档9
//1 点击之后修改属性,宽度变成400px;
let box = document.querySelector('.box');

let btn1 = document.getElementById('btn1');
btn1.onclick = function(){
    console.dir(box);
    box.style.width = '400px';
}

//2 可以每点一次增加一次
let box = document.querySelector('.box');

let btn1 = document.getElementById('btn1');
btn1.onclick = function(){
    console.dir(box);
	//宽度没点击一次增加一次
    let width = box.offsetWidth;
    box.style.width = width + 100 + 'px';
    //修改颜色
    box.style.backgroundColor = 'red';
}

​ 通过元素节点的style属性,可以设置css样式,如果css的属性名中包含 ‘-’,则去除连字符,转换为驼峰命名规则可以通过。 可以通过js给class属性添加其他的class值eg:"fl box"

//通过元素节点的className属性,可以获取该节点拥有的类样式,可以对className重新复制,以修改元素节点的样式:::::点一次增大,再点一次缩小
let box = document.querySelector('.box');

let btn2 = document.getElementById('btn2');
btn2.onclick = function(){
    let cn = box.className;
    if(cn.indexOf('big')== -1){
        box.className = 'box big';
    }else{
        box.className = 'box';
    }
};

位置和尺寸

2.1.9 事件流(高级部分,了解事件)

在这里插入图片描述

默认情况下,浏览器以冒泡的方式处理事件流

事件类型

//阻止事件冒泡
let child = document.getElementById('child');
    child.onclick = function(event){
        // console.dir(event);
        alert('子 元素被惦记了');
        event.stopPropagation();
    };
 //阻止默认行为(阻止跳转)
let a = document.querySelector('a');
    a.onclick = function(){
        alert('a标签被点击了');
        event.preventDefault();
    }
2.1.10 事件注册的方式

​ ① 传统方式

​ 第一种书写方式:直接在HTML标签元素中添加 onxxx="" (eg:onclick、onchange) 属性。在属性值中添加js代码。(一般是调用一个函数)

​ 第二种书写方式:在JavaScript代码中,为元素节点的 onxxx="" (eg:onclick、onchange) 属性赋值事件(一般是匿名函数,也可以是命名函数)

注意: 传统方式缺点:不能对统一元素节点重复注册事件监听。如果重复注册多个事件处理函数,name以最后一个为准(eg:两个函数名相同的弹窗事件只执行最后一个)

//通过为onclick、onchange之类的事件类型赋值为null,可以删除事件监听
btn.onclick = null;

​ ② w3c推荐方式

​ 通过元素节点的 addEventListener 方法,为节点添加事件 监听

//可选参数是一个boolean值,适用于设置事件流类型,true代表以捕获的方式处理事件流,false代表冒泡的方式处理事件流。
node.addEventListener(事件类型,事件处理函数,可选参数);

//通常写法
node.addEventListener(事件类型,事件处理函数);

注意:通过方法监听的方式,可以同一个元素节点的统一类型的事件重复这是处理函数,当事件触发时,所有函数都会被执行。

//如果有删除事件监听的需要,就必须将事件处理函数独立出出来removeEventListener(事件类型,事件处理函数)
//阻止事件默认行为,比如:链接的跳转,表单提交
e.preventDefault();
//阻止事件冒泡,调用之后,父元素将无法感知事件的发生
e.stopPropagation();

function fun3(e){
    alert('111111111111111111');
	//删除事件监听
    btn3.removeEventListener('click',fun3);
};      

event.target所指向的是box里面的最底层的事件

this是指所指向的box

2.1.11 事件委派

​ 当事件触发时,由于事件流会以冒泡的方式向上传递,父元素可以感知到事件的发生。

​ 这样在事件处理函数中,就有两个对象,分别指向了事件发生的元素,以及处理函数绑定的元素。

<div id = "box">
    <button id = "btn4">按钮</button>
</div>

<script>
let box = document.getElementById('box');
box.addEventListener('click',function(event){
    console.log(event.target);//event.target指向了事件产生的元素
    console.log(this);//this指向了当前处理函数所绑定的元素
});
</script>

事件委派原理

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件委派</title>
</head>
<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
    </ul>
</body>
<script>
    //事件委派
    //如果子元素特别多,为每一个子元素添加事件监听是不合算的
    //我们可以委托父元素处理这个事件
    //父元素可以通过事件对象的target属性得到真实触发事件的子元素,进行后续操作
    //优点:这样子做,我们只需要为一个元素注册一次事件监听即可,大大提升了程序性能。
    let ul = document.querySelector('ul');
    ul.addEventListener('click', function(e){
        let li = e.target;
        alert(li.innerText);
    });
</script>
</html>
2.1.12 表单事件

​ 常见的表单事件有:

事件说明
onfocus当表单元素获得焦点时触发
onblur当表单元素失去焦点时触发
onchange当表单元素的值发生改变时触发

​ 我们可以通过JavaScript代码主动触发事件:

node.click();
node.focus();

//千万不要在事件类型前面加  on  而是:
元素节点.事件类型();
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>表单事件</title>
    <style>
        form{
            width: 360px;
            margin: 50px auto;
            border: 1px solid #ddd;
            border-radius: 10px;
            padding: 50px;
        }
    </style>
    
</head>
<body>
    <form>
        <input id="imgSelect" type="file" style="display: none;">
        <button id="imgBtn" type="button">选择图片</button>
        <div>
            <input type="text" name="username" placeholder="用户名">
        </div>
        <div>
            <input type="text" name="password" placeholder="密码">
        </div>
        <div>
            <select  name="sf">
                <option value="sx">山西</option>
                <option value="hb">河北</option>
                <option value="bj">北京</option>
            </select>
        </div>
    </form>
</body>
<script>
    let username = document.querySelector('input[name="username"]');
    let pwd = document.querySelector('input[name="password"]');
    //当点用户名时候密码获得焦点
    pwd.onclick = function(e){
        console.log('密码输入框被点击。。。');
    };
    username.onfocus = function(e){
        console.log('用户名输入框获得焦点。。。');
        pwd.click();//此处click()是上面的pwd.onclick匿名函数
        // pwd.focus();//此处focus()是下面pwd.onfocus匿名函数
    };
    //在其他地方点击验证用户名是否合法
    username.onblur = function(e){
        console.log('用户名失去焦点。。。');
    };

    //省份不同,对应的市县不同处理方法是修改他的焦点

    let sf = document.querySelector('select[name="sf"]');
    sf.onchange=function(e){
        console.log('seclet被选择');
    };

    //事件转移:为了修改文件上传的输入框不好改的样式
    let imgBtn = document.getElementById('imgBtn');
    let imgSelect = document.getElementById('imgSelect');

    imgBtn.onclick = function(e){
        imgSelect.click();
    };


</script>
</html>
2.1.13 鼠标事件
坐标说明
screenX相对于电脑屏幕坐标原点的X坐标值,和浏览器本身在桌面的位置有关
screenY相对于电脑屏幕坐标原点的Y坐标值,和浏览器本身在桌面的位置有关
clientX鼠标在可视区域的X坐标值,和浏览器本身尺寸有关
clientY鼠标在可视区域的Y坐标值,和浏览器本身尺寸有关
pageX鼠标相对于真实的页面文档的X坐标,当页面滚动时,返回值不会变
pageY鼠标相对于真实的页面文档的Y坐标,当页面滚动时,返回值不会变

screen相对屏幕,client相对可视窗口,page相对html页面整体文档

2.1.14 键盘事件
事件说明
onkeyup键盘按键弹起时触发,按住不放不会触发,不区分大小写,默认是大写字母的ASCLL码值
onkeydown键盘按键按下时触发,按住不放会循环触发,不区分大小写(推进)
onkeypress键盘按键按下时触发,按住不放会循环触发,不能识别功能键,能区分大小写,默认返回是小写

按一下: :::down按下-------press按着-------up起来;;;;;顺序

<script>
    document.addEventListener( 'keyup',function(e){
        console.log('键盘弹起...up');
        // console.dir(e);
        //console.log('up',e.keyCode);
    });

    document.addEventListener('keydown',function(e){
        console.log('键盘按下...down');
    });

    document.addEventListener('keypress',function(e){
        console.log('键盘按下...press');
    });
</script>

键盘事件对象

​ 可以通过事件对象的keyCode属性获取按键值(ASCLL码值);

2.1.15 元素偏移量

① Offset偏移量

属性说明
offsetTop返回相对于 具有定位属性的父元素 的上边距
offsetLeft返回相对于 具有定位属性的父元素 的左边距
offsetHeight返回元素本身的高度 ,不包含单位(px)
offsetWidth返回元素本省的宽度 ,不包含单位(px)
offsetParent返回元素相对的父元素,如果所有父元素没有定位属性,继续往上找返回body
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值