5. JavaScript

1. JS概述

1.1 简介

JavaScript 是脚本语言,是一种解释性脚本语言(代码不进行预编译)

JavaScript 是一种轻量级的编程语言。

JavaScript 是可插入 HTML 页面的编程代码。

JavaScript 插入 HTML 页面后,可由所有的现代浏览器执行。

1.2 作用

  • 为网页添加各式各样的动态功能,

  • 为用户提供更流畅美观的浏览效果

1.3 用法

  • JavaScript通常简称为js脚本,必须位于script围堵标签之间,位置可以为
  1. 在页面中
  2. 外部引用JS文件
  3. 标签属性中
//1.页面中script标签可以放在 head 或 body中,对位置要求不严格
//2.现在 外部引用文件可以不写 type="text/javascript";因为JS已经是HTML5中默认的标本语言
// 外部文件导入方式 <script src="MyJs.js"></script> 注意:MyJs.js文件中不能有script,直接写JS代码即可
//3. 直接在HTML标签的一些属性中,一般JS语言较简单的可以,用的偏少。
//如:<a href="javascript:alert('在标签中使用JS语言')">提示</a>

案例展示:
<head>
    <meta charset="utf-8"/>
    <title>JavaScript的用法</title>
    <script>
      alert("hello JavaScript1-1");
    </script>
    <script src="MyJs.js"></script>
</head>
<body>
   <a href="javascript:alert('在标签中使用JS语言')">提示</a>
	<script>
  		alert("body中的Js脚本");
	</script>
</body>

1.4 显示数据

1. alert("显示数据");
2. document.write("<p>Hello, world!</p>");// 内容可以是纯文本、HTML或JavaScript代码;用的较少,
3. document.getElementById("id1").innerHTML = "hello world";
4. console.log(content) //写入到控制台 按F12可以查看

1.5 注释

单行注释以 // 开头。

多行注释以 /* 开始,以 */ 结尾。

2. 基本语法

JavaScript是弱语言类型,即有些时候有些错误不影响运行,但是依然推荐大家按照规范去编写代码,语言弱,程序员不能弱。

2.1 变量

//1. 声明变量的关键字:var
//2, 语法:var 变量名称
案例展示:
var myCompany;     //声明变量
myCompany='开课吧';  //赋值
var x=5;          //声明的同时赋值

//3,命名规约
必须以字母开头
能以 $ 和 _ 符号开头
对大小写敏感
不能使用关键字和保留字
//4.规范
见名知意, userService;避免使用a,b,c;
驼峰法命名 lastName

2.2 语句

  1. JavaScript 语句向浏览器发出的命令。语句的作用是告诉浏览器该做什么。

  2. 浏览器会在读取代码时,逐行地执行脚本代码。而对于传统编程来说,会在执行前对所有代码进行编译。

  3. JavaScript中也有分支结构和循环结构,语法与java类似,

  4. 一般一行只写一条语句,每句结尾编写分号结束。

2.3 数据类型

基本类型

1. 字符串String  --> 可以是单引号或双引号
2. 数字 number   --> 可以带小数点,也可以不带
3. 布尔值   --> true or false
4. null    --> 空值

案例说明:
var gameName = "英雄联盟";
var hairstylist = "tony";
var message1 = "我的发型师是‘ton'y’老师"  //注意引号类型

var breadprice = 16.7;
var gameLevel = 66;
var myMoney2= -666e-5;  //-0.00666

var isUnderstand=true;
var isSingle=false;

var email = null;

未定义Undefined

  • 表示变量不含有值。可通过将变量的值设置为 null 来清空变量。

  • 共有4中情况会出现undefined

1.变量声明且没有赋值
  var obj; //obj值为undefined
2.获取对象中不存在的属性
	var obj; console.log(obj.name);  //报错信息:"Uncaught TypeError: Cannot read property 'name'of undefined"
3.函数需要实参,但是没有传值时的形参
4.函数调用没有返回值或者return后没有数据,接受函数返回值的变量是undefined
	function printNum(num){
		alert(num);//函数未得到参数,此时num的值是undefined
	}
	var result=printNum();
	alert(result);//result的值也是undefined,因为printNum()没有返回值

引用数据类型:

对象(Object)、数组(Array)、函数(Function)。

动态类型

JavaScript 拥有动态类型。这意味着相同的变量可用作不同的类型

var param;    // param类型为 undefined
param = 5;    // 现在 param 为number
param = "John";  // 现在 param 为String
     //不建议使用

2.4 运算符

  1. 算数运算符:+ - * / % 、 ++ 、 –

  2. 赋值运算符:= 、 +=、 -= 、*= 、 /= 、 %=

  3. 字符串的连接符:+

  4. 逻辑运算符: && || !

  5. 条件运算符:?:

  6. 比较运算符: == 、!= 、 > 、<、 >= 、 <=

7. 新的运算符
=== 进行严格相等比较,要求值和类型都相等。
==  进行相等比较,会进行类型转换,可能导致意外结果。

案例说明:
var x = 5;
var res = (x === 5); // true
res = (x === '5');// false
res = (x !== 5); // false
res = (x !== '5');// true	

8. 关于 == 类型转换
	- undefined
   - null
   - 0
   - ' ' 空字符串
   - false
以上值的判断结果是false
9. == 运算符的应用场景
	var o;
if (o === undefined || o === '' || o === null) {
    console.log('o 对象不存在');
}
if (!o) {
    console.log('o 对象为空')  //两个if语句作用相等
}

3. JS对象

3.1 String对象

