JavaEE03_JavaScript

JavaEE03_JavaScript

1、使用javascript

1.1 js引入

Javascript代码写在script标签内,且script标签s必须成对出现,不能自闭和,不然会出错

<script type="text/javascript">
    
</script>

引入外部 文件名.js代码(src后跟路径)

<script src="js/qj.js"></script>

1.2 基本语法

语法基本与java一致,不过js的变量只有var和let

var是全局bianl

let是局部变量

可以通过console.log()在浏览器控制台输出(浏览器F12)

alert()弹出弹窗

var的基本测试

/**
 * 基本类型var:
 *    1.number:js不区分小数和整数
 *              123   整数123
 *              123.1 浮点数123.1
 *              1.123e3  科学计数法
 *              -99    负数
 *              NaN    not a number
 *              Infinity  表示无限大
 *     2.字符串:'abc'  "abc"
 *     3.布尔值:true false(与java用法一样)
 *     4.逻辑运算:&&
 *                ||
 *                !
 *     5.比较(重要)
 *      =      赋值
 *      ==     等于(类型不一样,值一样,也会判断为true)
 *      ===    绝对等于(类型一样,值一样才会判断为true)
 *      避免使用==,容易出问题
 *     6.NaN  与所有数值都不相等,包括自身
 *     只能通过NisNaN(NaN)来判断这个数是否为NaN
 *
 *     7.浮点数问题
 *      console.log((1/3)===(1-2/3));    因为精度会缺失,所以输出false
        console.log(Math.abs((1/3)-(1-2/3))<0.00000001); 精度小于0.00000001,默认两个相等
 *     8.null和undefined
 *       null 空
 *       undefined 未定义
 *     9.数组:java必须是一系列相同类型的对象,在JS中并不需要这样,因为var是所有类型,如果越界就会undefined
 *     var arr=[1,2,3,4,'name',true,null];
 *     console.log(arr[1]);
 *     10.对象:对象是大括号,数组是中括号
 *     每个属性之间使用逗号隔开,最后一个不需要添加
 *     输出:person.name
 */

1.3严格检查模式

<script>
    'use strict'
</script>

前提:IDEA 需要设置支持ES6语法

‘use strict’ 严格检查模式,预防js的随意性导致产生的一些问题,比如直接写i=1;没有去定义它为 var或let也是可以使用的,且默认是var

必须写在javascript的第一行

2、js详解

2.1字符串

  • 正常字符串一般使用单引号或双引号包裹。

  • 转义字符:

/**
 *
 * 2、转义字符
 *    \'
 *    \n
 *    \t
 *    \u4e2d    // \u#### Unicode编码
 *    \x41      //ascll
 *
 */
