#JavaScript
1.什么是javaScript
1.1 概述:
JavaScript是世界上最流行的脚本语言
一个合格的后端人员必须要精通JavaScript
javaScript语句十分松散,并没有java严谨,这导致有时候bug特别多
并且以后工作时接触的javaScript代码不会比java代码少
1.2 历史
ECMAScript可以理解为JavaScript的一个标准
最新版本已经到es6版本了但是浏览器大部分还只停留在es5代码上
这导致开发环境和线上环境版本不一样
2.快速入门
alert(score) 直接跳出弹窗
console.log(score) 在浏览器的控制台打印变量,相当于System.out.println(score)
2.1 编写javaScript代码的两种方式(往后简称js)
1 Script标签内直接写JavaScript代码,注意要加引号";"注释与java一样
<script>
alert('hello,world');//此方法为弹窗,会在打开页面的时候自动弹出
</script>
2 可以像css一项从外部引入,但是需要手动输入src然后导入
<script src="js/弹窗.js"></script>
2.2 基本语法入门
基本逻辑判断语句与Java一样此处略
浏览器调试代码需要的工具栏有:
Elements,Console,Sources,Network,Application
2.3 数据类型
数值,文本,图形,音频,视频 等等…
1.number
js无法区分小数和整数,统一使用number
整数,小数,科学计数法,负数 NaN(not a number) Infinity(无限)全部都可以显示使用
2.字符串
"aaa"或者’aaa’两种引号都可以表示
3.布尔值
true false
4.逻辑运算
&& 两个都为真,结果为真
|| 一个为真 结果为真
! 真改为假,假改为真
5.比较符运算
== 等于(类型不一样,值一样,如1和"1"也会判断为true)
=== 绝对等于(类型一样,值也必须等于结果才会为true)
注意:==是js中的一个缺陷,坚持不要使用 ==判断
PS:NaN与所有的数值都不相等,包括自己 只能通过isNaN(NaN)来判断这个数字是否是NaN
console.log((1/3) === (1-2/3));结果为false
尽量避免使用浮点数进行运算,因为存在精度问题
console.log(Math.abs(1/3-(1-2/3))<0.00000001);//结果为true,通常用此方法判断两个浮点数是否相等
6.null和undefined
null代表空 undefined代表未定义
7.数组
java中数组必须是一系列相同类型的对象,但是js中不需要是相同类型,
如:var arr =[1,2,34,5,“hello”,true]
或者 new Array(1,3,5,“hello”,true); 但尽量不要用这个
同时js中的数组依然有下标的概念console.log(arr[3]);//out:5
如果下标越界不会报异常,只会报undefined。(未定义)
8.对象
java中创建对象时使用 Person p=new Person();
但是js中new对象时使用大括号,传参同理,new数组是中括号
每个属性之间用逗号隔开,最后一个不用,
注意,js中对象参数一个设置错之后全部参数都会报错
var person={
name:'chinese',
age:21,
tags:['js','java','web','...']
};
9.变量声明方式
Java中的变量声明标准在js中全都可以使用
2.4 严格检查模式 ‘use strict’
前提:idea需要设置支持es6语法 ‘use strict’
'use strict’必须放在script标签中的第一行
为了更规范代码,预防js的随意性导致产生一些问题可以使用’use strict’;来开启严格检查模式
3.数据类型
3.1 字符串
1.正常的字符串一般使用单引号或者双引号包裹
2.注意转义字符,也是要在字符串包裹内才能有效
3.多行字符串编写
tab上面(esc下面)的引号键 可以用来编写多行长字符串 `
var msg=
hello
world
`
4.模板字符串
//平时Java中println(“姓名:”+name)这种表达方法在script中有了新的定义
let name="gege";
let age=3;
let aaa=`你好啊,${name}`;
console.log(aaa);
console.log(`你好啊,${name}`);
5.字符串长度
var student='student';
console.log(student.length);//out:7
6.字符串的不可变性
student[3]=1
1
console.log(student);
out:1 student
字符串声明之后再改动虽然不会报错,但是依然会修改失败
7.大小写转换
注意,此处用的是方法,浏览器上只会提示属性关键字
转换大写方法为:console.log(student.toUpperCase());
转换小写方法为:console.log(student.toLowerCase())
8.student.indexOf(‘t’);返回字符串中对应元素下标
9.substring 截取下标对应的字符串元素,包含前面后不包含后面
console.log(student.substring(1,3)) out: tu
console.log(student.substring(1))从第一个字符串元素截取到最后一个字符串
3.2 数组
Array可以包含任意的数据类型
1.长度
-
假如给已有的数组长度赋值,数组大小就会发生变化,如果赋值变小,元素就会丢失,如果赋值变大2则增加两个空值empty × 2
-
如果查询多出的两个就会返回undefined
2.indexOf
通过元素获得下标索引,如果一个数组中同时有字符串"1"和数字1两者可以被程序区分开
3.slice()
截取Array的一部分,返回一个新的数组 其实就是数组版的substring()
4.push与pop
-
push会在数组’‘后面’'添加(压入)元素 arr.push(‘a’,‘b’)
-
pop会在数组’‘后面’'弹出尾部的元素,一次默认一个 arr.pop()
5.unshift(),shift()
unshift()是从头部添加(压入)元素
shift()是从头部弹出元素
6.排序 sort()
[“b”, “c”, “a”] a.sort() [“a”, “b”, “c”]
7.元素反转 reverse()
a.reverse() [“c”, “b”, “a”]
8.concat() 拼接数组
不会修改数组,只是会返回一个新的数组
arr.concat([‘q’,‘w’,]) //将[‘q’,‘w’]则会个数组拼接到arr中,
输出结果为: (10) [1, 2, 3, 4, 5, “1”, “2”, true, “q”, “w”]
9.连接符join
打印拼接数组,使用特定的字符串链接数组中的各个元素
arr.join("-") //输出为:“1-2-3-4-5-1-2-true”
10.多维数组
arr=[[11,22],[33,44],[55,66]]
查询的时候按照下标套下标,
如下: arr [2][1] 66
3.3 对象
js中对象是由{}来包含若干个键值对组成的,多个属性之间用逗号隔开,最后一个属性不加逗号
js中所有的键都是字符串,值是任意对象!
var 对象名={ 属性名:属性值, 属性名:属性值, 属性名:属性值 }
如:var person={ name:“baba”, age:16, qq:2045807586 }
1.对象赋值
格式: 对象.属性=‘新属性’ 进行赋值
注意: 使用一个不存在的对象属性时,不会报错!只会提示undefined
2.动态增删属性
Java做不到的js也能做
3.对象自身属性的逻辑判断
判断属性是否再这个对象中:
“name” in person //true
同时还可以判断是否是继承关系:
‘toString’ in person //true
判断一个属性是否是这个对象所拥有的:
person.hasOwnProperty(‘toString’) //false
person.hasOwnProperty(‘age’) //true
3.4 流程控制
1.if判断
与java一致,略
2.while循环
while(age<70){
age=age+1;
console.log(age)
}
do{
age=age+1;
console.log(age)
}while(age<70)
3.for循环
for (let i = 0; i <10 ; i++) {
console.log(i)
}
// forEach循环:
let age=[12,13,14,15];
//可以在这边看到forEach变为了一个具体的函数方法,然后又向参数中又套了一个函数,函数中又套了value作为参数,最后打印value
age.forEach(function (value) {
console.log(value)
})
//for....in循环
//该循环格式为for(var index in object){}
for (var num in age){
//这里的num代表数组的下标(索引) 下面是判断age是否包含
if (age.hasOwnProperty(num)){
console.log("存在");
console.log(age[num])
}
}
但是使用循环时尽量避免像下面这样的死循环弹窗,跟病毒一样
while(true){ alert(“你就是个弟弟”)}
3.5 Map和Set集合 (ES6)
1.JavaScript中的集合
ES6的新特性~之前没有map和set,现在也只有map和set两种集合
//Map:键值对类型的集合
var map=new Map([['tom',99],['mark',50],['w1',150]]);
//通过get(key值)来获取key值对应的value
var name=map.get('tom');
console.log(name)
map.set('as',89);//通过set来进行添加数据
map.delete('tom');//通过删除key值来进行删除操作
for (let x of map){
console.log(x);//for...of也可以进行遍历map集合
}
//Set:代表无序不重复的集合 如果创建的时候有多余重复的元素会消失
var s=new Set([9,9,5,5,12,13,13]);
s.add(3);//添加元素的时候注意不能重复,否则无意义
s.delete(1);
console.log(s.has(3))//true
2.inerator迭代器
var arr=[1,2,3,5];
arr.name="aaa";
for (var x in arr){
console.log(x);//for...in返回的是下标
}
for (var x of arr){
console.log(x);//for...of返回的是具体的元素
}
3.迭代器遍历集合
// 遍历Map集合
var map=new Map([['tom',99],['mark',50],['w1',150]])
for (let x of map){
console.log(x);//for...of也可以进行遍历map集合
}
//遍历Set集合
var s=new Set([9,9,5,5,12,13,13]);
for (let x of s){
console.log(x);
}
4.函数
4.1 定义函数
注意: 一旦执行return,就代表函数结束,返回结果 如果没有执行return,函数执行完也会返回结果,结果就是undefined
如下两种定义方式: (abs为函数名称 x为参数)
调用函数时需要手动在控制台输入abs(x),x代表你将要传入的自定义参数
注意:js如果想调用一个无参方法,需要在script标签中创建之后再次声明调用,如声明aa函数方法后,再次在函数外边aa()调用这个函数方法才能在浏览器控制台运行,或者在控制台再输入aa() 如果是内部类,则需要在外部类中调用
定义方式1
此方法偏向于后端,与Java有些类似
//如下js中定义函数(方法)的格式:(求绝对值)
function abs(x){
if(x>=0){
return x;
}else{
return -x;
}
}
定义方式2
//此方法与方法1一样都是求绝对值,但是格式不同
var abs = function(x){
if(x>=0){
return x;
}else{
return -x;
}
}
异常处理方面
如果向带参函数中,直接使用无参调用,那么就会显示NaN
所以有些时候需要我们手动来添加一个报异常的判断方法,
(throw后跟字符串) 如下:
var abs = function(x){
//提前手动抛出异常
if(typeof x!=='number'){
throw 'Not a Number,你传的参数是什么玩意?';
}
if(x>=0){
return x;
}else{
return -x;
}
}
4.2 参数获取
arguments
‘arguments’ 是一个js免费赠送的关键字, js会将方法中传入的所有参数都放在这个arguments数组中 这样就可以利用**arguments[]**传入下标来获取各个参数
甚至可以利用传入参数的数量不同来调用不同的方法 (但这样会导致代码太过于臃肿)
var abs = function(x){
console.log("x=>"+x);
//如下:使用for循环遍历aeguments参数
for (let i = 0; i <arguments.length ; i++) {
console.log(arguments[i]);
}
if(x>=0){
return x;
}else{
return -x;
}
}
但是arguments存在一个问题:arguments包含所有的参数,但是有时候想要是用多余的参数来进行附加操作 需要排除部分已有参数,这样就需要用到下面的es6的新特性了
rest
ES6新特性,相当于arguments的升级版
rest可以获取除了已经定义的参数之外的所有参数并整合为一个参数~(类似于Java传参中的可变长参数 int…) 但是rest参数只能写在参数列表的最后边
function aaa(a,b,...rest){
console.log("a=>"+a);
console.log("b=>"+b);
console.log(rest);
}
测试结果如下:
4.3 变量的作用域
在JavaScript中,var定义变量实际是有作用域的
1.函数体自身变量作用域
假设在函数体中声明变量,则在函数体外不可以使用
(如果非要实现的话,可以在后期研究一下闭包)
function aa() {
var x=1;
x=x+1;
}
x=x+2;//这里会报错,Uncaught ReferenceError: x is not defined
2.不同函数的同名变量问题
function a() {
var x=5;
x=x+1;
console.log(x);
}
function b() {
var x=9;
x=x+1;
console.log(x);
}
3.内部函数(类)
//内部类可以访问外部类的属性,
// 但是外部类无法访问内部类的属性
function aa() {
let x=1;
console.log(x);
function aa1() {
let y = x + 1; //2
console.log(y);
}
let z=y+1; //报错 Uncaught ReferenceError: x is not defined,x未定义
console.log(z);
}
4. 内外函数变量优先级问题
假设,内部函数变量和外部函数变量重名,则优先从自身函数变量中查找,
或者说是由内向外查找 假设外部函数存在同名的函数变量,则内部函数会屏蔽外部函数变量(类似覆盖)
function xg() {
var x=1;
function xg1() {
let x='xxx';
console.log(x);
}
xg1();
}
xg();// 'xxx'
5.变量作用域的提升
function xg2() {
var x='x'+y;
console.log(x);
//结果输出为'xundefined',注意此处不是x本身undefined
//而是输出x和y,只不过y本身undefined
var y='y';
}
xg2();
注意,一般未定义会直接报错,而不是undefined
说明了:js执行引擎操作时,自动把y的声明往前面提升,但是却不会提升变量y的赋值 这是在js建立之初就存在的特性,
所以一般在函数方法中,尽量将变量声明提在最前面,这样便于代码维护
6.全局变量
定义在方法外面的就是全局变量
let b=1;
function f() {
console.log(b); // 1
}
f();
console.log(b); //1
7.全局对象 window
var x='xxx';
alert(x);
alert(window.x); //两者输出效果一致
//默认所有的全局变量都会自动绑定在window对象下
//alert()这个函数本身也是一个window的变量
测试代码如下:
window.alert(x);//这里是一个全局对象实例
let old_alert=window.alert;//这里将window.alert本身(作为一个对象)再定义为一个新的变量,
// 注意,这里必须是window.alert不能是window.alert()
old_alert(x);//由于alert是一个带参函数(方法),所以再给这个函数一个参数就相当于再次调用了alert()方法 (详见函数的定义方法2)
window.alert=function () {}
//这时将window.alert重新定义一个空的函数方法
window.alert(998);//给无参函数传递参数自然会失效
window.alert=old_alert;//这里用之前定义好的old_alert再定义给window.alert
//注意,将一个方法作为对象传递给另外一个参数时,不能带括号(也就是方法体),不然这里只会出现一个空的弹窗
window.alert(123123123);//这里自然就成功弹出了
//整个过程就是来回赋值,给b定义一个a函数,得到函数b,然后把a函数作废,再把b定义给a
```
JavaScript实际上只有一个全局作用域,任何变量(函数本身也可以视为变量),假如没有在函数作用范围内找到就会向外查找,
假如在全局作用域都没有找到,那么就会报错 ReferenceError
所以就有了这么一个问题:由于所有的全局变量都会绑定到window上面,如果不同人的js文件偶然使用了相同的全局变量就会产生冲突
8.window全局变量的命名冲突问题
解决方法如下:
//先定义一个唯一全局变量
let xg={};
//从唯一全局变量中再次定义全局变量
xg.name="daxi";
//从唯一全局变量定义方法
xg.add=function (a,b) {
return a+b;
}
也就是把自己代码的变量全部放入自定义的唯一全局变量中
通过定义"变量.变量=xxx"来减少冲突的可能性
9.局部作用域与let
function aaa() {
for (var i = 0; i <5 ; i++) {
console.log(i);
}
console.log(i+1);//注意,这里使用var之后出了i应有的for循环作用域依然可以使用,这就是一个问题了
}
所以为了解决这个问题,一般推荐使用ES6的let声明局部变量
10.常量 const
官方名字叫做只读变量,效果与静态变量一样
在ES6之前定义常量只能通过人为的约定,
如: 约定好只有用全部大写字母明明的变量就是常量,然后人为约定好不要修改这样的值 这样人为的约定台不靠谱了,
所以在ES6中引入了常量关键字 const 代码如下:
const dx=222;
console.log(dx);
dx=333;
//这里如果再次定义的话就会报错:已经是一个只读变量,无法被改变
//在浏览器运行也会报错:TypeError: Assignment to constant variable.(类型错误)
4.4 方法
方法就是把函数放在对象的里面,对象只有两个东西:属性和方法
1.方法的定义
let xg={
name:"czx",
birth:1998,
//方法
age:function () {
let now=new Date().getFullYear();
//这个函数方法是获取当前年数
return now - this.birth;
xg.age(); // 22
}
}
2.方法的调用
调用属性: xg.name
调用方法: xg.age() 注意,调用方法必须要带上括号
将’‘方法的定义’'中的对象进行拆分则是:
let now=new Date().getFullYear();
return now - this.birth;
}
let xg={
name:"czx",
birth:1998,
age:getAge //注意 ,此处将一个函数作为属性值定义给另一个属性时不能加括号
}
控制台调用xg.age()可以正常输出 但是调用getAge()则会出现NaN,
因为: this始终指向调用者的属性,可是直接调用getAge()的话window中没有birth这个属性 所以会出现NaN
3.apply (this指向控制)
一般在JAVA中this无法指定指向哪个对象,永远都默认指向调用它的那个对象,但是js中有些改动,apply就是专门用来控制this指向的
getAge.apply(xg,[]);//代表this指向xg,参数为空
还需要在控制台中输入这句代码才能得到结果· 这样就可以将this定向调用
5.内部对象
5.1 标准对象
(利用typeof可以返回对象的数据类型)
typeof 123 //“number”
typeof ‘123’ //“string”
typeof true //“boolean”
typeof NaN //“number”
typeof undefined //“undefined”
typeof [] //“object”
typeof {} //“object”
typeof Date"function" //函数类型
5.2 Date
注意,使用时都按照方法来进行调用,而不是属性
let now= new Date();//Thu Mar 12 2020 12:25:07 GMT+0800 (中国标准时间)
now.getFullYear();//年
now.getMonth();//月
now.getDate();//日
now.getDay();//星期几
now.getHours();//时
now.getMinutes();//分
now.getSeconds();//秒
now.getTime();//时间戳 全世界统一 返回一串数字
console.log(new Date(1583995960754))
//里面的一串数字就是时间戳返回的
//得到的结果为:1 Thu Mar 12 2020 14:52:40 GMT+0800 (中国标准时间)
now.toLocaleString();//获取本地主机时间"2020/3/12 下午2:52:40"
now.toGMTString();// GMT时间"Thu, 12 Mar 2020 06:52:40 GMT"
5.3 JSON
1. json是什么
早期,所有的数据传输习惯使用XML文件!
JSON(javaScript Object Notation,意为js对象简谱) 是一种轻量级的数据交换格式
简洁和清晰的"层次结构"使得JSON成为理想的数据交换语言
方便人们阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率
在JavaScript中一切皆为对象,任何js支持的类型都可以用json来表示
(其实就相当于支付宝,你的钱(代码)存在支付宝(JSON)中才能更快的转账交易(数据交互),
要转账了就存进去(代码转换为json字符串,具体方法为JSON.stringify(a)),
不转帐了就取出来用(json转换为代码,具体方法为JSON.parse(),括号内为JSON字符串,记得用引号包裹)
而json中本身也只有两个方法,代码转json和json转代码
格式: 对象都用{} 数组都用[] 所有的键值对都是用 key:value
```javascript
let a ={
name:‘xg’,
age:15,
like:‘game’
}
console.log(a);
// 输出为:1 {name: “xg”, age: 15, like: “game”}
let s=JSON.stringify(a);
console.log(s);
//输出为:1 {“name”:“xg”,“age”:15,“like”:“game”}
JSON.parse(’{“name”:“xg”,“age”:15,“like”:“game”}’);
//输出为{name: “xg”, age: 15, like: “game”}
```
注意:对象转换为json后。可以看到对象中的各个属性也转换为字符串(也用引号包裹了)了
json转化为对象时也需要将整个字符串对象再用引号包裹起来
6.面向对象编程
类:模板 原型对象
对象:具体的实例
6.1 原型继承
gg.__proto__=xx;//js的原型也是只能有一个,所以会被后来的原型继承覆盖
gg.__proto__=xg;//此处意为将xg对象视作gg的原型(爹)(在Java来讲就是gg是xg的子类,gg继承了xg)
//然后就可以调用xg的属性和方法了
//如果有其他的方法也可以继承,但也是只能指向一个对象
6.2 class继承
1.定义一个类:属性 ,方法
class student{
constructor(name){//js所有的构造器都叫做constructor
this.name=name;
}
hello(){
alert('hello'+name)
}
}
let xiaoming =new student('xg');
let xiaobai =new student('gg');
2.class继承一个类
本质还是指向原型,只不过换了一种表现形式
class student{
constructor(name){//js所有的构造器都叫做constructor
this.name=name;
}
hello(){
alert('hello'+this.name)
}
}
//继承如下:
class xiaostudent extends student{
constructor(name,score) {
super(name);
this.score=score;
}
myscore(name,score){
//对象里的方法调用对象的属性需要加this
alert('我是'+this.name+',今天考了'+this.score+'分!!!');
}
}
var xiaoming =new student('小明');
xiaoming.hello();
let xiaobai =new xiaostudent('小白',100);
xiaobai.myscore();
6.3原型链
prototype就是原型的意思
foo.prototype也就是foo的原型
7.操作BOM对象
BOM就是浏览器的对象
7.1 浏览器介绍
JavaScript和浏览器的关系 :
JavaScript的诞生就是为了能够让他在浏览器中运行
现有主流浏览器有: (有内核)
IE 6~11 (windows系统)
Chrome (谷歌浏览器) (windows系统)
Safari (苹果浏览器) (苹果系统)
FireFox (火狐浏览器) (linux系统)
7.2 window (浏览器窗口)
window.innerHeight 返回内部高度 (不固定)
window.innerWidth 返回内部宽度
window.outerHeight 返回外部高度
window.outerWidth 返回外部宽度
7.3 Navigator
Navigator 封装了浏览器的信息 不建议使用
navigator.appName 返回当前应用名
navigator.appVersion 返回当前浏览器版本号
navigator.userAgent 返回用户消息
navigator.platform 获得系统的版本
大多数时候一般不会使用navigator对象,因为会被人为的修改不建议使用这些属性来判断和编写代码
不能将此对象返回的数据当作条件判断依据,因为这些数据都是可以被更改的
7.4 screen
screen封装了全屏幕的属性
screen.width 屏幕宽度
screen.height 屏幕高度
7.5 location 重要
location代表当前页面的URL信息
可以直接输入返回全部信息,也可以location.host返回具体消息
需要注意的几条属性有:
host: “www.baidu.com” //主机
href: “https://www.baidu.com/” //地址
protocol: “https:” //协议名
reload: ƒ reload() //刷新网页的方法
location.assign(’’) //相当于一个跳转,一般方法为空,但是可以手动在里设置跳转的地址 重要 坐牢全靠它
7.6 document
document代表当前的页面信息 html DOM文档树
比如获取标题:
获取具体的文档树节点:
let dl=document.getElementById(‘app’);
//此方法可以根据id来获取具体的节点,同时也可以根据类或者标签来获取
获取cookie: 也就是客户端的本地信息,这些信息将会被发送到服务器
document.cookie;
劫持cookie的原理:
通过恶意代码(getcookie方法)获取你的cookie然后通过他的客户端上传你的cookie从而获取你的账户信息,登录上你的账户服务器端
可以设置cookie:httpOnly (代表只读)可以保证安全性
7.7 history (历史记录)
history就是点开超链接之后的前进(前往超链接)和后退(返回原历史页面)
history只有两个方法 很重要
history.forward(); //前进
history.back(); //后退
8.操作DOM对象
DOM: 文档对象模型
8.1 DOM核心基础
浏览器网页就是一个DOM树型结构,这个结构上有一根一根用各种标签(p标签,a标签,ul li标签)组成的树枝,
树枝(标签)与树干(网页)的连接处就叫做节点
除了先天生长出树枝(建立之初的手动添加)之外,还可以进行后天的加工(操作DOM对象)
相关操作有:
1 更新: 更新DOM节点 比如添加一个新的属性
2 遍历: 得到DOM节点
3 删除: 删除DOM节点
4 添加: 添加一个新DOM节点
要操作一个Dom节点,就必须要先获得的这个Dom节点
选中方式如下:
var h1=document.getElementsByTagName('h1'); //选中标签
var h2=document.getElementById('p1'); //选中id
var h3=document.getElementsByClassName('p2');//选中类名
var father=document.getElementById('father');
//可以通过父类节点获取子类所有节点,如下:
var childrens=father.children;
//输出为:HTMLCollection(3) [h1, p#p1, p.p2, p1: p#p1]
var ch=father.children[0];
//由于得到的是一个数组,所以可以通过选定下标来确定具体的元素
father.firstChild; //选中父类第一个节点
father.lastChild; //选中父类最后一个节点
注意:这是原生代码,之后会学到jQuery,使用jq写比这样写要方便的多
8.2更新DOM节点
a.innerText=‘123’;注意,这里是通过id来获取innerText方法来进行添加"123"
a.innerHTML=‘hahahahahahha’;"
a.innerHTML可以解析HTML文本并执行代码
a.innerText只能上传字符串文本
a.style.fontSize=‘70px’; //css代码也可以执行
var ss=document.getElementById(‘su’); //并且属性要使用字符串包裹
ss.style.fontSize=‘10px’; //在这里-需要转换为驼峰命名
8.3删除DOM节点
节点都无法自我删除,只能通过父节点来删除子节点
删除节点的步骤:
//方法1:首先通过自己的id属性获取父节点:
var fa=p1.parentElement;
//再通过父节点删除自己
fa.removeChild(p1);
//方法2 通过选中father.children返回的数组元素,进行选定删除
father.removeChild(father.children[0]);//删除原第一个节点
father.removeChild(father.children[0]);//原第二个节点
father.removeChild(father.children[0]);//原第三个节点
但是使用下标进行删除时绝对要注意:
删除第一个元素的瞬间,所有元素都会自动向前补位
也就是说三个元素中删除下标为0的第一个元素时,
第二个元素的下标已经从1变为0 第三个元素的下标也从2变为1了
8.4 插入DOM节点
获得了某个DOM节点,如果这个DOM节点是空的,那么就可以通过innerHTML来增加一个元素
但是如果这个DOM节点已经存在元素了,那么就不能这么操作了,不然就会产生覆盖
<p id="p0">sql</p>
<div id="father">
<p id="p1">javase</p>
<p id="p2">javascript</p>
<p id="p3">html</p>
<p id="p4">css</p>
</div>
<script>
//需求:将sql也放在div标签中
let a1=document.getElementById('p0')//获取已经存在的节点
let fa=document.getElementById('father');//获取父节点
father.appendChild(p0); //使用父节点调用添加方法
//需求:通过js创建一个新的节点并添加到div标签中
let a2=document.createElement('p');//创建一个p标签
a2.id='p5'; //给p标签赋值一个新id属性
a2.innerText='jdbc'; //给p标签添加文本
father.append(a2); //注意,这里括号中是元素而不是id
//需求:创建一个script标签节点 对就是用js创建js标签
let news=document.createElement('script'); //首先创建一个script标签
news.setAttribute('type','text/javascript'); //然后给这个script标签设置参数,设置的参数属于键值对关系
father.appendChild(news);//最后添加到相应的父节点
//需求:创建一个Style标签进而改变背景颜色
//首先动态的创建一个style标签
let ns=document.createElement('style');
ns.setAttribute('type','text/css'); //设置文本参数,注意,文本参数是固定的(指'text/css'),否则不起作用
//设置标签内容
ns.innerHTML='body{background-color: #728ee9;}';
document.getElementsByTagName('head')[0].append(ns);
//注意,document.getElementsByTagName('head')返回的不是头部标签<head>,返回的是包含头部标签的对象数组
//这个对象数组的第一个才是头部标签,然后再选中并append添加标签
//需求,创建一个标签并将其插入到目标前面
let eq=document.getElementById('jse');//首先都是获取节点
let eq1=document.getElementById('js');
let eq2=document.getElementById('father');
//格式: 要包含的节点(父节点).insertBefore(新节点,目标节点)
eq2.insertBefore(js,jse);//把一个节点插在目标节点的前面
eq2.insertBefore(jse,js);//通过调换括号的顺序可以改变顺序
</script>
style标签需求的步骤图:
9.表单
表单一般是用来处理验证问题的
1.什么是表单
(详见html笔记)
文本框 text
下拉框
单选框 radio
多选框 checkbox
隐藏域 hidden
密码框 password等等…
2.表单的目的是什么
一般是用来提交信息以及进行验证操作
以下是表单的一些操作,以及密码的四种加密手法
重点记住密码的隐藏域加密和表单提交加密:
<!-- md5工具类-->
<script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script>
</head>
<body>
//使用表单绑定(onsubmit)提交事件 onsubmit绑定一个提交检测的函数 并返回布尔值再将这个结果返回给表单,最后使用onsubmit接收
//前面的return是自己添加的,这样如果方法返回值为false则不能跳转
<form action="登录内容.html" method="get" onsubmit=" return aaa()">
<p>
<span>用户名:</span><input type="text" id="username" name="username" required placeholder="请输入用户名">
</p>
<p>
<span>密码:</span><input type="text" id="password" name="password" required placeholder="密码">
</p>
<input type="hidden" id="md5-password" name="password">
//hidden代表隐藏,这是一个隐藏域,用这个来接收密码输入栏经过md5加密后的结果
<input type="submit" onclick="aaa()">
//给按钮绑定事件 onclick 被点击时触发函数
<button type="submit" onclick="aaa()">提交</button>
</form>
<script>
function aaa() {
alert('what are you 弄啥哩?');
//获取用户名节点
let ad=document.getElementById('username');
//获取密码节点
let pd=document.getElementById('password');
//获取md5密码节点(md5隐藏域用到的代码)
let md5pd=document.getElementById('md5-password');
console.log(ad.value);//通过获取节点的值value,也就是用户名和密码
console.log(pd.value);
//注意,一般真正的登录都需要拦截表单,获取密码并进行二次加密
//所以也就需要对密码进行二次加密:
//方法1.发送请求之后,再次进行修改
pd.value='*****';
//方法2 使用MD5进行二次加密 但是使用此方法跳转的瞬间会看到密码被加长,别人会根据这一点立马就知道使用了什么方法
pd.value=md5(pd.value); //md5本身就是一个方法
//效果:password: fddd21b9d7ce17da93c30fa5a653a1df
console.log(pd.value);
//方法三 使用隐藏域隐藏MD5的密码加密效果 这个方法是最优解
md5pd.value=md5(pd.value);
//效果与二一样 password: fddd21b9d7ce17da93c30fa5a653a1df
console.log(pd.value);
//方法四,表单验证
/*使用表单绑定(onsubmit)提交事件 onsubmit绑定一个提交检测的函数 并返回布尔值
再将这个结果返回给表单,最后使用onsubmit接收
前面的return是自己添加的,这样如果方法返回值为false则不能跳转*/
/<form action="登录内容.html" method="get" onsubmit=" return aaa()">
}
10.jQuery
javaScript与jQuery(库)的关系:
jQuery就相当于是JavaScript的一个大型工具类
里面有大量的JavaScript函数方法
1.获取jQuery
方法1 官网下载
方法2 在线cdn jQuery链接
<script src="https://cdn.bootcss.com/jquery/3.4.1/core.js"></script>
2.jQuery选择器对比
//原生js选择器代码 选择器少 并且不好记
//标签选择器
document.getElementsByTagName();
//id选择器
document.getElementById();
//类选择器
document.getElementsByClassName();
//jQuery选择器 css中的选择器都能用
('p').click(); //使用标签选择器
('#id').click(); //使用id选择器
$('.class').click(); //使用类选择器
3.jquery事件
//其他的各种事件方法都在网上有说明,不一一演示,到时候自己看,
// 就在编程辅助工具中jQuery中文api文档的最右边
//需求:获取鼠标当前的一个坐标
mouse: <span id="mousemove"></span>
<div id="divmove">
在这里移动鼠标试试
</div>
//当网页元素加载完毕之后,响应事件 document就是文档 ready就是加载完之后的事件,两者都是默认,所以可以省略
//详细代码: $(document).ready(function () {})
<script>
$(function () {
//mousemove 代表鼠标移动之后响应事件,触发函数方法
$('#divmove').mousemove(function (e) {
//下面的函数方法又指向另外一个元素的文本,并在文本中显示
$('#mousemove').text('x:'+e.pageX+',y:'+e.pageY);
})
})
</script>
4. jQuery操作DOM元素123
// 原生:document.getElementsByClassName('js');
$('#testul li[class=py]').text('4566454');
//选择器不单单只能选择一个, 修改文本
$('#testul li[class=js]').html('<strong>473400</strong>'); //修改html
//css操作:
$('#testul li[class=js]').css('color','red');
//如果有多个操作:
$('#testul li[class=py]').css('font-size','40px');
//元素的隐藏和显示
$('#testul li[class=py]').hide();
$('#testul li[class=py]').show();
//测试
$(window).width(); //1024
$(window).height(); //267
// 如果文本是显示就改为隐藏 如果是隐藏就改为显示:
$('#testul li[class=js]').toggle();