直接上案例
<!--string的常用方法-->
    var s = "hello world";
    console.log(s.trim().length);
    console.log('length=' + s.length);

    console.log("charAT(4)=" + s.charAt(4));
    console.log("charcodeAT(0)=" + s.charCodeAt(0));
    //     返回在指定的位置的字符的 Unicode 编码。

    console.log(s.substring(3));//从下标为3开始提取到结尾
    console.log(s.substring(3, 5));

    console.log(s.toUpperCase());//转为大写
    console.log("------------")
    var s2 = "abc,123,456,789";
    var strings = s2.split(",");
    for (var s1 of strings) {
        console.log(s1);
    }

注意: for...of 循环数组,不需要下标  //推荐使用
	for...in 根据下标循环数组

3.2 Array对象

1. 声明数组的三种方式
 var names = new Array();  //方式1
 names[0] = "暴雨1";
 names[1] = "暴雨2";
 names[2] = "暴雨3";
 var cars = ["大众", "保时捷", "法拉利"];  //方式2 推荐
 var classes = new Array("1班", "2班", "3班");//方式3 

2. 循环遍历数组
 for (var name of names) {
     console.log(name);
 }
3. 获取数组的长度
names.length

4. 案例和方法
var arr = ["赵云", "张飞", "刘备", "诸葛亮", "张辽", "马超", "黄忠"];
var arr2 = new Array();
arr2.push("曹操");//向数组中放入元素
arr2.push("曹丕");
arr2.push("周瑜");
arr2.push("孙权");

console.log(arr.concat(arr2)); //追加数组,生成新的数组,原数组没有改变
console.log(arr.join("-"));    // 把数组的所有元素放入一个字符串。元素通过 ‘-’ 进行分隔。
console.log(arr.pop());     //移除数组的最后一个元素
console.log(arr.reverse()); //数组反转
console.log(arr.shift());   //删除并返回数组的第一个元素
arr.slice(0, 3)             //从某个已有的数组返回选定的元素,子数组
console.log("原数组=" + arr)
console.log(arr.splice(2, 2, 3, '马腾', '马岱'));//从下标2开始,删除个数为2,在该位置插入3,‘马腾’ '马岱'
console.log("目标数组=" + arr)
	运行结果:
   原数组=张辽,诸葛亮,刘备,张飞,赵云
 	目标数组=张辽,诸葛亮,3,马腾,马岱,赵云

3.3 Date对象

	 var date2 = new Date(milliseconds);
	 var date3 = new Date(dateString);
	 var date4 = new Date(year, month, day, hours, minutes, seconds, milliseconds);

    var d = new Date();//返回当日的日期和时间

    console.log(d.toLocaleDateString());//根据本地时间格式,把 Date 对象转换为字符串。

    console.log("时间戳=" + d.getTime());//返回 1970 年 1 月 1 日至今的毫秒数

    console.log(d.getFullYear());//获取当前年份
    console.log(d.getMonth());    //月份从0开始
    console.log(d.getDay())      //从 Date 对象返回一周中的某一天 (0 ~ 6)

    console.log(d.getDate())// Date 对象返回一个月中的某一天 (1 ~ 31

    console.log(d.getHours())//小时
    console.log(d.getUTCHours())//根据世界时返回Date对象的小时 (0 ~ 23)
    console.log(d.getMinutes())//分钟

    console.log(d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate());
    //当前日期
  • 日期对象的常用方法
getSeconds()返回 Date 对象的秒数 (0 ~ 59)。
setDate()设置 Date 对象中月的某一天 (1 ~ 31)。
setFullYear()设置 Date 对象中的年份(四位数字)。
setHours()设置 Date 对象中的小时 (0 ~ 23)。
setMinutes()设置 Date 对象中的分钟 (0 ~ 59)。
setSeconds()设置 Date 对象中的秒钟 (0 ~ 59)。
setMonth()设置 Date 对象中月份 (0 ~ 11)。

3.4 Math对象

var pi=Math.PI;//返回圆周率
Math.ceil(12345.1)
Math.floor(12345.9)
Math.round(12345.7)
Math.random() * 100 + 1
var max=Math.max(12,34,-90,9);//返回 n个数值中的最大值。
var min=Math.min(12,34,-90,9);//返回 n个数值中的最小值。

3.5 正则表达式

1. <!--正则表达式其一 -->
function checkQQ() {
    var regex = /^[1-9]\d{5,11}$/;//检测qq号
    var v = document.getElementById("txt").value;
    console.log(regex.test(v));//包含返回true,不包含返回false
  }
2. <!--正则表达式其二 -->
    const regex = /(\w+)\s(\w+)/;
    const str = '@#$John Smith';
    const result = regex.exec(str);//包含则返回该值,不包含则返回null

    console.log(result); //返回一个数组,里面有三个组
    console.log(result[0]);//组一 John Smith
    console.log(result[1]);//组二 John
    console.log(result[2]);//组三 Smith
    console.log(result.index);// 3

3.  // 正则表达式的使用其三
    const regex = /a/g;
    const str = 'aabbccaaa';
    // 循环打印
    // var result = regex.exec(str)
    // console.log(result);
    // result = regex.exec(str)
    // console.log(result);
    while ((result = regex.exec(str)) !== null) {
        console.log("Found " + result[0] + " at index" + result.index);
       //打印方式也可以是如下:
        console.log(`Found ${result[0]} at index=${result.index}`)//``使用着重号,变量需要形式为:${变量名}
    }
元字符描述
\d查找数字。
\s查找空白字符。
\b匹配单词边界。
\uxxxx查找以十六进制数 xxxx 规定的 Unicode 字符。
\w字母、数字、下划线
\s匹配空白字符如:空格、tab键、回车符
//常用的验证方式