console.log('a\'');
console.log("a\nd");
console.log("\u4e2d\n\x41");

  • 多行字符串编写(tab上面的 ` 键)

    let msg= `
    xiaosi
    world
    `
    console.log(msg)
    
  • 模板字符串

    let name="xiaosi";
    let  msg2=`你好,${name}`
    
  • 字符串长度:.length

  • 字符串的不可变性

    var myStr = "Bob";
    myStr[0] = "J";//这是无法实现的,字符串创建完单个值是无法改变的,要改变要重新给它赋一个值
    
    var myStr = "Bob";
    myStr = "Job";
    
  • 大小写转换

    .toUpperCase()转大写

    .toLowerCase()转小写

  • 显示某字符的下标

    .indexOf(’ ')

  • substring

    .substring(n,m) 从第n个字符串截取到最后m个字符串,若m没写就是到最后一个字符串[n,m)

2.2 数组

  • 长度:给arr.length赋值,数组大小就会发生变化,自动添加undefined,如果赋值过小,元素就会丢失

    arr.length=10;
    
  • indexOf,通过元素获得下标索引,字符串的"1"和数字的1是不一样的,字符串的"1"是获取此字符串的下标值,1是获取下标1的字符串

  • slice()截取Array的一部分,返回一个新数组,类似String中的substring

    数组.slice(n) :从下标n开始截取,到最后一个字符,且原数组不会发生改变

  • push pop

    arr2.push("a","b");//压入尾部
    console.log(arr2);
    arr2.pop();//弹出尾部
    console.log(arr2);
    
  • unshift() shift()

    arr2.unshift("a","b");//压入头部
    console.log(arr2);
    arr2.shift();//弹出头部
    console.log(arr2);
    
  • 排序sort()

    sort() 方法用于对数组的元素进行排序。

    排序顺序可以是字母或数字,并按升序或降序。

    默认排序顺序为按字母升序。

  • 元素反转

    .reverse()

  • 拼接 concat,并没有修改数组,只是会返回一个新的数组

    arr3.concat(arr2)  //不会改变原数组
    
  • 连接符join,打印拼接数组,使用特定的字符串连接

    console.log(arr3.join('-'));
    //结果C-B-A
    
  • 多维数组

    let  arr4=[ [1,2],
                [3,4],
                ["5","6"] ];
    console.log(arr4[1][1]);
    

2.3 对象

var 对象名={

​ 属性名:属性值,

​ 属性名:属性值

}

var person={
        //多个属性用逗号隔开,最后一个不加逗号
        name:'xiaosi',
        age:3,
        email:"1170035083@qq.com",
        score:0
    }
//对象赋值
person.name='haishi';
//使用一个不存在的对象属性,不会报错,会undefined
console.log(person.haha);
//动态删除属性,通过delete删除对象属性,可以在控制台直接删除
delete person.score;
//动态添加,直接给新的属性添加值就可以
person.haha="haha";
//判断属性值是否在对象中   xxx in xxx
console.log('name' in person);
console.log('toString' in person);//true 可以知道它父类的方法
//判断一个属性是否是这个对象自身拥有的hasOwnProperty
console.log(person.hasOwnProperty('name'));//true
console.log(person.hasOwnProperty('toString'));//false

Object的hasOwnProperty()方法返回一个布尔值,判断对象是否包含特定的自身(非继承)属性。

pereson里面有name属性,虽然他的父类有toString但是他自己没有,所以是false

2.4 流程控制

除了foreach,其余的与java一致

//判断
var age=3;
 if(age>3){
     alert("haha");
 }else{
     alert("kuwa");
 }
//循环
while(age<100){
    age++;
    console.log(age);
}
//for循环
for(let i=100;i<110;i++){
    console.log(i);
}
//foreach循环,对象可以value.xxx
var arr=[1,2,3,34,54,6,7,12,32];
arr.forEach(function (value) {
    console.log(value);
})
/*
* 在java中,for(Type str:el){}
* */

2.5 Map和Set

与java一致

//ES6的新特性
//学生的成绩,学生的名字
var map=new Map([['tom',100],['jack',90],['haha',80]]);
var name=map.get('tom');
console.log(name);
map.set('admin',10);
console.log(map);
map.delete('tom');

var set=new Set([3,1,1,1,1]);//set可以去重
set.add(2);
console.log(set);
set.delete(1);
console.log(set);
console.log(set.has(3));//里面是否包含x

2.6 iterator

// for in只能打印下标,新增下标不能正常显示下标,会直接显示里面的值
//若for in要打印数值的话,用下面实现
for(var num in arr){
	console.log(arr[num]);//这里的num只是下标
}

//通过for of来打印数 遍历map 遍历set都是一样的
for(let x of arr){
    console.log(x);
}

2.7 定义函数

//定义方式1:
//绝对值函数,一旦执行到return就表示函数结束,返回结果
//如果没有执行return,函数执行完也会返回结果,结果是undefined
function aaa(x) {
    if(x>=0){
        return x;
    }else{
        return -x;
    }
}
/定义方式2:(与上一种等效)
/*
* function(x) {...}是一个匿名函数,但是可以把结果赋值给abs,通过abs就可以调用函数
* */
var abs= function(x) {
    if(x>=0){
        return x;
    }else{
        return -x;
    }
}
/**
 * 参数问题:js可以传任意个参数,也可不传递参数
 * 参数进来是否存在  假设不存在参数,如何规避(手动抛出异常)
 * 
 运算数为数字 typeof(x) = "number"
 字符串 typeof(x) = "string"
 布尔值 typeof(x) = "boolean"
 对象,数组和null typeof(x) = "object"
 函数 typeof(x) = "function"
 */
function abc(x) {
    if(typeof x!=='number'){
        throw 'Not a Number';
    }
    if(x>=0){
        return x;
    }else{
        return -x;
    }
}
/**
 * arguments是一个JS免费赠送的关键字,代表传递进来的参数,是一个数组
 * 问题:arguments包含所有的参数,有时想使用多余的参数来进行附加操作,需要排除已有的参数
 * 若传入多个参,这些参数就会被自动放入arguments数组中,可以直接从arguments中拿出来
 */
function bbb(x) {
    console.log("x->"+x);
    for(let i=0;i<arguments.length;i++){
        console.log(arguments[i]);
    }
    if(x>=0){
        return x;
    }else{
        return -x;
    }
}

2.8 可变长参数

以前的写法:

//以前的写法,使用arguments来判断aaa()里到底输入了多少个值,因为js是一款极其不严谨的语言,就算你传入一
//百个值都不会报错。所以可以使用arguments来执行传入多参的方法
function aaa(a,b) {
    console.log("a=>"+a);
    console.log("b=>"+b);
    if(arguments.length>2){
        for(let i=2;i<arguments.length;i++){
            console.log(arguments[i]);
        }
    }
}

由于ES6引入的新特性,可以直接写可变长参数:

//现在
function bbb(a,b,...rest) {//rest只能写在最后面,必须用...标识
    console.log("a=>"+a);
    console.log("b=>"+b);
    console.log(rest);
}

2.9 变量的作用域

  1. 全局作用域:所有地方都可以访问
  2. 函数作用域:只能在函数内部访问

变量的声明:显示声明(var i=1;)和隐式声明(i=1;)

  • 在函数体中声明的变量,在函数体外不能使用,要用得使用闭包

  • 如果两个函数用了同一个变量名,只要在函数内部声明就不冲突

  • 内部函数成员可以访问外部函数,外部不能访问内部

  • 内部函数变量和外部函数变量重名的情况下,内部与外部重名的部分用内部的变量。。。。由内向外查找

  • 假设外部存在这个同名的函数变量,则内部函数会屏蔽外部函数的变量

2.10 作用域的提升

下面的定义的变量上面可以调用(作用域提升),但是仅仅只是提升作用域,它的赋值并不会被提升上去。

var x='x'+y;
console.log(x);
var y='y';//结果:xundefined,js的执行引擎,自动提升了y的声明但是不会提升变量y的赋值,在js建立之初就存在的

//养成规范:所有的变量定义都放在函数的头部,不要乱放,便于代码维护

2.11 alert的一些方法

alert(a);
alert(window.a);//默认所有全局变量,都会自动绑定在Window对象上
window.alert(a);//alert()这个函数本身也是Window变量
//把alert方法赋予别的变量,原来的alert失效
var old_alert=window.alert; //把alert方法赋给一个变量,这个变量就有了alert的功能
old_alert('haishi');

//重写alert方法
window.alert=function () {
};

//恢复
window.alert=old_alert;

JS实际上只有一个全局作用域,任何变量(函数也可视为变量),假设没有在函数作用范围内找到,就会向外查找,

如果在全局作用域都没有找到,报错ReferenceError

2.12 自定义唯一全局变量

由于我们所有的全局变量都会绑定到我们的window上,如果不同的js文件使用了相同的全局变量,就会造成冲突。解决办法:自定义唯一全局变量,把自己的代码全部放入自己定义的唯一空间名字中,降低全局命名冲突的问题

//唯一全局变量
var XiaoSi={};

//定义全局变量或方法
XiaoSi.name='xiaosi';
XiaoSi.add=function(a,b){
	return a + b ;
}

全局作用域冲突使用自定义全局变量来解决,而局部作用域冲突问题则使用let来解决。

2.13 常量

在ES6之前,定义常量:只有用全部大写字母命名的变量就是常量;建议不要修改这样的值,但实际上是可以随意修改的。ES6我们可以const来实现真正的常量(类似java的final)

const PI='3.14'; //只读变量
console.log(PI);
PI='3.1415';//报错Uncaught TypeError: invalid assignment to const 'PI'

2.14方法

方法就是把函数放在对象里面,对象只有两个东西:属性和方法

var xiaosi={
    name:'小厮',
    birth:1998,
    //方法
    age:function () {
        //今年-出生的年份
        var now=new Date().getFullYear();
        return now-this.birth;
    }
}

也可以在对象中引入外面的函数。

function getAge() {
    var now=new Date().getFullYear();
    return now-this.birth;
}
var xiaosi={
    name:'小厮',
    birth:1998,
    //引入外部函数的方法
    age:getAge
}

3、扩展

3.1 typeof

console.log(typeof 123); //查看后面的东西是什么类型的(这里是number)

3.2 Date

var now=new Date();
now.getFullYear();//年
now.getMonth();//月 0_11代表月
now.getDate();//日
now.getDay();//星期几
now.getHours();//时
now.getMinutes();//分
now.getSeconds();//秒

now.getTime(); //时间戳  全世界统一  1970 1.1 0:00:00 毫秒数

console.log(new Date(1578106175991));//把时间戳转换为时间
/**
 * 转换
 */
now=new Date(1578106175991);
console.log(now.toLocaleString());//调用一个方法,而不是属性
//now.toGMTString()格林威治标准时间

3.3 Json

/**
 * JSON一种轻量级的数据交换格式
 * 具有层次结构
 *
 * 在JS中一切都是对象、任何js支持的类型都可以用JSON来表示
 * 对象{}
 * 数组[]
 * 键值对key:value
 */
//对象转化为json字符串
var JSONUser=JSON.stringify(user);

//json字符串转化为对象,参数为JSON字符串
var obj=JSON.parse('{"name":"xiaosi","age":3,"sex":"男"}');

3.4 js的面对对象编程

/**
 * 类:模板
 * 对象:具体的实例
 *
 * 但在JS中,需要换一下思路:
 * 原型:
 */
var user={
    name:'xiaosi',
    age:3,
    run:function () {
        console.log(this.name+" run...");
    }
};

var Bird={
    fly:function () {
        console.log(this.name+" fly...");
    }
};

var xiaoming={
    name:'xiaoming'  //无法直接调用run方法,会报错
};

/*
* 原型对象(实际上是继承)
* */
xiaoming.__proto__=user;//小明的原型是user,这是旧的方法,可以随意更换
xiaoming.run();
xiaoming.__proto__=Bird;
xiaoming.fly();

3.5 class的继承

在ES6之前无class关键字,所以要使用prototype往前面的函数添加新方法

prototype 属性使您有能力向对象添加属性和方法。

 function  Student(name) {
     this.name=name;
 }
 //给student新增一个方法,要么改它的方法,要不如下获得它的原型增加...ES6之前的原生方法,不用记
 Student.prototype.hello=function () {
     alert('hello')
 }
//ES6之后
//定义一个学生的类
class Student{
    constructor/*构造器关键字*/(name) {
        this.name=name;
    }

    hello(){
        alert('hello');
    }
}
var xiaoming=new Student('xiaoming');
xiaoming.hello();
console.log(xiaoming.name);

/**
 * 继承
 */

class XiaoStudent extends Student{
    constructor(name,grade) {
        super(name);
        this.grade=grade;
    }

    myGrade(){
        alert('我是一个小学生');
    }
}

var xiaohong=new XiaoStudent('xiaohong');
xiaohong.myGrade();
console.log(xiaohong);

3.6 原型与原型链

原型

在JavaScript中,每当定义一个函数数据类型(普通函数、类)时候,都会天生自带一个prototype属性,这个属性指向函数的原型对象,并且这个属性是一个对象数据类型的值。

让我们用一张图表示构造函数和实例原型之间的关系:

3174701-2dd95188a8f6b19e

原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象,我们可以将对象中共有的内容,统一设置到原型对象中。

原型链

  • 1.__proto__constructor

每一个对象数据类型(普通的对象、实例、prototype…)也天生自带一个属性__proto__,属性值是当前实例所属类的原型(prototype)。原型对象中有一个属性constructor, 它指向函数对象。

    function Person() {}
    var person = new Person()
    console.log(person.__proto__ === Person.prototype)//true
    console.log(Person.prototype.constructor===Person)//true
    //顺便学习一个ES5的方法,可以获得对象的原型
    console.log(Object.getPrototypeOf(person) === Person.prototype) // true

3174701-9a3de0b501161c07

image

  • 2.何为原型链

在JavaScript中万物都是对象,对象和对象之间也有关系,并不是孤立存在的。对象之间的继承关系,在JavaScript中是通过prototype对象指向父类对象,直到指向Object对象为止,这样就形成了一个原型指向的链条,专业术语称之为原型链

举例说明:person → Person → Object ,普通人继承人类,人类继承对象类

当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象中寻找,如果找到则直接使用。如果没有则去原型的原型中寻找,直到找到Object对象的原型,Object对象的原型没有原型,如果在Object原型中依然没有找到,则返回undefined。

我们可以使用对象的hasOwnProperty()来检查对象自身中是否含有该属性;使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true

    function Person() {}
    Person.prototype.a = 123;
    Person.prototype.sayHello = function () {
      alert("hello");
    };
    var person = new Person()
    console.log(person.a)//123
    console.log(person.hasOwnProperty('a'));//false
    console.log('a'in person)//true

person实例中没有a这个属性,从 person 对象中找不到 a 属性就会从 person 的原型也就是 person.__proto__ ,也就是 Person.prototype中查找,很幸运地得到a的值为123。那假如 person.__proto__中也没有该属性,又该如何查找?

当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层Object为止。Object是JS中所有对象数据类型的基类(最顶层的类)在Object.prototype上没有__proto__这个属性。

console.log(Object.prototype.__proto__ === null) // true

3174701-18a76d28c0a9ea1b

4、BOM和DOM

DOM是一套操作HTML标签的API(接口/方法/属性)
BOM是一套操作浏览器的API(接口/方法/属性)

4.1 操作BOM对象

4.1.1 基本

BOM:浏览器对象模型
JS诞生就是为了能够让他在浏览器中运行

  • 浏览器内核:
    IE 6-11
    Chrome
    Safari
    FireFox(Linux默认)

  • 三方:
    QQ,360

  • window:
    window代表浏览器窗口

window.innerHeight;
window.innerWidth;
window.outerHeight;
window.outerWidth;//浏览器的内宽高和外宽高,调整浏览器会改变
  • Navigator封装了浏览器的信息:

    navigator.appName
    “Netscape”
    navigator.appVersion
    “5.0 (Windows)”
    navigator.userAgent
    “Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0”
    navigator.platform
    “Win32”

大多数时候不会使用navigator对象,因为会被人为修改
不建议使用这些属性来判断和编写代码(例如if(navigator.appName=‘xxx’)之类的)

window.navigator;
  • screen屏幕
screen.width;
screen.height;//像素
  • location
/**
 * location(重要)
 * 代表当前页面的URL信息
 * host: "localhost:63342"  主机
 * href: "http://localhost:63342/JavaScript/lesson04/1.%E6%93%8D%E4%BD…87%8D%E7%82%B9%EF%BC%89.html?_ijt=onret8mf0ch9jg9gjfsdsv9vjv"  当前指向网页
 * protocol: "http:"  协议
 * reload: reload()  重新加载网页
 */
console.log(location);

//设置新的地址,直接转到assign指向的网站
location.assign('https://www.baidu.com');
4.1.2 document
/**
 *document代表当前页面, HTMl DOM树
 */
var dl=document.getElementById('app');//获取具体的文档树节点

/**
 * 获取cookie
 * 劫持cookie原理
 * 恶意人员:获取你的cookie上传到他的服务器
 *
 * 服务器端可以设置cookie:httpOnly(只读)
 */
console.log(document.cookie);
4.1.3 history

history代表浏览器的历史记录,不建议使用
history.back() //后退
history.forward() //前进

4.2 操作DOM对象

4.2.1 基本

DOM:文档对象模型

核心:
浏览器网页就是一个DOM树形结构
1.更新:更新DOM节点
2.遍历dom节点:得到DOM节点
3.删除:删除一个DOM节点
4.添加:添加一个新的节点
要操一个dom节点就必须获得这个dom节点

4.2.2 获得DOM节点

document

<body>
<div id="father">
<h1>标题一</h1>
<p id="p1">p1</p>
<p class="p2">p2</p>
</div>
<script>
    //对应CSS选择器,获得dom节点
    var h1=document.getElementsByTagName('h1');
    var p1=document.getElementById('p1');
    var p2=document.getElementsByClassName('p2');
    var father=document.getElementById('father');

    var childrens=father.children; //获取父节点下的所有子节点
    //father.firstChild第一个节点
    //father.lastChild最后一个节点
    //这是原生代码,之后尽量使用jQuery();

</script>
</body>
4.2.3 更新节点
var id1=document.getElementById('id1');
id1.innerText='456';//修改文本的值
id1.innerHTML='<strong>456</strong>';//可以解析HTML文本标签

//可以进行CSS操作,在网页上可以直接用JS进行修改界面
id1.style.color='yellow';
id1.style.fontSize='200px';//不支持-,用驼峰命名
4.2.4 删除节点
/**
 * 删除节点的步骤:先获取父节点,再通过父节点删除自己
 * 第一种标准流程
 */
var self=document.getElementById('p1');
var father=self.parentElement;
//father.removeChild(self);

/**
 * 方法2:通过下标移除,要注意删除多个节点的时候children是在时刻变化的
 */
//father.removeChild(father.children[1]);//你删除完一后原来的2就变成一
4.2.5 插入节点

我们获得了某个Dom节点,假设这个Dom节点是空的,我们通过innerHTML就可以增加一个元素了,但是这个Dom节点已经存在元素了,我们就不能这么干,会覆盖,可以使用追加:append

var
    js=document.getElementById('js'),//已存在的节点
    list=document.getElementById('list');
//list.appendChild(js);//控制台输入,id为js的标签会变为div的子标签
/**
 * 通过JS创建一个新的节点,实现插入
 */
var newP=document.createElement('p');//创建一个新标签
newP.id='newP';//标签id设为newP
/*newP.id='newP';等价于newP.setAttribute('id','newP');*/
newP.innerText='xiaosi';
list.appendChild(newP);
/**
 * 创建一个标签节点
 * <script type="text/javascript" src=""></ script>
 */
var myScript=document.createElement('script');
myScript.setAttribute('type','text/javascript');
//list.appendChild(myScript);
/**
 * 插入CSS
 */
var myStyle=document.createElement('style');//创建一个空style标签
myStyle.setAttribute('type','text/css');
myStyle.innerText='body{background-color:pink;}';//设置标签内容
document.getElementsByTagName('head')[0].appendChild(myStyle);//不知道head标签下标的话可以先打印看一下
4.2.6 前插
<body>
<p id="js">JavaScript</p>
<div id="list">
    <p id="se">JavaSE</p>
    <p id="ee">JavaEE</p>
    <p id="me">JavaME</p>
</div>

<script>
    var ee=document.getElementById('ee');
    var js=document.getElementById('js');
    var list=document.getElementById('list');

    //要包含的节点.insertBefore(newNode,targetNode),新节点插入目标节点前面,他们都包含在list里面
    list.insertBefore(js,ee);
</script>
</body>
4.2.7 操作表单
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="#">
    <p>
        <span>用户名:</span> <input type="text" id="username">
    </p>

    <!--多选框的值,就是定义好的value-->
    <p>
        <span>性别:</span>
        <input type="radio" name="sex" value="man" id="boy"><input type="radio" name="sex" value="woman" id="girl"></p>
</form>

<script>
    /**
     * 获得提交的信息
     *
     * */
    var
        input_text=document.getElementById('username'),
        boy_value=document.getElementById('boy'),
        girl_value=document.getElementById('girl');

   /* //得到输入框的值
    input_text.value;
    //修改输入框的值
    input_text.value = '123';
    */

  /* //对于单选框,多选框等固定的值,boy_radio.value只能取到当前的值
    boy_value.checked;//查看返回的结果,如果为true,被选中
    girl_value.checked=true;//赋值
   */
</script>
</body>
</html>
4.2.8 提交表单
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--MD5工具类-->
    <script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script>
</head>
<body>
<form action="#" method="post">
    <p>
        <span>用户名:</span> <input type="text" id="username" name="username">
    </p>
    <p>
        <span>密码:</span> <input type="password" id="password" name="password">
    </p>
    <!--绑定事件 onclick 被点击-->
    <button type="submit" onclick="aaa()">提交</button>

</form>

<script>
    function aaa() {
        var uname=document.getElementById('username'),
            pwd=document.getElementById('password');
        console.log(uname.value);
        console.log(pwd.value);
        //MD5算法
        pwd.value=md5(pwd.value);
        console.log(pwd.value);
    }
</script>
</body>
</html>
4.2.9 表单绑定提交
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--MD5工具类-->
    <script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script>
</head>
<body>
<!--
表单绑定提交事件
οnsubmit=绑定一个提交检测的函数,true false
将这个结果返回给表单,使用onsubmit接受
-->
<form action="https://www.baidu.com/" method="post" onsubmit="return aaa()">
    <p>
        <span>用户名:</span> <input type="text" id="username" name="username">
    </p>
    <p>
        <span>密码:</span> <input type="password" id="input-password">
    </p>
    <input type="hidden" id="md5-password" name="password">//用隐藏的方法你提交的一瞬间密码不会变长

    <button type="submit">提交</button>

</form>

<script>
    function aaa() {
        var uname=document.getElementById('username'),
            pwd=document.getElementById('password'),
            md5pwd=document.getElementById('md5-password');
        console.log(uname.value);
        console.log(pwd.value);
        //MD5算法
        md5pwd.value=md5(pwd.value);

        //可以校验判断表单内容,true是通过,false是阻止
        return true;
    }
</script>
</body>
</html>

5、JQuery简解

5.1 初识JQuery

导入:CDN或者下载到本地,script标签不能自闭和

<!--CDN jQuery 直接从网上粘下来,不需要下载-->
<!--    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/core.js"></script>   -->

<!--  下载到本地直接导入  -->
<script src="lib/jquery-3.5.1.js"></script>

公式:$(selector).action(),例:

//选择器就是css的选择器
$('#test-jquery').click(function () {
    alert('hello jQuery');
});

5.2 选择器

//原生JS,选择器少,麻烦不好记
//标签
document.getElementsByTagName()
//id
document.getElementById()
//类
document.getElementsByClassName()

//Jquery选择器  css中的选择器它都能用,不会的查网站
$('p').click()//标签选择器
$('#id1').click() // id选择器
$('.class1').click() // class选择器

5.3 事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="lib/jquery-3.5.1.js"></script>
    <style>
        #divMove{
            width: 500px;
            height: 500px;
            border: 1px solid pink;
        }
    </style>
</head>
<body>
<!--要求:获取鼠标当前的一个坐标-->
mouse:<span id="mouseMove"></span>
<div id="divMove">
    在这里移动鼠标试一下
</div>

<script>
    //当前网页元素加载完毕之后响应事件,相当于公式的简化
    $(function () {
        $('#divMove').mousemove(function (e) {
            $('#mouseMove').text('x:'+e.pageX+'y:'+e.pageY);
        })
    });
</script>
<div>

</div>

</body>
</html>

5.4 操作dom元素

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="lib/jquery-3.5.1.js"></script>
</head>
<body>
<ul id="test-ul">
    <li class="js">JavaScript</li>
    <li name="python">Python</li>
</ul>

<script>

    $('#test-ul li[name=python]').text();//获得ul下面name=python的值
    //$('#test-ul li[name=python]').text('aaa');//修改ul下面name=python的值
    $('#test-ul').html();//获得ul的html
    //$('#test-ul').html('<strong>123</strong>');//修改ul的html

    /**
     * css的操作
     */
    $('#test-ul li[name=python]').css("color","pink");//要设置多个属性可以用键值对$('#test-ul li[name=python]').css({"color","pink"},{})

    /**
     * 元素的显示和隐藏:本质display:none
     */
    $('#test-ul li[name=python]').show();
    $('#test-ul li[name=python]').hide();

    /**
     * 别的用法:可以通过查文档来了解
     */
    $(window).width();//只要满足公式,这里是浏览器窗口的宽


</script>
</body>
</html>

6、闭包

概念:一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。

6.1 一个简单的闭包

function A(){
  function B(){
    console.log(``'Hello Closure!'``);
  }
  return B;
}
var C = A();
C();// Hello Closure!

函数A的内部函数B被函数A外的一个变量 c 引用。

也就是:

当一个内部函数被其外部函数之外的变量引用时,就形成了一个闭包。

6.2 用途

在 Javascript 中,如果一个对象不再被引用,那么这个对象就会被 GC 回收,否则这个对象一直会保存在内存中

也就是说,A 不会被 GC 回收,会一直保存在内存中。

function A() {
  var count = 0;
  function B() {
    count ++;
    console.log(count);
  }
  return B;
}
var C = A();
C();// 1
C();// 2
C();// 3

count 是函数A 中的一个变量,它的值在函数B 中被改变,函数 B 每执行一次,count 的值就在原来的基础上累加 1 。因此,函数A中的 count 变量会一直保存在内存中。

当我们需要在模块中定义一些变量,并希望这些变量一直保存在内存中但又不会 “污染” 全局的变量时,就可以用闭包来定义这个模块。

6.3 闭包的高级写法

(function (document) {
  var viewport;
  var obj = {
    init: function(id) {
      viewport = document.querySelector('#' + id);
    },
    addChild: function(child) {
      viewport.appendChild(child);
    },
    removeChild: function(child) {
      viewport.removeChild(child);
    }
  }
  window.jView = obj;
})(document);

这个组件的作用是:初始化一个容器,然后可以给这个容器添加子容器,也可以移除一个容器。

功能很简单,但这里涉及到了另外一个概念:立即执行函数。 简单了解一下就行,需要重点理解的是这种写法是如何实现闭包功能的。

可以将上面的代码拆分成两部分:(function(){})()

第1个**()** 是一个表达式,而这个表达式本身是一个匿名函数,所以在这个表达式后面加 () 就表示执行这个匿名函数。

因此这段代码执行执行过程可以分解如下:

var f = function(document) {
  var viewport;
  var obj = {
    init: function(id) {
      viewport = document.querySelector('#' + id);
    },
    addChild: function(child) {
      viewport.appendChild(child);
    },
    removeChild: function(child) {
      viewport.removeChild(child);
    }
  }
  window.jView = obj;
};
f(document);

在这段代码中似乎看到了闭包的影子,但 f 中没有任何返回值,似乎不具备闭包的条件,注意这句代码:

window.jView = obj;

nction B() {
count ++;
console.log(count);
}
return B;
}
var C = A();
C();// 1
C();// 2
C();// 3


count 是函数A 中的一个变量,它的值在函数B 中被改变,函数 B 每执行一次,count 的值就在原来的基础上累加 1 。因此,函数A中的 count 变量会一直保存在内存中。

当我们需要在模块中定义一些变量,并希望这些变量一直保存在内存中但又不会 “污染” 全局的变量时,就可以用闭包来定义这个模块。

### 6.3 闭包的高级写法

```javascript
(function (document) {
  var viewport;
  var obj = {
    init: function(id) {
      viewport = document.querySelector('#' + id);
    },
    addChild: function(child) {
      viewport.appendChild(child);
    },
    removeChild: function(child) {
      viewport.removeChild(child);
    }
  }
  window.jView = obj;
})(document);

这个组件的作用是:初始化一个容器,然后可以给这个容器添加子容器,也可以移除一个容器。

功能很简单,但这里涉及到了另外一个概念:立即执行函数。 简单了解一下就行,需要重点理解的是这种写法是如何实现闭包功能的。

可以将上面的代码拆分成两部分:(function(){})()

第1个**()** 是一个表达式,而这个表达式本身是一个匿名函数,所以在这个表达式后面加 () 就表示执行这个匿名函数。

因此这段代码执行执行过程可以分解如下:

var f = function(document) {
  var viewport;
  var obj = {
    init: function(id) {
      viewport = document.querySelector('#' + id);
    },
    addChild: function(child) {
      viewport.appendChild(child);
    },
    removeChild: function(child) {
      viewport.removeChild(child);
    }
  }
  window.jView = obj;
};
f(document);

在这段代码中似乎看到了闭包的影子,但 f 中没有任何返回值,似乎不具备闭包的条件,注意这句代码:

window.jView = obj;

obj 是在函数 f 中定义的一个对象,这个对象中定义了一系列方法, 执行window.jView = obj 就是在 window 全局对象定义了一个变量 jView,并将这个变量指向 obj 对象,即全局变量 jView 引用了 obj . 而 obj 对象中的函数又引用了函数 f 中的变量 viewport ,因此函数 f 中的 viewport 不会被 GC 回收,viewport 会一直保存到内存中,所以这种写法满足了闭包的条件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值