<script>
	/*检查输入的身份证号是否正确*/
	function checkCard(str) {
		/*15位数身份证正则表达式:
		 * 编码规则顺序从左至右依次为6位数字地址码,6位数字出生年份后两位及日期,3位数字顺序码。
			[1-9]\d{5}                  前六位地区,非0打头    
			\d{2}                       出生年份后两位00-99
			((0[1-9])|(10|11|12))       月份,01-12月
			(([0-2][1-9])|10|20|30|31)  日期,01-31天
			\d{3}                       顺序码三位,没有校验码
		*/
		var arg1 = /^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}$/;
		if (arg1.length == 15 && !arg1.test(arg1)) {
             return false;
         }				
		/*
		 * 18位数身份证正则表达式:
		 * 编码规则顺序从左至右依次为6位数字地址码,8位数字出生年份日期码,3位数字顺序码,1位数字校验码(可为x)。
			[1-9]\d{5}                 前六位地区,非0打头
			(18|19|([23]\d))\d{2}      出身年份,覆盖范围为 1800-3999 年
			((0[1-9])|(10|11|12))      月份,01-12月
			(([0-2][1-9])|10|20|30|31) 日期,01-31天
			\d{3}[0-9Xx]:              顺序码三位 + 一位校验码
		 */
var arg2 = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
		if (arg2.length == 18 && !arg2.test(sfzhmcode)){
             return false;
         }
		return true;
	}
	/*是否是小数*/
	function isDecimal(strValue) {
		var objRegExp = /^\d+\.\d+$/;
		return objRegExp.test(strValue);
	}
	/*校验是否中文名称组成 */
	function ischina(str) {    
		var reg = /^[\u4E00-\u9FA5]{2,4}$/; 
		return reg.test(str); 
	}
	/*校验是否全由8位数字组成 */
	function isNum(str) {    
		var reg = /^[0-9]{8}$/; 
		return reg.test(str); 
	}
	/*校验电话码格式 :座机和手机*/
	function isTelCode(str) {    
		var reg = /^((0\d{2,3}-\d{7,8})|(1[345789]\d{9}))$/;
		return reg.test(str);
	}
	/*校验手机号*/
	function isPhoneNum(str) { 
		//如果你要精确验证手机号码,那个你可以使用第一个正则。这是根据电信,移动,联通目前发行的号码来的。验证比较精确。 
		var reg = /^1[3|4|5|7|8][0-9]{9}$/;
		// 如果因为现有的号码不能满足市场需求,电信服务商会增大号码范围。所以一般情况下我们只要验证手机号码为11位,且以1开头。 
		var reg = /^^1[0-9]{10}$$/;
		return reg.test(str);
	}
	/*校验邮件地址是否合法 */
	function IsEmail(str) {    
		var reg = /^\w+@[a-zA-Z0-9]{2,10}(?:\.[a-z]{2,4}){1,3}$/;
		return reg.test(str);
	}
	/*检查输入的URL地址是否正确	*/
	function checkURL(str) {
		if(str.match(/http(s)?:\/\/[\w.]+[\w\/]*[\w.]*\??[\w=&\+\%]*/i) == null) {
			return false;
		} else {
			return true;
		}
	}	
</script>

4. 函数

4.1 系统函数

1. isNaN(): 是数值返回false,不是返回true
	console.log(isNaN(666));//false
	console.log(isNaN(1+2));//false
	console.log(isNaN("hello"));//true
2. parseFloat(String)// 返回带小数的数字。
	console.log(parseFloat("66"));//66
	console.log(parseFloat("199.99"));//199.99
	console.log(parseFloat("1024 2048 4096"));//1024
	console.log(parseFloat(" 128 "));//128
	console.log(parseFloat("10年"));//10
	console.log(parseFloat("今天是8号"));//NaN
- 字符串中只返回第一个数字。
- 开头和结尾的空格是允许的。
- 如果字符串的第一个字符不能被转换为数字,那么 parseFloat() 会返回 NaN。

3. parseInt(string,radix)//将字符串转为数字。radix指字符串当前的进制
	console.log(parseInt("10",10));  //10
	console.log(parseInt("010"));    //10, 以“0”开头默认使用十进制
	console.log(parseInt("10",8));   //8   八进制
	console.log(parseInt("0x10"));   //16  16进制
	console.log(parseInt("10",16));  //16
- 只有字符串中的第一个数字会被返回。
- 开头和结尾的空格是允许的。
- 如果字符串的第一个字符不能被转换为数字,那么 parseInt() 会返回 NaN。
- 在字符串以"0"为开始时旧的浏览器默认使用八进制基数。ECMAScript 5,默认的是十进制的基数。

4.2 自定义函数

()函数创建的两种方式:
	1.function f1() {
        return 'f1';
    }console.log(f1());//调用函数f1()

	2. var f3 = function () {//匿名函数
        return 'helloworld f3'
    }; console.log(f3());

	3. (function () {//封闭函数:格式为 (function(){...})();
        var a = "a";
        var b = "b";
        function f1() {
            return 'f1执行'
        }console.log(a + " " + b + f1()); 
    })();   //调用这个函数并执行

()函数形参
var f4 = function (a, b) {
    console.log(a + ' ' + b);
    console.log("--------");
    for (var i = 0; i < arguments.length; i++) {
        console.log(arguments[i]);
    }
	};// f4();		f4('hello', 'world');		 f4('hello', 'world', 'javascript', 'ECMA', 'ES6')
	  //可以传入多个值,也可以不传值。函数中的a,b只能接收前两个值,arguments接受所有
()函数没有返回值,则调用的变量的值为undefined

4.3 变量作用域

var a = 100;  	//全局变量
function f5() {
    var b = 200;	//局部变量
    c = 300;	//全局变量,因为没有var修饰
    console.log(`${b}`)//输出b
    console.log("f1 a=" + a);
}
function f6() {
    console.log(c);
    console.log(a);
}
// console.log(b);//报错,b为局部变量
f5();
f6();

5. JavaScript类

  • 对象也是一个变量,但对象可以包含多个值(多个变量)

5.1 创建方式

1. 方式一: 不常用
    var flower = new Object();
    flower.name = "长春花";
    flower.genera = "夹竹桃科 长春花属";
    flower.area = "非洲、亚热带、热带以及中国大陆的华东、西南、中南等地";
    flower.uses = "观赏或用药等";
    flower.showName = function () {//方法
        console.log(this.name);}

    flower.showName()//调用方法
    console.log(flower.name);//调用属性

2. 方式二 JSON格式  {"属性名":值,“属性名":值}
    var flower1 = {
        "name": "长春花", "genera": "夹竹桃科 长春花属", "area": "非洲、亚热带、热带以及中国大陆的华东、西南、中南等地",
        "showName": function () {
            console.log(this.name)
        },
        "showArea": function () {
            console.log(this.area);
        }
    };flower1.uses = "观赏或用药等";
    
    flower1.showName();// 调用方法
    flower1.showArea();

3. 方式三 构造函数
    function Person(name, age) {
        this.name = name;//必须携带this,否则报错
        this.age = age;
        this.showName = function () {
            console.log(this.name);
        }
    }
    var zhangsan = new Person("张三", "18");
    console.log(zhangsan.name + zhangsan.age);
    zhangsan.showName();

5.2 原型链

上面代码方式三的问题:

  1. 每个对象都有一个方法,不符合标准规格。
  2. 无法继承父类的方法
  3. 利用率低,重复性低
<!--  对类中代码的优化:方法放在原型链中,以提高性能-->
    function Person(name, age) {
        this.name = name;
        this.age = age;
    }
    //优化后
    Person.prototype.showName = function () {//方法放在原型链中,
        console.log(this.name);
    };
    var a1 = new Person("张三", "18");
    console.log(a1.name + a1.age);
    a1.showName();//先去a1中找showName 没有就去Person中找,最后去Person.prototype
	//此时新的对象a2也能使用showName()方法

5.3 对象冒充

概述:对象冒充就是一种继承

function ClassParent(name) {//一个父类
    this.name = name;
    this.sayName = function () {
        console.log(this.name);
    };
}
function ClassChild(name, sex) {
    
    //将下面的代码换成 ClassParent(name) 会导致父类中的this= windows
    this.newMethod = ClassParent;//1. 函数指针指向ClassParent,此时父类的this = ClassChild
    this.newMethod(name);//2. 调用方法  父类的构造函数相当于给子类做
    delete this.newMethod;//3. 删除对ClassParent的引用
    this.sex = sex;
    this.saySex = function () {
        console.log(this.sex);
    };
}
var obj = new ClassChild("张三", "男");
console.log(obj.name + "|" + obj.sex);//此时子类拥有了父类的方法和属性
obj.sayName();
obj.saySex();

5.4 最终优化

	//父类
    function ClassParent1(name) {
        this.name = name;	//1.属性还要写
    }
    ClassParent1.prototype.sayName = function () { //2,方法放在原型链中
        console.log(this.name);
    };

    //子类
    function ClassChild1(name, sex) {
        ClassParent1.call(this,name)//3.此时ClasParent中的this=ClassChild 等价于对象冒充。
       	//3.5传this后,父类的this等于子类的this
         //4.完成父类的继承,带无法使用父类的方法
        this.sex = sex;
    }
    ClassChild1.prototype = new ClassParent1();
		//5.子类原型 = new 父类();子类找不到的方法去子类的原型去找,找不到就去父类原型找,从而形成链状结构
		//5.5 该方法必须放在原型的第一位
    ClassChild1.prototype.saySex = function () {//6.在上面的基础上追加方法saySex;
        console.log(this.sex);
    };
	//7.调用类中的方法和属性进行验证:
    var obj = new ClassChild1("李四", "女");
    console.log(obj.name + "|" + obj.sex);
    obj.saySex();
    obj.sayName();

5.5 案例说明

/*
生物是父类,动物继承生物,猴子继承动物
*/
    //生物
    function Creature(name) {
        this.name = name;
    }
    Creature.prototype.sayName = function () {
        console.log(this.name);
    };

    //动物,继承生物
    function Animal(name, sex) {
        Creature.call(this, name);//对象冒充 相当于java中的super()
        this.sex = sex;
    }
    Animal.prototype = new Creature();//放在原型的第一位
    Animal.prototype.saySex = function () {
        console.log(this.sex);
    };

    //猴子,继承生物
    function Monkey(name, sex, age) {
        Animal.call(this, name, sex);//对象冒充。获取父类的属性
        this.age = age;
    }
    Monkey.prototype = new Animal();
    Monkey.prototype.sayAge = function () {
        console.log(this.age);
    };//到此为止,子类猴子拥有了父类和超父类的属性和方法
    //测试代码
    var m1 = new Monkey("孙悟空", "公", 10000);
    console.log(`属性 name=${m1.name}, sex=${m1.sex}, age=${m1.age}`);
    m1.sayAge();
    m1.saySex();
    m1.sayName();

6. 浏览器对象模型

浏览器对象模型 (BOM) 使 JavaScript 有能力与浏览器"对话"。

BOM:Browser Object Model:浏览器对象模型。

虽然现在BOM尚无正式标准,但是由于现代浏览器已经(几乎)实现了 JavaScript 交互性方面的相同方法和属性,因此window常被认为是 BOM 的方法和属性。

6.1 window属性

所有浏览器都支持 window 对象。它表示浏览器窗口。( 没有应用于 window 对象的公开标准,不过所有浏览器都支持该对象)。

Window中的重要属性
    location	<!--window.location可以不写 window 这个前缀-->
        - href:获取当前页面的URL
        - reload(): 刷新
        - replace("URL"): 跳转,不产生历史
    history  <!--window.history 对象包含浏览器的历史,可不写 window 这个前缀。-->
        - forward():前进
        - back()  后退
        - go(+-1) : 进或退


<button οnclick="btnClk()">按钮</button>
<br>
<a href="javascript:alert(window.location.href)">获取当前页面的URL地址</a>
<a href="javascript:window.location.reload()">刷新</a>
<a href="javascript:window.location.replace('https://www.baidu.com')">跳转到百度不产生历史</a>

<a href="javascript:window.history.forward()">前进</a>
<a href="javascript:window.history.back()">后退</a>
<a href="javascript:window.history.go(1)">前进go</a>
<a href="javascript:window.history.go(-1)">后退go</a>

6.2 window方法

<!--Window对象方法 可以省略window
    - alert(); 弹框
    - confirm(); 验证窗口
    - prompt(); 输入
    - open(); 打开
    - close(); 关闭该标签
	 - setTimeout()  clearTimeout()   延迟执行
	 - setInterval()  clearInterval()  循环执行
-->
<script>
    function test2() {
        if (window.confirm('是否要删除数据')) {
            alert('成功删除数据');
        }
    }
    function test3(){
        var s = window.prompt('请输入要写的数字');
        document.write(s);//用的较少
    }
    function test4(){
        window.open("https://www.baidu.com");
    }
    function test5(){
    	window.close();
    }

    // 循环执行
    function start1(){
        alert('x');
        timeoutid = window.setTimeout(start1,2000);//两秒执行一次,方法本身只执行一个
    }
    function end1(){
        window.clearTimeout(timeoutid);//清除的timeout
    }
    function fn(){
        alert('x2');
    }
    function start2(){
        timeoutId = window.setInterval(fn, 2000);//自动循环执行
    }
    function end2(){
        window.clearInterval(timeoutId);
    }
</script>

6.3 定时执行案例

  • 方式1 -->setInterval
<body>
恭喜您注册成功,<span id="second" style="color: red;">10</span>秒后跳转到首页,如果不跳转请<a
        href="https://www.baidu.com">点击这里</a>
<script>
    var timer = 10;//超过10秒自动跳转
    var fn = function () {
        timer--;
        document.getElementById("second").innerText = timer;//获取并设置second的内容
        if (timer === 0) {
            window.clearInterval(tid)
            window.alert("即将跳转");//跳转代码
            return;
        }
    };
    if (timer >= 0) {
        var tid = window.setInterval(fn, 1000);
    }
</script>
</body>
  • 方式2 -->setTimeout
<body>
恭喜您注册成功,<span id="second" style="color: red;">10</span>秒后跳转到首页,如果不跳转请<a
        href="demo11.html">点击这里</a>
<script>
    var timer = 10;
    var fn = function () {
        timer--;
        document.getElementById("second").innerText = timer;
        if (timer === 0) {
            window.clearTimeout(tid)
            window.alert("即将跳转");
            return;
        }
        window.setTimeout(fn, 1000);
    };
    var tid = window.setTimeout(fn, 1000);
</script>
</body>

7. Event事件

7.1 简介

  • HTML 事件是发生在 HTML 元素上的事情。当在 HTML 页面中使用 JavaScript 时, JavaScript 可以触发这些事件。

  • 例如页面加载完成、你点击个按钮、文本框输入了文字等等,都是HTML事件的案例。

  • 例如点击完毕按钮之后希望跳转页面、文本框输入完毕之后验证有效性等,那么这些要做的事情我们就可以通过JavaScript实现。

事件描述
onchange元素发生改变时
onclick单击
ondblclick双击
oncontextmenu右击
onmouseover鼠标移动到元素上
onload浏览器已完成页面的加载
onblur元素失去焦点时触发

7.2 案例展示

<script>
function myload(){
    function fn1() {
        alert("单击事件后");
    }
    function fn2() {
        alert("双击事件生效")
    }
    function fn3(o) {
        alert(o.value);//onchange
    }
    function fn4(o) {
        o.style.border = "solid 2px red";
    }

    var a2 = document.getElementById("a2");
    a2.oncontextmenu = function () { //通过JS代码给元素添加属性
        alert("右击事件");
    };
    var btn3 = document.getElementById("btn3");
    btn3.onclick = function () {
        alert("通过在里面赋值");
    };
    btn3.onclick = function () {//两个相同的,后面的会覆盖前面的
        alert("通过在里面赋值2");
    };
}      
</script>
<body onload="myLoad()">
<button id="butn1" onclick="fn1()">btn1</button>
<button id="butn2" ondblclick="fn2()">btn2</button>
<input type="text" id="text1" onchange="fn3(this)">
<input type="text" id="text2" onmouseover="fn4(this)">
<a href="" id="a1" onclick="">btn3</a>
<a href="" id="a2" onclick="">btn4</a>
<button id="btn3">一个按钮</button>
</body>

7.3 默认事件

<body>
1. <!--阻止默认事件-->
  				 <!--一个元素右击弹窗,阻止默认右键菜单-->
   			 <!--这里fn1()传参event,函数对event修改 -->
<span style="background: red" οncοntextmenu="fn1(event);">123</span><br> 
   
<a href="https://www.baidu.com " οnclick="fn(event)">超链接1</a>  <!--阻止默认跳跃-->

	<!--去除跳跃的超链接方式
    	- ”#“
    	- ”javascript:void(0);“
    	- " "  
	以上方法都可以防止超链接跳跃
	-->
<a href="#" οnclick="alert('a');">超链接2</a>
<a href="javascript:void(0);" οnclick="alert('a');">超链接3</a>
<a href=" " οnclick="alert('a');">超链接4</a>

2.	<!--阻止事件传播:事件传播是指‘放生在包含关系中,当触发里面的元素时,外面元素的事件也会触发’-->
<div οnclick="fn3()" style="width:100px;height:100px;background-color: green;margin:0px;padding: 50px;">
    <div οnclick="fn4(event)" style="width:100px;height:100px;background-color:red;border:0px">内部元素</div>
</div>

3. <!--阻止的具体函数-->
   <script>
    function fn1(e) {
        e.preventDefault()//阻止默认事件
        alert("阻止成功");}
      
    function fn(e) {
        e.preventDefault();//也可以阻止链接跳跃
        alert("防越"); }
      
    function fn3() {
        alert("fn3"); }
      
    function fn4(e) {
        alert("fn4");
        //如果没有以下内容,将会发生-->弹出fn4 后又弹出fn3
		 e.stopPropagation()//阻止事件传递。}
</script>
</body>

8. DOM模型

DOM:Document Object Model:文档对象模型。

  • 通过 HTML DOM,可访问 JavaScript HTML 文档的所有元素。

  • JavaScript 有足够的能力来创建动态的 HTML

    • JavaScript 能够改变页面中的所有 HTML 元素

    • JavaScript 能够改变页面中的所有 HTML 属性

    • JavaScript 能够改变页面中的所有 CSS 样式

    • JavaScript 能够对页面中的所有事件做出反应

8.1 document对象

  1. 当浏览器载入 HTML 文档, 它就会成为 Document 对象

  2. Document 对象是 HTML 文档的根节点。

  3. Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问

**提示:**Document 对象是 Window 对象的一部分,可通过 window.document 属性对其进行访问。

8.2 dom常用方法

方法描述
document.getElementById()返回对拥有指定 id 的第一个对象的引用。
document.getElementsByClassName()返回文档中所有指定类名(class)的元素集合,作为 NodeList 对象。
document.getElementsByTagName()返回带有指定标签名的对象集合。
document.getElementsByName()返回带有指定名称(name)的对象集合。

8.3 获取HTML内容

<body>
<input type="text" id="txt1">
<a href="demo1.html" id="a1">超链接1</a>
<p class="demo"></p>
<div id="myDiv" class="demo">div</div>
<ul class="demo">
    <li class="a">111111</li>
    <li name="myLi">2222</li>
    <li class="a">3333</li>
    <li name="myLi">4444</li>
</ul>
<ol class="demo">
    <li class="b">aaaa</li>
    <li name="myLi">bbbb</li>
    <li class="a">cccc</li>
    <li name="myLi">dddd</li>
</ol>
</body>
<script>
console.log(document.getElementById("a1").innerHTML);//获取元素的内容
    var mylis = document.getElementsByName("myLi")//获取name = “myli"的元素,因为myli有很多所以返回一个数组
    for (var myli of mylis) {
        console.log(myli.innerHTML);
    }
    console.log("---------");
    lis = document.getElementsByTagName("li");//返回标签为li的元素
    for (var lii of lis) {
        console.log(lii.innerHTML);}
</script>

8.4 修改HTML内容

1. 修改元素的内容:
	方式1:document.getElementById('id').innerHTML=新的 HTML	//运行HTML代码
	方式2:document.getElementById('id').innerText=新的 HTML	//不运行HTML代码	

2. 修改元素的属性:
	方式1:document.getElementById('id').attribute=新属性值
	方式2:document.getElementById('id').setAttribute(属性名,属性值);
	
3.	修改元素的样式:document.getElementById("div1").style.样式属性=”值“
<div id="mydiv">div</div>
var mydiv=document.getElementById("mydiv");
mydiv.innerHTML="新的div内容";
document.getElementById("myimg").src="x1.jpg";

<h1 style="color: green;" id="myh1">hello world</h1>
var h1=document.getElementById("myh1");
h1.setAttribute("class","bg");//设置属性
console.log(h1.getAttribute("class"));//获取属性class
console.log(h1.getAttribute("style"));//获取属性style

<span id="myli">样式修改</span>
document.getElementById("myli").style.color="blue";
document.getElementById("myli").style.fontFamily="微软雅黑";
document.getElementById("myli").style.fontSize="24px";

8.5 创建 替换 删除元素

1. 创建元素节点:
	document.getElementById("btn").onclick = function () {
        var li = document.createElement("li");//创建元素
        li.id = "tj";
        li.value = "tianjin";
        li.innerHTML = "天津";
        document.getElementById("city").appendChild(li);//将新创建的节点加入到city父节点下
      //也可以使用下面的代码:
      // var city = document.getElementById("city");
      // city.innerHTML = city.innerHTML + "<li id='tianjin' value='tianjin'>天津</li>";
    }

2. 替换元素节点:
<div id="div1">
    <p id="p1">这是一个段落。</p>
    <p id="p2">这是另外一个段落。</p>
</div>
   function changeElement() {
        var newElementP = document.createElement("p");//1,创建一个新的段落元素
        newElementP.innerHTML="这是我新创建的段落p";//2. 设置元素的内容
        newElementP.style.color = "red";
      
        var div = document.getElementById("div1");//获取父节点和要替换的节点
        var p1 = document.getElementById("p1");
        //将div中的元素p1替换为新创建的元素
        div.replaceChild(newElementP, p1);
    }

3. 删除元素节点:
    function deleteElement(){
        var div = document.getElementById("div1");
        var p1 = document.getElementById("p1");
        div.removeChild(p1);
    }

9. 综合案例

9.1 表单验证

思路:1. 验证使用名格式是否正确,长度大于6,第一位不为0;
	2. 验证密码均为数字且长度在6~12;
	3. 验证 确认密码,其值必须与密码相同
<body>
<h1>英雄会注册</h1>
<form action="#" method="get" onsubmit="return register()"> //必须要加上return,满足条件才能被提交
    用户名<input type="text" id="userName" placeholder="请输入用户名" onblur="validateName()">
    <span id="nameMsg">用户名长度至少6位 </span><br>			onblur:表示元素失去焦点时触发
    密码<input type=" password" id="password1" placeholder="请输入密码" onblur = "validatePwd()">
    <span id="pwdMsg1">密码长度至少8位</span><br/>
    确认密码:<input type="password" id="password2" placeholder="请确认密码" onblur = "confirmPwd()"/>
    <span id="pwdMsg2">确认密码与密码一致</span><br/>
    性别:<select id="gender">
    <option value="0"></option>
    <option value="1"></option>
    <option value="-1" selected>请选择性别</option>
</select>
    <br>
    <button type="submit">注册</button>
    <button type="reset">重置</button>
</form>
<script>
    //验证用户名
    function validateName() {
        var name = document.getElementById("userName").value;
        var msg = document.getElementById("nameMsg");
        var regex = /^\w{6,}$/;//六位以上
        if (regex.test(name)) {
            msg.style.color = "green";
            msg.innerHTML = "√";
            return true;
        } else {
            msg.style.color = "red";
            msg.innerHTML = "×";
            return false;
        }
    };
    //验证密码
    function validatePwd() {
        var passwd = document.getElementById("password1").value
        var msg = document.getElementById("pwdMsg1");
        var regex = /^\d{6,12}$/;//密码6~12位
        if (regex.test(passwd)) {
            msg.innerHTML = "密码合法";
            msg.style.color = "green";
            return true;
        } else {
            msg.innerHTML = "密码错误";
            msg.style.color = "red";
            return false;
        }
    };
    //对确认密码的验证
    function confirmPwd() {
        var pwd1 = document.getElementById("password1").value;
        var pwd2 = document.getElementById("password2").value;
        var msg = document.getElementById("pwdMsg2");
        if (pwd1 !== pwd2) {
            msg.innerHTML = "密码不一致";
            msg.style.color = "red";
            return false;
        }
        msg.innerHTML = "两次输入的密码一致";
        msg.style.color = "green";
        return true;
    };
    //提交条件
    function register() {
        return validateName() && validatePwd() && confirmPwd();//三个都满足才能被提交
    }
</script>
</body>

9.2 轮播图片

思路:1.先选取一张图片,并以这张图片作为对象进行修改
	2. 修改这张图片的src属性的值来达到切换图片的效果
	3. 对这种切换每2s执行一次。
<body>
<img src = "../../img/shy.png" height="500px"  id = "img1">

<script>
    var arr = ["../../img/lady.jpg","../../img/夜光.png","../../img/shy.jpeg"];
   	//设置图片路径数组,根据下标选取图片路径
    var index = 0;
    setInterval(changeImg, 1000);//每一秒执行一次切换照片的操作

    function changeImg(){
        var index1 = index%3 //0,1,2
        var img = document.getElementById("img1");
        img.src = arr[index1];
        index++;
    }
</script>
</body>

9.3 定时弹出 + 手动隐藏

定时弹出思路:1. 选取一张图片 2. 修改图片的样式:display来完成隐藏和显示  3. 显示图片后两秒执行隐藏图片,两秒后再执行显示图片

手动隐藏思路: 1. 选取一张图片和两个按钮,一个显示一个隐藏 2. 修改图片的样式:display 3. 使用事件的onclick做到显示和隐藏
<body>
<input type="button" value="显示" οnclick="showImg()"/>
<input type="button" value="隐藏" οnclick="hideImg()"/><br/>
<img src="../../img/JK.jpg" width="30%" id="img2"/>
<hr>
<img src="../../img/ai.jpg" id="img1" width="20%" style="display: none">
<script>
   //手动显示和隐藏
    var img2 = document.getElementById("img2");
    function showImg() {
        img2.style.display = "block";
    }
    function hideImg() {
        img2.style.display = "none";
    }
   
	 //定时弹出
    var img = document.getElementById("img1");
    function imgShow() {
        img.style.display = "block";
        setTimeout(imgHidden, 2000);//2.再进行隐藏图片
    }
    function imgHidden() {
        img.style.display = "none";
        setTimeout(imgShow, 2000);//3,再进行显示图片,循环进行
    }
    setTimeout(imgShow, 2000);//1.先执行显示图片
</script>
</body>

9.4 表格换色+全选

表格换色思路:1. 先得到包含每一行(tr) 的数组 2. 使用for循环,奇数一类,偶数一类 3. 进行类型的区分样式

表格全选思路:1. 先得到 表头元素 和其它行元素 
		2. 给表头元素的复选框添加单击事件 
		3. 使用for循环使其他行的 checked属性值 等于 表头的 checked属性值

<body>
<table border="1px" width="600px" id="table1">
    <tr>
        <td>
            <input type="checkbox" id="checkAll"/><!--复选框-->
        </td>
        <td>分类ID</td>
        <td>分类名称</td>
        <td>分类商品</td>
        <td>分类描述</td>
        <td>操作</td>
    </tr>
    <tr>
        <td>
            <input type="checkbox" name="checkOne"/>
        </td>
        <td>1</td>
        <td>手机数码</td>
        <td>华为,小米,尼康</td>
        <td>数码产品质量最好</td>
        <td>
            <a href="#">修改</a>|<a href="#">删除</a>
        </td>
    </tr>
    <tr>
        <td>
            <input type="checkbox" name="checkOne"/>
        </td>
        <td>2</td>
        <td>生活用品</td>
        <td>牙膏、牙刷</td>
        <td>很好用,性价比很高,质量好</td>
        <td><a href="#">修改</a>|<a href="#">删除</a></td>
    </tr>
    <tr>
        <td>
            <input type="checkbox" name="checkOne"/>
        </td>
        <td>3</td>
        <td>电脑办公</td>
        <td>联想,小米</td>
        <td>笔记本特卖</td>
        <td><a href="#">修改</a>|<a href="#">删除</a></td>
    </tr>
    <tr>
        <td>
            <input type="checkbox" name="checkOne"/>
        </td>
        <td>4</td>
        <td>馋嘴零食</td>
        <td>辣条,麻花,黄瓜</td>
        <td>年货</td>
        <td><a href="#">修改</a>|<a href="#">删除</a></td>
    </tr>
    <tr>
        <td>
            <input type="checkbox" name="checkOne"/>
        </td>
        <td>5</td>
        <td>床上用品</td>
        <td>床单,被套,四件套</td>
        <td>都是套子</td>
        <td><a href="#">修改</a>|<a href="#">删除</a></td>
    </tr>
</table>
<script>
    var rows = document.getElementsByTagName("tr");
    for (var row in rows) {
        if (row % 2 === 0) {
            rows[row].bgColor = "antiquewhite";
        } else {
            rows[row].bgColor = "grey";
        }
    }
    var checkAll = document.getElementById("checkAll");
    var checkOne = document.getElementsByName("checkOne");
    checkAll.onclick = function () {
        // console.log(checkAll.getAttribute("checked"));
        for (var i = 0; i < checkOne.length; i++) {
            checkOne[i].checked = checkAll.checked
        }
    };
</script>
</body>

9.5 省市联动

思路:1. 使用二维数组存放每个省份的城市
	2. 获取选中的省份的value作为数组的下标,
	3. 清空当前的城市的内容
	4. 使用for循环将数组中的城市添加到城市下拉列表中

<body>
<!--选择省份-->
<select id="province">
    <option value="-1">--请选择--</option>
    <option value="0">广东省</option>
    <option value="1">湖南省</option>
    <option value="2">福建省</option>
</select>
<!--选择城市-->
<select id="city"></select>

<script>
    var provinces = [//使用二维数组
        ["深圳市", "东莞市", "惠州市", "广州市"],
        ["长沙市", "岳阳市", "株洲市", "湘潭市"],
        ["厦门市", "福州市", "漳州市", "泉州市"]
    ];
    var province = document.getElementById("province");
    var city = document.getElementById("city");

    province.onchange = function () {
        var citys = provinces[province.value]//数组
        city.innerHTML = " ";
        for (var i = 0; i < citys.length; i++) {
            var option = document.createElement("option");
            option.value = i;
            option.innerHTML = citys[i];
            city.appendChild(option);
        }
    };
</script>
</body>

9.6 商品移动

<body>
<table border="1px" width="400px">
    <tr>
        <td>分类名称</td>
        <td>手机数码</td>
    </tr>
    <tr>
        <td>分类描述</td>
        <td>这里面都是手机数码</td>
    </tr>
    <tr>
        <td>分类商品</td>
        <td>
            <!--左边-->
            <div style="float: left">
                已有商品<br/>
                <select multiple="multiple" id="leftSelect">
                    <option>华为</option>
                    <option>小米</option>
                    <option>锤子</option>
                    <option>oppo</option>
                </select>
                <br/>
                <a href="#" id="a1"> &gt;&gt; </a> <br/>
                <a href="#" id="a2"> &gt;&gt;&gt; </a>
            </div>
            <!--右边-->
            <div style="float: right;">
                未有商品<br/>
                <select multiple="multiple" id="rightSelect">
                    <option>苹果6</option>
                    <option>肾7</option>
                    <option>诺基亚</option>
                    <option>波导</option>
                </select>
                <br/>
                <a href="#"id="a3"> &lt;&lt; </a> <br/>
                <a href="#"id="a4"> &lt;&lt;&lt; </a>
            </div>
        </td>
    </tr>
    <tr>
        <td colspan="2">
            <input type="submit" value="提交"/>
        </td>
    </tr>
</table>

思路:1. 获取左侧商品和右侧商品列表   
   2. 获取超链接并添加事件-->使用超链接挪动商品
   3. 介绍几种select-dom的属性:
   	1). options[]:所有的商品元素
   	2). selectedIndex:选中的商品元素
   4. 右侧商品列表添加左侧选中的商品r.appendChild(l.options[ l.selectedIndex])
   5. 全部移动使用for循环根据数组的长度,从最后一个开始移动商品元素。
   	注意:必须从最后一个开始,因为从第一开始options[]数组中想要移动的商品下标会发生改变,不容易控制
   6.同理,从右侧列表移动到左侧列表,只需要修改(4-5)的对象即可。
<script>
    var l = document.getElementById("leftSelect");
    var r = document.getElementById("rightSelect");
    var a1 = document.getElementById("a1");
    var a2 = document.getElementById("a2");

   //从左往右移动
    a1.onclick = function () {
        r.appendChild(l.options[ l.selectedIndex]);
    };
    a2.onclick = function () {
        for (var i = l.options.length - 1; i >= 0; i--) {
            r.appendChild(l.options[i]);
        }
    };
   //从右往左移动
    var a3 = document.getElementById("a3");
    var a4 = document.getElementById("a4");
    a3.onclick = function () {
        // console.log(l.options[l.selectedIndex]);
        l.appendChild(r.options[r.selectedIndex]);
    };
    a4.onclick = function () {
        for (var i = r.options.length - 1; i >= 0; i--) {
            l.appendChild(r.options[i]);
        }
    };
</script>
</body>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值