JavaScript

JavaScript 介绍

Javascript 语言诞生主要是完成页面的数据验证,是一门脚本语言。
因此它运行在客户端,需要运行浏览器来解析执行 JavaScript 代码。
JS是 Netscape网景公司的产品,最早取名为 LiveScript;为了吸引更多 java程序员。更名为 JavaScript。

Java 和 JavaScript 没什么联系
JS是弱类型,Java是强类型。

特点:

  1. 交互性(它可以做的就是信息的动态交互)
  2. 安全性(不允许直接访问本地硬盘)
  3. 跨平台性(只要是可以解释 JS的浏览器都可以执行,和平台无关)

JavaScript 和 html 代码的结合方式

内部标签Script

在 head 标签中 或者 在 body 标签中
使用 script 标签 来书写 JavaScript 代码.

<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    
    <script type="text/javascript">
        // alert是JavaScript语言提供的一个警告框弹窗函数。
        // 它可以接收任意类型的参数,这个参数就是警告框的提示信息
        alert("hello javaScript!");
    </script>
    
</head>
<body>

</body>
</html>

外部引入 .js

先创建一个专门 JS代码的文件夹

使用 script 标签 引入 外部的js文件 来执行
src 属性专门用来引入js文件路径(可以是相对路径,也可以是绝对路径)

<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    
    <!--
        script标签可以用来定义js代码,也可以用来引入js文件
        但是,两个功能二选一使用。不能同时使用两个功能
    -->
    <script type="text/javascript" src="1.js"></script>
    <script type="text/javascript">
        alert("?");
    </script>

    <!--
        下面的这种是错误的因为在一个 script 标签内,用了两种方式
        而上面的 是用了两个 script 标签,分别用了不同的方式
    -->
<!--    <script type="text/javascript" src="1.js">-->
<!--    alert("?");-->
<!--    </script>-->


</head>
<body>

</body>
</html>

1.js:

alert("1125 hello!");

变量

JavaScript 的变量类型:
数值类型: number
字符串类型:string
对象类型: object
布尔类型: boolean
函数类型:function

JavaScript 里特殊的值:
undefined:未定义,所有 js变量未赋于初始值的时候,默认值都是 undefined.
null:空值
NaN:全称是:Not a Number。非数字。非数值。
Infinity:无限大的数

JS 中的定义变量格式:
var 变量名;
var 变量名 = 值;

<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    
    <script type="text/javascript">
        var i;
        // alert(i); // undefined
        
        i = 12;
        // typeof()是JavaScript语言提供的一个函数。
        // alert( typeof(i) ); // number

        i = "abc";
        // 它可以取变量的数据类型返回
        // alert( typeof(i) ); // String

        var a = 12;
        var b = "abc";
        alert( a * b ); // NaN是非数字,非数值。
    </script>
    
</head>
<body>

</body>
</html>

在浏览器F12后,可以通过
console.log() 函数在控制台打印变量

关系(比较)运算

等于: == 等于是简单的做 字面值的比较
全等于:=== 除了做字面值的比较之外,还会 比较两个变量的数据类型

少用==,一般用===

另一个例外是 NaN 这个特殊的Number与所有其他值都不相等,包括它自己
NaN === NaN; // false

唯一能判断 NaN 的方法是通过 isNaN() 函数:
isNaN(NaN); // true

<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    
    <script type="text/javascript">

        var a = "12";
        var b = 12;

        alert( a == b ); // true
        alert( a === b ); // false

    </script>
    
</head>
<body>

</body>
</html>

逻辑运算

且运算: &&
或运算: ||
取反运算: !

在 JavaScript 语言中,所有的变量,都可以做为一个 boolean 类型的变量去使用。

0 、null、 undefined、 ””(空串)

​ 都是 false;

&& 且运算,有两种情况:
第一种:当表达式全为真的时候。返回最后一个表达式的值。
第二种:当表达式中,有一个为假的时候。返回第一个为假的表达式的值

|| 或运算,有两种情况:
第一种情况:当表达式全为假时,返回最后一个表达式的值
第二种情况:只要有一个表达式为真。就会把回第一个为真的表达式的值 并且

&& 与运算 和 ||或运算 有短路。
短路就是说,当这个&&或||运算有结果了之后 。
后面的表达式不再执行

<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    
    <script type="text/javascript">
   /*     在JavaScript语言中,所有的变量,都可以做为一个boolean类型的变量去使用。
        0 、null、 undefined、””(空串) 都认为是 false;*/

        // var a = 0;
        // if (a) {
        //     alert("零为真");
        // } else {
        //     alert("零为假");
        // }

        // var b = null;
        // if (b) {
        //     alert("null为真");
        // } else {
        //     alert("null为假");
        // }

        // var c = undefined;
        // if (c) {
        //     alert("undefined为真");
        // } else {
        //     alert("undefined为假");
        // }

        // var d = "";
        // if (d) {
        //     alert("空串为真");
        // } else {
        //     alert("空串为假");
        // }


/*         && 且运算。
		有两种情况:
		第一种:当表达式全为真的时候。返回最后一个表达式的值。
		第二种:当表达式中,有一个为假的时候。返回第一个为假的表达式的值*/

        var a = "abc";
        var b = true;
        var d = false;
        var c = null;

        // alert( a && b );//true
        // alert( b && a );//abc
        // alert( a && d ); // false
        // alert( a && c ); // null

 /*      || 或运算
       第一种情况:当表达式全为假时,返回最后一个表达式的值
       第二种情况:只要有一个表达式为真。就会把回第一个为真的表达式的值*/
        // alert( d || c ); // null
        // alert( c|| d ); //false

        // alert( a || c ); //abc
        // alert( b || c ); //true

    </script>
    
</head>
<body>

</body>
</html>

strict模式

问题:
如果一个变量没有通过 var 申明就被使用
那么该变量就自动被申明为全局变量
i = 10; // i现在是全局变量

引入:
在strict模式下运行的 JavaScript代码,强制通过 var 申明变量,
未使用 var 申明变量就使用的,将导致运行错误。

格式:
在JavaScript代码的第一行写上:'use strict';

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

image-20210322094100616

<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <!--
    局部变量建议都使用 let 去定义~
    -->
    <script>
        'use strict';
        let i = 1;
    </script>

</head>
<body>

</body>
</html>

字符串

JavaScript的字符串就是用 '' 或 "" 括起来的字符表示。
如果 ' 本身也是一个字符,那就可以用 "" 括起来
比如 "I'm OK" 包含的字符是'I\'m \"OK\"!';

用转义字符 \ 来标识

表示的字符串内容是: I'm "OK"!

多行字符串

由于多行字符串用 \n 写起来比较费事,所以最新的ES6标准新增了一种多行字符串的表示方法
用反 引号``` `表示:这是一个 多行 字符串;

`这是一个 
多行 
字符串`;

注意:反引号在键盘的ESC下方,数字键1的左边:

模板字符串

要把多个字符串连接起来,可以用 + 号连接:

var name = '小明';
var age = 20;
var message = '你好, ' + name + ', 你今年' + age + '岁了!'; 
alert(message);

如果有很多变量需要连接,用号就比较麻烦
ES6新增了一种模板字符串,表示方法和上面的多行字符串一样,但是它会自动替换符串中的变量:

var name = '小明';
var age = 20;
var message = `你好, ${name}, 你今年${age}岁了!`; alert(message);

操作字符

求字符串长度: .length

var s = 'Hello, world!'; 
s.length; // 13

取指定位置:

要获取字符串某个指定位置的字符,使用类似Array的下标操作,索引号从0开始:

var s = 'Hello, world!'; 
s[0]; // 'H'
s[6]; // ' ' 
s[7]; // 'w' 
s[12]; // '!'
s[13]; // undefined 超出范围的索引不会报错,但一律返回undefined

需要特别注意的是,字符串是不可变的,如果对字符串的某个索引赋值,不会有任何错误,但是,也没有任何效果:

var s = 'Test'; 
s[0] = 'X';
alert(s); // s仍然为'Test'

**把一个字符串全部变为大写: **toUpperCase()

var s = 'Hello';
s.toUpperCase(); // 返回'HELLO'

把一个字符串全部变为小写:toLowerCase()

var s = 'Hello';
var lower = s.toLowerCase(); // 返回'hello'并赋值给变量lower 
lower; // 'hello'

会搜索指定字符串出现的位置:indexOf()

var s = 'hello, world';
s.indexOf('world'); // 返回7
s.indexOf('World'); // 没有找到指定的子串,返回-1

返回指定索引区间的子串:substring()

var s = 'hello, world'
s.substring(0, 5); // 从索引0开始到5(不包括5),返回'hello' 
s.substring(7); // 从索引7开始到结束,返回'world'

数组

基础

定义格式:
var 数组名 = []; // 空数组
var 数组名 = [1 , ’abc’ , true]; // 定义数组同时赋值元素

length属性:

var arr = [1,2,666,'pff']
arr.length; //6

给length赋新值:
会导致大小的变化

var arr = [1, 2, 3];
arr.length; // 3
arr.length = 6;
arr; // arr变为[1, 2, 3, undefined, undefined, undefined]
arr.length = 2;
arr; // arr变为[1, 2]

访问越界索引值
数组会自动扩容

var arr = [1, 2, 3]; 
arr[5] = 'x';
arr; 
// arr变为[1, 2, 3, undefined, undefined, 'x']

常用函数

  1. indexOf
    Array也可以通过indexOf来搜索一个指定的元素的位置
var arr = [10, 20, '30', 'xyz'];
arr.indexOf(10); // 元素10的索引为0
arr.indexOf(20); // 元素20的索引为1
arr.indexOf(30); // 元素30没有找到,返回-1
arr.indexOf('30'); // 元素'30'的索引为2
  1. slice()
    相当于String的substring()
    用于截取原数组的部分元素,然后返回一个新的数组
var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
arr.slice(0, 3); // 从索引0开始,到索引3结束,但不包括索引3: ['A', 'B', 'C'] 
arr.slice(3); // 从索引3开始到结束: ['D', 'E', 'F', 'G']

可以很容易地利用silice()复制一个数组

var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G']; 
var aCopy = arr.slice();
aCopy; // ['A', 'B', 'C', 'D', 'E', 'F', 'G'] 
aCopy === arr; // false
  1. push()
    向数组末尾添加若干元素
var arr = [1, 2];
arr.push('A', 'B'); // 返回Array新的长度: 4
arr; // [1, 2, 'A', 'B']
  1. pop()
    将数组最后一个元素删除掉
var arr = [1, 2,'A', 'B'];
arr.pop(); // pop()返回'B'
arr; // [1, 2, 'A']
arr.pop(); arr.pop(); arr.pop(); // 连续pop 3次
arr; // []
arr.pop(); // 空数组继续pop不会报错,而是返回undefined
arr; // []
  1. unshift()
    向数组头部添加若干元素
  2. shift()
    将数组第一个元素删除
var arr = [1, 2];
arr.unshift('A', 'B'); // 返回Array新的长度: 4
arr; // ['A', 'B', 1, 2]
arr.shift(); // 'A'
arr; // ['B', 1, 2]
arr.shift(); arr.shift(); arr.shift(); // 连续shift 3次
arr; // []
arr.shift(); // 空数组继续shift不会报错,而是返回undefined
arr; // []
  1. sort()
    可以对当前数组进行排序,它会直接修改当前的元素位置,直接调用时,按照默认顺序排序
var arr = ['B', 'C', 'A']; 
arr.sort();
arr; // ['A', 'B', 'C']
  1. reverse()
    reverse()把整个数组的元素进行反转
var arr = ['one', 'two', 'three']; 
arr.reverse();
arr; // ['three', 'two', 'one']
  1. splice()
    修改数组的万能方法
    从指定的索引开始删除若干元素,然后再从该位置添加若干元素
var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle']; // 从索引2开始删除3个元素,然后再添加两个元素:
arr.splice(2, 3, 'Google', 'Facebook'); // 返回删除的元素    ['Yahoo', 'AOL', 'Excite']
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle'] // 只删除,不添加:
arr.splice(2, 2); // ['Google', 'Facebook'] 
arr; // ['Microsoft', 'Apple', 'Oracle'] // 只添加,不删除
arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因为没有删除任何元素 
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
  1. concat()
    把当前的数组和另一个数组连接起来,并返回一个新的数组

concat()方法没有修改当前数组,之示返回了一个新的数组

concat()方法可以接收人一个元素和数组,并把数组拆开,然后全部添加到新的数组当中去

var arr = ['A', 'B', 'C'];
var added = arr.concat([1, 2, 3]); 
added; // ['A', 'B', 'C', 1, 2, 3] 
arr; // ['A', 'B', 'C']
arr.concat(1,2,[3,4]);	//['A','B', 'C', 1, 2, 3, 4]
  1. join()
    把当前数组的每个元素都用指定的字符串连接起来
    然后返回连接后的字符串
var arr = ['A', 'B', 'C', 1, 2, 3];
arr.join('-'); // 'A-B-C-1-2-3'
  1. 多维数组
    如果数组的某个元素又是一个数组,则可以形成多维数组
var arr = [[1, 2, 3],[400,500,600],'-'];
var x = arr[1][2]; console.log(x); // x应该为500

Map

概述:

map是一组键值对的结构,具有极快的查找速度

【用Map实现一个“名字”-“成绩”的对照表】

var m = new Map([['Michael', 95], ['Bob',75],
['Tracy', 85]]);
m.get( 'Michael'); // 95

初始化:

初始化Map需要一个二维数组,或者直接初始化一个空Map

var m = new Map(); // 空Map

常用方法:

m.set('Adam', 67); // 添加新的key-value
m.set('Bob', 59);
m.has('Adam'); // 是否存在key 'Adam': true
m.get('Adam'); // 67
m.delete('Adam'); // 删除key 'Adam'
m.get('Adam'); // undefined

由于一个key只能对应一个value
当多次对一个key放入value,后面的值会把前面的值冲掉

var m = new Map();
m.set('Adam', 67);
m.set('Adam', 88);
m.get('Adam'); // 88

Set

set也是一组key的集合,但不存储value,但规定key不能重复

var s1 = new Set(); // 空Set
var s2 = new Set([1, 2, 3]); // 含1, 2, 3

自动过滤重复元素:

var s = new Set([1,2, 3, 3, '3']);
s; // Set {1,2, 3, "3"}

添加元素: add()

var s = new Set([1, 2, 3]); // 含1, 2, 3
s.add(4);
s; // Set {1, 2, 3, 4}

//添加重复元素,不会有效果
s.add(4);
s; // 仍然是 Set {1, 2, 3, 4}

删除元素: delete()

var s = new Set([1, 2, 3]); s; // 
Set {1, 2, 3}
s.delete(3);
s; // Set {1, 2}

Iterable

遍历 Array 可以采用下标循环,遍历Map 和 Set 就无法使用下标。
为了统一集合类型,ES6标准引入了新的 iterable 类型
Array,Map,Set 可以通过新的 for...of 循环来遍历。

遍历:

var a = ['A', 'B', 'C'];
var s = new Set(['A', 'B', 'C']);
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
for (var x of a) { // 遍历Array    
    console.log(x);
}
for (var x of s) { // 遍历Set    
    console.log(x);
}
for (var x of m) { // 遍历Map
   console.log(x[0] + '=' + x[1]); 
}

forEach() 方法

它接收一个函数,每次迭代就自动回调该函数

forEach() 方法是ES5.1标准引入

【数组】

a.forEach(function (element, index, array) {    
    // element: 指向当前元素的值
   	// index: 指向当前索引
   	// array: 指向Array对象本身
   console.log(element + ', index = ' + index); });

【Map】

回调函数参数依次为value、key、map

var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]); m.forEach(function (value, key, map) {
   console.log(value); 
});

【Set】

set没有索引,因此回调函数的前两个参数都是元素本身

var s = new Set(['A', 'B', 'C']);
s.forEach(function (element, sameElement, set) {
    console.log(element);
});

流程控制

if判断

var age = 3;
if (age >= 18) {
   alert('adult'); 
} else if (age >= 6) {    
    alert('teenager'); 
} else {
   alert('kid'); 
}

for循环

  1. 基础语法
var x = 0; var i;
for (i=1; i<=10000; i++) {    
    x = x + i;
}
x; // 50005000
  1. 遍历数组
var arr = ['Apple', 'Google', 'Microsoft']; 
var i, x;
for (i=0; i<arr.length; i++) {    
    x = arr[i];
    console.log(x); 
}
  1. for ... in

遍历对象属性

var o = {
    name: 'Jack',    
    age: 20,
    city: 'Beijing' };
for (var key in o) {
   if (o.hasOwnProperty(key)) {
       console.log(key); // 'name', 'age', 'city'
   }
}

遍历数组元素

var a = ['A', 'B', 'C']; 
for (var i in a) {
    console.log(i); // '0', '1', '2'    
    console.log(a[i]); // 'A', 'B', 'C' 
}

这里对数组循环得到的是 String 而不是 Number

while循环

  1. 基本操作
var x = 0;
var n = 99; while (n > 0) {    
    x = x + n;
    n = n - 2; 
}
x; // 2500
  1. do ... while
var n = 0; 
do {
    n = n + 1;
} while (n < 100); 
n; // 100

函数

定义函数

function 关键字

格式:
function 函数名(形参列表){
函数体
}

返回值:
在函数体内直接使用 return 语句返回值

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    
    <script type="text/javascript">
        // 定义一个无参函数
        function fun(){
            alert("无参函数fun()被调用了");
        }
        // 函数被调用了才会执行
        // fun();

        function fun2(a ,b) {
            alert("有参函数fun2()被调用了 a=>" + a + ",b=>"+b);
        }
        // fun2(12,"abc");

        // 定义带有返回值的函数
        function sum(num1,num2) {
            var result = num1 + num2;
            return result;
        }

        alert( sum(100,50) );
    </script>
    
</head>
<body>

</body>
</html>

函数变量

格式:
var 函数名 = function(形参列表) {
函数体
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    
    <script type="text/javascript">
        var fun = function () {
            alert("无参函数");
        }
        // fun();

        var fun2 = function (a,b) {
            alert("有参函数a=" + a + ",b=" + b);
        }
        // fun2(1,2);

        var fun3 = function (num1,num2) {
            return num1 + num2;
        }
        alert( fun3(100,200) );
    </script>

</head>
<body>

</body>
</html>

调用函数

function abs(x) {
    if (x >= 0) {
        return x;
    } else
       return -x;
    }
}
// 调用上面定义的函数
abs(10); // 返回10 
abs(-9); // 返回9

参数

参数个数

JavaScript允许传入任意个参数而不影响调用

传入的参数比定义的参数多也没有问题

abs(10, 'blablabla'); // 返回10
abs(-9, 'haha', 'hehe', null); // 返回9

传入的参数比定义的少也没有问题

这里函数的形参x收到undefined
计算结果为 NaN

abs();	// 返回NaN

避免收到undefined,对参数进行检查

function abs(x) {
   if (typeof x !== 'number') {        throw 'Not a number';  }
   if (x >= 0) {        return x;   } else {
       return -x;  }
}

arguments

arguments只在函数内部起作用
并且永远指向当前函数的调用者传入的所有参数

function foo(x) {
   console.log('x = ' + x); // 10
   for (var i=0; i<arguments.length; i++) {
       console.log('arg ' + i + ' = ' + arguments[i]); // 10, 20, 30  
   }
}
foo(10, 20, 30);

rest参数

rest参数可以获取 除了已在形参中定义了的 参数

function foo(a, b, ...rest) {
   console.log('a = ' + a);
   console.log('b = ' + b);
   console.log(rest); 
}

foo(1, 2, 3, 4, 5); // 结果:
// a = 1 // b = 2
// Array [ 3, 4, 5 ] 

foo(1);
// 结果:
// a = 1
// b = undefined // Array []

变量的作用域

局部变量:

function foo() {
   var x = 1;    x = x + 1; 
}
x = x + 2; // ReferenceError! 无法在函数体外引用变量x

问题: 局部变量域冲突
JavaScript的变量作用域实际上是函数内部,我们在 for等语句中块中是无法定义具有局部作用域的变量的

function foo() {
   for (var i=0; i<100; i++) {        
 }
   i += 100; // 仍然可以引用变量i 
}

用let定义块级作用域变量:

function foo() {    
    var sum = 0;
    for (let i=0; i<100; i++) {        
        sum += i;
    }
   // SyntaxError:    
    i += 1;
}

不同函数 内部同名变量:

function foo() {
    var x = 1;    
    x = x + 1; 
}

function bar() {    
    var x = 'A';   
    x = x + 'B'; 
}

函数内外的同名变量:

function foo() {    
    var x = 1;
    function bar() {        
        var x = 'A';
        console.log('x in bar() = ' + x); 	// 'A'  
    }
    console.log('x in foo() = ' + x); // 1    
    bar();
}
foo();

这说明JavaScript的函数在查找变量时从自身函数定义开始,从“内”向“外”查找。

如果内部函数定义了与 外部函数重名的变量,则内部函数的变量将“屏蔽”外部函数的变量。

全局变量:

不在任何函数内定义的变量就具有全局作用域,也就是全局变量

var course = 'Learn JavaScript'; 
alert(course); // 'Learn JavaScript'
alert(window.course); // 'Learn JavaScript' 

直接访问全局变量course 和 window.course是完全一样的

全局变量会自动绑定到window对象上

不允许重载

在 JS中函数的重载会直接覆盖掉上一次的定义

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    
    <script type="text/javascript">
        function fun(a,b) {
            alert("有参函数fun(a,b)");
        }

        function fun() {
            alert("无参函数fun()");
        }

        //这里调用的fun函数 是后面的无参函数
        fun(1,"ad");
        
    </script>
    
</head>
<body>

</body>
</html>

方法

在一个对象中定义的函数,称为这个对象的方法

var xiaoming = {
   name: '小明',
   birth: 1990,
   age: function () {
       var y = new Date().getFullYear();      
       return y - this.birth;
   } 
};

xiaoming.age(); 

拆开方法:

function getAge() {
    var y = new Date().getFullYear();    
    return y - this.birth;
}
var xiaoming = {    
    name: '小明',    
    birth: 1990,    
    age: getAge 
};
xiaoming.age(); // 26, 正常结果 
getAge(); // NaN,这里的默认调用的是window对象

apply函数指向对象:

function getAge() {
    var y = new Date().getFullYear();    
    return y - this.birth;
}
var xiaoming = {    
    name: '小明',    
    birth: 1990,    
    age: getAge 
};
xiaoming.age(); // 25
getAge.apply(xiaoming, []); // 25, this指向xiaoming, 参数为空

JSON

概述

  • JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式,目前使用特别广 泛。
  • 采用完全独立于编程语言的文本格式来存储和表示数据。
  • 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。
  • 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

语法格式

任何JavaScript 支持的类型都可以通过 JSON 来表示
例如字符串、数字、对象、数组等。

看看他的要求和语法格式:

  • 对象 表示为键值对
  • 数据 由逗号分隔
  • 对象 用花括号保存
  • 数组 用方括号保存

JSON 和 JavaScript 对象互转

JSON 是 JavaScript 对象的字符串表示法
它使用文本表示一个 JS 对象的信息,本质是一个字符串。

var obj = {a: 'Hello', b: 'World'}; //这是一个对象,注意键名也是可以使用引号包裹 的
var json = '{"a": "Hello", "b": "World"}'; //这是一个    JSON 字符串,本质是一个 字符串

从 JSON字符串 转换为 JavaScript 对象
使用 JSON.parse() 方法:

var obj = JSON.parse('{"a": "Hello", "b": "World"}'); 
//结果是    {a: 'Hello', b: 'World'}

从 JavaScript 对象 转换为 JSON字符串
使用 JSON.stringify() 方法:

var json = JSON.stringify({a: 'Hello', b: 'World'});
2  //结果是    '{"a": "Hello", "b": "World"}'

对象

JavaScript不区分类和实例的概念
而是通过原型 (prototype)来实现面向对象编程

对象的定义

用 Object 的形式

对象的定义:
var 变量名 = new Object(); // 对象实例(空对象)
变量名.属性名 = 值; // 定义一个属性
变量名.函数名 = function(){} // 定义一个函数

对象的访问:
变量名. 属性/函数名();

// 对象的定义:
var obj = new Object();
obj.name = "华仔";
obj.age = 18;
obj.fun = function () {
    alert("姓名:" + this.name + " , 年龄:" + this.age);
}

// 对象的访问:
// alert( obj.age );
obj.fun();

利用大括号{}的形式

格式:

var 变量名 = { // 空对象

​ 属性名:值, // 定义一个属性
​ 属性名:值, // 定义一个属性
​ 函数名:function(){} // 定义一个函数
};

在里面增加 属性或函数 时,在两个之间加上 "," 最后一个不需要加

        // 对象的定义:
        var obj = {
            name:"国哥",
            age:18,
                fun : function () {
                alert("姓名:" + this.name + " , 年龄:" + this.age);
            }
        };

        // 对象的访问:
        alert(obj.name);
        obj.fun();

原型对象

原型:相当于java中的类
实际上是父类的概念

__proto__

var Student = {
   name: 'Robot',
   height: 1.2,
   run: function () {
       console.log(this.name + ' is running...');  
   }
};
var xiaoming = {    name: '小明' };
xiaoming.__proto__ = Student;

注意最后一行代码把 xiaoming 的原型指向了对象 Student
看上去xiaoming仿佛是从student继承下来的

xiaoming.name; // '小明'
xiaoming.run(); // 小明 is running...

class

定义一个类、属性、方法:

class Student {
    // 构造器的关键字:constructor
    constructor(name) {        
       this.name = name;  
   }
    hello() {
       alert('Hello, ' + this.name + '!');  
    }
}

创建一个Student的对象:

var xiaoming = new Student('小明'); 
xiaoming.hello();

继承:

class PrimaryStudent extends Student {    constructor(name, grade) {
    super(name); // 记得用super调用父类的构造方法!
    this.grade = grade;
 }
   myGrade() {
       alert('I am at grade ' + this.grade);  
   }
}

对象的使用

自由地给一个对象添加或删除属性:

var xiaoming = {    name: '小明' };
xiaoming.age; // undefined

xiaoming.age = 18; // 新增一个age属性
xiaoming.age; // 18

delete xiaoming.age; // 删除age属性 
xiaoming.age; // undefined
delete xiaoming['name']; // 删除name属性 
xiaoming.name; // undefined
delete xiaoming.school; // 删除一个不存在的school属性也不会报错

检测对象是否拥有某一属性,可以用 in 操作符:

var xiaoming = {    
    name: '小明',    
    birth: 1990,
    school: 'No.1 Middle School',    
    height: 1.70,
    weight: 65,
    score: null 
};
'name' in xiaoming; // true 
'grade' in xiaoming; // false

不过要小心,如果用 in 判断一个属性存在,这个属性不一定是由
这个对象的
它可能是这个对象继承得到的

'toString' in xiaoming; // true

判断一个属性是否是自身拥有的,而不是继承得到的
可以用 hasOwnProperty() 方法:

var xiaoming = {    name: '小明' };
xiaoming.hasOwnProperty('name'); // true 
xiaoming.hasOwnProperty('toString'); // false

事件

事件是 电脑输入设备与页面进行交互的响应

常用的事件:

onload 加载完成事件: 页面加载完成之后,常用于做页面 js 代码初始化操作
onclick 单击事件:常用于按钮的点击响应操作。
onblur 失去焦点事件: 常用用于输入框失去焦点后验证其输入内容是否合法。
onchange 内容发生改变事件: 常用于下拉列表和输入框内容发生改变后操作
onsubmit 表单提交事件:常用于表单提交前,验证所有表单项是否合法。

事件的注册:

  1. 定义:告诉浏览器,当事件响应后要执行哪些操作代码
  2. 静态注册事件:通过 html 标签的事件属性直接赋于事件响应后的代码
  3. 动态注册事件:是指先通过 js 代码得到标签的 dom 对象
    然后再通过 dom 对象.事件名 = function(){}
    这种形式赋于事件 响应后的代码
  4. 动态注册基本步骤:
    获取标签对象
    标签对象.事件名 = fucntion(){}

静态注册事件方法:将要做的事情放在一个函数内,先定义在 script 标签内
然后在 body 标签进行调用

动态注册事件方法:window.onload = function () { ... }
不需要调用

onload 加载完成事件

页面加载完成之后,常用于做页面 js 代码初始化操作

<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    
    <script type="text/javascript">
        // onload事件的方法
        function onloadFun() {
            alert('静态注册onload事件,所有代码');
        }

        // onload事件动态注册。是固定写法
        window.onload = function () {
            alert("动态注册的onload事件");
        }

    </script>
    
</head>
<!--静态注册onload事件
        onload事件是浏览器解析完页面之后就会自动触发的事件
       <body onload="onloadFun();">
-->
<body>

</body>
</html>

onclick 单击事件

常用于按钮的点击响应操作。

<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    
    <script type="text/javascript">
        //静态注册onclick事件
        function onclickFun() {
            alert("静态注册onclick事件");
        }

        
        // 动态注册onclick事件,,还要配合onload进行操作
        window.onload = function () {
            // 1 获取标签对象
            
            /*
             * document 是JavaScript语言提供的一个对象(文档)
             * getElementById通过id属性获取标签对象
             */
            var btnObj = document.getElementById("btn01");
            // alert( btnObj );
            // 2 通过标签对象.事件名 = function(){}
            btnObj.onclick = function () {
                alert("动态注册的onclick事件");
            }
        }
    </script>
    
</head>
<body>
    <!--静态注册onClick事件-->
    <button onclick="onclickFun();">按钮1</button>
    
    <!-- 在按钮标签里设置id,通过这个id
		 确定onclick事件发生位置 
	  -->
    <button id="btn01">按钮2</button>
</body>
</html>

onblur 失去焦点事件

失去焦点事件:
鼠标在除了指定位置处,进行了点击
光标就会消失

image-20210308130727979 image-20210308130853868

常用用于输入框失去焦点后 验证其输入内容是否合法。

console.log();

​ 在 console 界面进行输出的语句,本界面不会输出
​ 按 F12 可以打开浏览器的console界面

<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    
    <script type="text/javascript">
        
        // 静态注册失去焦点事件
        function onblurFun() {
            // console是控制台对象,是由JavaScript语言提供,专门用来向浏览器的控制器打印输出, 用于测试使用
            // log() 是打印的方法
            console.log("静态注册失去焦点事件");
        }

        // 动态注册 onblur事件,也要配合onload进行操作
        window.onload = function () {
            //1 获取标签对象
           var passwordObj = document.getElementById("password");
           // alert(passwordObj);
            //2 通过标签对象.事件名 = function(){};
            passwordObj.onblur = function () {
                console.log("动态注册失去焦点事件");
            }
        }

    </script>
    
</head>
<body>
    用户名:<input type="text" onblur="onblurFun();"><br/>
    密码:<input id="password" type="text" ><br/>
</body>
</html>
  1. 静态注册失去焦点事件

image-20210308131607177

  1. 动态注册失去焦点事件

image-20210308131655231

onchange 内容发生改变事件

每次更改选项会弹出的事件信息

常用于下拉列表和输入框内容发生改变后操作

<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script type="text/javascript">
        function onchangeFun() {
            alert("女神已经改变了");
        }

        window.onload = function () {
            //1 获取标签对象
            var selObj = document.getElementById("sel01");
            // alert( selObj );
            //2 通过标签对象.事件名 = function(){}
            selObj.onchange = function () {
                alert("男神已经改变了");
            }
        }
    </script>
    
</head>
    
<body>
    请选择你心中的女神:
    <!--静态注册onchange事件-->
    <!--在这里进行调用,每次选择 非当前选项 的时候,都会进行一次调用onchange事件-->
    <select onchange="onchangeFun();">
        <option>--女神--</option>
        <option>芳芳</option>
        <option>佳佳</option>
        <option>娘娘</option>
    </select>

    请选择你心中的男神:
    <select id="sel01">
        <option>--男神--</option>
        <option>国哥</option>
        <option>华仔</option>
        <option>富城</option>
    </select>


</body>
</html>

onsubmit

常用于表单提交前,验证所有表单项是否合法

<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    
    <script type="text/javascript" >
        // 静态注册表单提交事务
        function onsubmitFun(){
            // 要验证所有表单项是否合法,如果,有一个不合法就阻止表单提交
            alert("静态注册表单提交事件----发现不合法");

            return flase;
        }
        
        // 动态注册表单提交事务
        window.onload = function () {
            //1 获取标签对象
            var formObj = document.getElementById("form01");
            //2 通过标签对象.事件名 = function(){}
            formObj.onsubmit = function () {
                // 要验证所有表单项是否合法,如果,有一个不合法就阻止表单提交
                alert("动态注册表单提交事件----发现不合法");

                return false;
            }
        }
    </script>
    
</head>
<body>
    <!--return false 可以阻止 表单提交 -->
    <!-- form是表单标签 -->

    <form action="http://localhost:8080" method="get" onsubmit="return onsubmitFun();">
                <!-- 这里标签内的 onsubmit 里一定要有return,
                                然后通过事件的返回值确定是否提交
                  -->
        
        <input type="submit" value="静态注册"/>
    </form>
    <form action="http://localhost:8080" id="form01">
        <input type="submit" value="动态注册"/>
    </form>

</body>
</html>

操作BOM对象

BOM(Browser Object Model) 是指浏览器对象模型
用于描述这种对象与对象之间层次关系的模型,浏览器对象模型提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。
BOM由多个对象组成,其中代表浏览器窗口的Window对象是BOM的顶层对象,其他对象都是该对象的子对象。

window对象

window对象不但充当全局作用域,而且表示浏览器窗口

  • 获取浏览器窗口的内部宽度和高度

    内部宽高是指除去菜单栏、工具栏、边框等占位元素后
    用于显示网页的净宽高

    • innerWidth
    • innerHeight
  • 获取浏览器窗口的整个宽高

    • outerWidth
    • outerHeight
// 可以调整浏览器窗口大小试试:
console.log('window inner size: ' + window.innerWidth + ' x ' + window.innerHeight);

navigator表示浏览器的信息,最常用的属性包括:

  • navigator.appName:浏览器名称;
  • navigator.appVersion:浏览器版本;
  • navigator.language:浏览器设置的语言;
  • navigator.platform:操作系统类型;
  • navigator.userAgent:浏览器设定的User-Agent字符串
console.log('appName = ' + navigator.appName);
console.log('appVersion = ' + navigator.appVersion);
console.log('language = ' + navigator.language);
console.log('platform = ' + navigator.platform);
console.log('userAgent = ' + navigator.userAgent);

navigator的信息可以被用户修改
所以不建议使用这些属性来判断和编写代码

screen对象

screen对象表示屏幕的信息,常用的属性有:

  • screen.width:屏幕宽度,以像素为单位
  • screen.height:屏幕高度,以像素为单位
  • screen.colorDepth:返回颜色位数,如8、16、24
console.log('Screen size = ' + screen.width + ' x ' + screen.height);

location对象

location对象表示当前页面的URL信息

location.href获得一个完整的URL

例如:
http://www.example.com:8080/path/index.html?a=1&b=2#TOP

若要获得URL各个部分的值:

location.protocol; // 'http'
location.host; // 'www.example.com'
location.port; // '8080'
location.pathname; // '/path/index.html'
location.search; // '?a=1&b=2'
location.hash; // 'TOP'

加载一个新的页面: location.assign()

重新加载当前界面: location.reload()

document

document对象表示当前页面。
由于HTML在浏览器中以DOM形式表示为树形结构,document对象就是整个DOM树的根节点

document的title属性是从HTML文档读取的,而且可以动态改变

document的cookie属性可以获取当前页面Cookie

为了确保安全,服务器端在设置Cookie时
应该始终坚持使用httpOnly

history

history对象保存了浏览器的历史记录
JavaScript可以调用history对象的back()或forward(),相当于用户点击了浏览器的“后退”或“前进”按钮

操作DOM对象

DOM 是 Document Object Model 文档对象模型
把文档(html文件)中的 标签,属性,文本 转换成为对象来管理

DOM是一个树形结构。操作一个DOM节点实际上就是这么几个操作:

  • 更新:更新该DOM节点的内容,相当于更新了该DOM节点表示的HTML的内容;
  • 遍历:遍历该DOM节点下的子节点,以便进行进一步操作;
  • 添加:在该DOM节点下新增一个子节点,相当于动态增加了一个HTML节点;
  • 删除:将该节点从HTML中删除,相当于删掉了该DOM节点的内容以及它包含的所有子节点

document对象

  1. Document 它管理了所有的 HTML 文档内容。

  2. document 它是一种树结构的文档。有层级关系

  3. 它让我们把所有的 标签 都对象化

  4. 我们可以通过 document 访问所有的标签对象

image-20210308195048349

对象化

【将html标签 进行 对象化】

<body>
<div id="div01">div01</div> 
</body>
class Dom{
private String id;          // id  属性
private String tagName; 	//表示标签名
private Dom parentNode; 	//父亲
private List<Dom> children; //    孩子结点
private String innerHTML; 	//    起始标签和结束标签中间的内容 
}
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" >
        /*
        * 需求:当用户点击了较验按钮,要获取输出框中的内容。然后验证其是否合法。<br/>
        * 验证的规则是:必须由字母,数字。下划线组成。并且长度是5到12位。
        * */
        function onclickFun() {
            // 当我们要操作一个标签的时候,一定要先获取这个标签对象。
            // 这里通过 id(username)获取的是输入框标签对象
            var usernameObj = document.getElementById("username");

            // [object HTMLInputElement] 它就是dom对象
            // 获取输入框中,输入的字符串
            var usernameText = usernameObj.value;

            // 如何 验证 字符串,符合某个规则 ,需要使用正则表达式技术
            var patt = /^\w{5,12}$/;


            var usernameSpanObj = document.getElementById("usernameSpan");
            // innerHTML 表示起始标签和结束标签中的内容
            // innerHTML 这个属性可读,可写
            usernameSpanObj.innerHTML = "国哥真可爱!";

            /*
            *  test()方法用于测试某个字符串,是不是匹配我的规则 ,
            *  匹配就返回true。不匹配就返回false.
            * */
            if (patt.test(usernameText)) {
                // alert("用户名合法!");
                // usernameSpanObj.innerHTML = "用户名合法!";
                usernameSpanObj.innerHTML = "<img src=\"right.png\" width=\"18\" height=\"18\">";
            } else {
                // alert("用户名不合法!");
                // usernameSpanObj.innerHTML = "用户名不合法!";
                usernameSpanObj.innerHTML = "<img src=\"wrong.png\" width=\"18\" height=\"18\">";
            }
        }
    </script>

</head>
<body>
    用户名:<input type="text" id="username" value="wzg"/>
    <span id="usernameSpan" style="color:#ff0000;"></span>
    <button onclick="onclickFun()">较验</button>
</body>
</html>

操作

修改DOM

修改文本:

  • 通过innerHTML属性
    不但可以修改一个DOM节点的文本内容,还可以修改直接通过HTML片段修改DOM节点内部的子树
// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id'); // 设置文本为abc:
p.innerHTML = 'ABC'; // <p id="p-id">ABC</p> // 设置HTML:
p.innerHTML = 'ABC <span style="color:red">RED</span> XYZ'; // <p>...</p>的内部结构已修改
  • 通过innerText属性
    自动对字符串进行HTML编码,保证无法设置任何HTML标签
// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id'); // 设置文本:
p.innerText = '<script>alert("Hi")</script>'; 
// HTML被自动编码,无法设置一个<script>节点:
// <p id="p-id">&lt;script&gt;alert("Hi")&lt;/script&gt;</p>

修改css:

  • 通过style属性
// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id'); // 设置CSS:
p.style.color = '#ff0000'; 
p.style.fontSize = '20px'; 
p.style.paddingTop = '2em';

插入DOM

appendChild(): 在已知节点内插入新节点

<p id="js">JavaScript</p> 
<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>    
    <p id="scheme">Scheme</p> 
</div>

把JavaScript添加到最后一项

var
   js = document.getElementById('js'),
   list = document.getElementById('list'); list.appendChild(js);

结果:

<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>    
    <p id="scheme">Scheme</p>    
    <p id="js">JavaScript</p> 
</div>

因为要插入的节点已经存在当前的文档树当中了
所以这个节点会先从指定位置删除,在出入到新的位置

creatElement(): 创建一个新的节点

创建一个新的节点,然后插入到指定位置

var
   list = document.getElementById('list'),
   haskell = document.createElement('p');
haskell.id = 'haskell';
haskell.innerText = 'Haskell'; list.appendChild(haskell);

结果:

<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>    
    <p id="scheme">Scheme</p>    
    <p id="haskell">Haskell</p> 
</div>

setAtrribute(): 插入的万能方法

添加CSS代码

var d = document.createElement('style'); d.setAttribute('type', 'text/css');
d.innerHTML = 'p { color: red }'; 
//head 头部标签
document.getElementsByTagName('head')[0].appendChild(d);

insertBefore: 把子节点插入到指定的位置

parentElement.insrertBefore(newElement, referenceElement);

在parentElement内部
将newElement插入到referenceElement前面

<div id="list">
    <p id="java">Java</p>
    <p id="python">Python</p>    
    <p id="scheme">Scheme</p> 
</div>

把Haskell插入到Python之前:

var
    list = document.getElementById('list'),    
    ref = document.getElementById('python'),
    haskell = document.createElement('p');
haskell.id = 'haskell';
haskell.innerText = 'Haskell'; 

list.insertBefore(haskell, ref);

结果:

<div id="list">
    <p id="java">Java</p>
    <p id="haskell">Haskell</p>    
    <p id="python">Python</p>    
    <p id="scheme">Scheme</p> 
</div>

删除DOM

获得该节点本身以及它的父节点
然后,调用父节点的removeChild 把自己删掉

// 拿到待删除节点:
var self = document.getElementById('to-be-removed'); // 拿到父节点:
var parent = self.parentElement; // 删除:
var removed = parent.removeChild(self); 
 removed === self; // true

当你遍历一个父节点的子节点并进行删除操作时
children 属性是一个只读属性,并且他在子节点变化时会实时更新

<div id="parent">    
    <p>First</p>    
    <p>Second</p> 
</div>

删除子节点:

var parent = document.getElementById('parent'); parent.removeChild(parent.children[0]);
parent.removeChild(parent.children[1]); // <-- 浏览器报错

在第一次删除以后,节点的下标变化了

正则表达式对象

JavaScript RegExp 对象
RegExp:是正则表达式(regular expression)的简写。

作用:

正则表达式描述了字符的模式对象。
当检索某个文本时,可以使用 一种模式 来描述要检索的内容。

简单的模式 可以是一个单独的字符。
复杂的模式 包括了更多的字符,并可用于解析、格式检查、替换等等。
可以规定字符串中的检索位置,以及要检索的字符类型,等等。

创建对象的格式:

  1. new一个出来

var patt=new RegExp(pattern,modifiers);

  1. / /的形式

var patt=/pattern/modifiers;

方括号:

用于查找某个范围内的字符

image-20210308204421075

元字符:

特殊含义的字符

image-20210308204455187

量词:

image-20210308204525929

对象方法:

image-20210308204618395

<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript">
        // 创建正则表达式,表示要求字符串中,是否包含字母e
        // 1. new一个:  var patt = new RegExp("e");
        // 2. var patt = /e/;  //也是创建正则表达式对象的形式
        
        // 表示要求字符串中,是否包含字母a或b或c
        // var patt = /[abc]/;
        
        // 表示要求字符串,是否包含小写字母
        // var patt = /[a-z]/;
        
        // 表示要求字符串,是否包含任意大写字母
        // var patt = /[A-Z]/;
        
        // 表示要求字符串,是否包含任意数字
        // var patt = /[0-9]/;
        
        // 表示要求字符串,是否包含字母,数字,下划线
        // var patt = /\w/;
        
        // 表示要求 字符串中是否包含至少一个a
        // var patt = /a+/;
        
        // 表示要求 字符串中是否 *包含* 零个 或 多个a
        // var patt = /a*/;
        
        // 表示要求 字符串是否包含一个或零个a
        // var patt = /a?/;
        
        // 表示要求 字符串是否包含连续三个a
        // var patt = /a{3}/;
        
        // 表示要求 字符串是否包 至少3个连续的a,最多5个连续的a
        // var patt = /a{3,5}/;
        
        // 表示要求 字符串是否包 至少3个连续的a,
        // var patt = /a{3,}/;
        
        // 表示要求 字符串必须以a结尾
        // var patt = /a$/;
        
        // 表示要求 字符串必须以a打头
        // var patt = /^a/;

        // 要求字符串中是否*包含* 至少3个连续的a
        // var patt = /a{3,5}/;
        
        // !!!要求字符串,从头到尾都必须完全匹配
        // var patt = /^a{3,5}$/;

        var patt = /^\w{5,12}$/;
        var str = "wzg168[[[";

        alert( patt.test(str) );


    </script>
</head>
<body>

</body>
</html>

Document 对象中的方法

  • document.getElementById(elementId)
    通过标签的 id属性查找标签 dom对象,elementId是标签的 id属性值

  • document.getElementsByName(elementName)
    通过标签的 name属性查找标签 dom对象,elementName标签的 name属性值

  • document.getElementsByTagName(tagname)
    通过标签名查找标签 dom对象。tagname是标签名

  • document.createElement( tagName)
    方法,通过给定的标签名,创建一个标签对象。tagName 是要创建的标签名

document 对象的三个查询方法
如果有 id 属性,优先使用 getElementById方法来进行查询
如果没有 id属性,则优先使用 getElementsByName方法来进行查询
如果 id属性和 name属性都没有最后再按标签名查 getElementsByTagName
以上三个方法,一定要 在页面加载完成之后执行 ,才能查询到标签对象。

getElementById 方法示例

image-20210310103602205

【当用户点击了较验按钮,要获取输出框中的内容。
然后验证其是否合法。
然后在输入框的右边提示是否合法。】

思路:

  • 通过创建标签对象,在span标签里设置id
  • 用创建好了的标签对象调用 innerHTML ,修改起始标签和结束标签中的内容
  • 可以是显示文字语句
  • 也可以是显示图片的内容(image标签)
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" >
        /*
        * 验证规则是:必须由字母,数字。下划线组成。并且长度是5到12位。
        * */
        function onclickFun() {
            // 当我们要操作一个标签的时候,一定要先获取这个标签对象。
            // 这里通过 id(username)获取的是输入框标签对象
            var usernameObj = document.getElementById("username");

            // [object HTMLInputElement] 它就是dom对象
            // 获取输入框中,输入的字符串
            var usernameText = usernameObj.value;

            // 如何 验证 字符串,符合某个规则 ,需要使用正则表达式技术
            var patt = /^\w{5,12}$/;


            var usernameSpanObj = document.getElementById("usernameSpan");
            // innerHTML 表示起始标签和结束标签中的内容
            // innerHTML 这个属性可读,可写

            /*
            *  test()方法用于测试某个字符串,是不是匹配我的规则 ,
            *  匹配就返回true。不匹配就返回false.
            * */
            if (patt.test(usernameText)) {
                // alert("用户名合法!");
                // usernameSpanObj.innerHTML = "用户名合法!";
                usernameSpanObj.innerHTML = "<img src=\"right.png\" width=\"18\" height=\"18\">";
            } else {
                // alert("用户名不合法!");
                // usernameSpanObj.innerHTML = "用户名不合法!";
                usernameSpanObj.innerHTML = "<img src=\"wrong.png\" width=\"18\" height=\"18\">";
            }
        }
    </script>

</head>
<body>
    用户名:<input type="text" id="username" value="wzg"/>
    <span id="usernameSpan" style="color:#ff0000;"></span>
    <button onclick="onclickFun()">较验</button>
</body>
</html>

getElementsByName 方法示例

image-20210310103525514

【在复选框当中设置全选、全不选、反选的按钮
并实现这些操作】

<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript">
        // 全选
        function checkAll() {
            // 让所有复选框都选中
            // document.getElementsByName();是根据 指定的name属性查询返回多个标签对象集合
            // 这个集合的操作跟数组 一样
            // 集合中每个元素都是dom对象
            // 这个集合中的元素顺序是他们在html页面中从上到下的顺序
            var hobbies = document.getElementsByName("hobby");
            // checked表示复选框的选中状态。如果选中是true,不选中是false
            // checked 这个属性可读,可写
            for (var i = 0; i < hobbies.length; i++){
                hobbies[i].checked = true;
            }
        }
        //全不选
        function checkNo() {

            var hobbies = document.getElementsByName("hobby");
            // checked表示复选框的选中状态。如果选中是true,不选中是false
            // checked 这个属性可读,可写
            for (var i = 0; i < hobbies.length; i++){
                hobbies[i].checked = false;
            }
        }
        // 反选
        function checkReverse() {
            var hobbies = document.getElementsByName("hobby");

            for (var i = 0; i < hobbies.length; i++) {
                hobbies[i].checked = !hobbies[i].checked;

                // if (hobbies[i].checked) {
                //     hobbies[i].checked = false;
                // }else {
                //     hobbies[i].checked = true;
                // }
            }


        }

    </script>
</head>
<body>
    兴趣爱好:
    <!--就是通过这里的name分的类 来创建的集合 hobbies -->
    <input type="checkbox" name="hobby" value="cpp" checked="checked">C++
    <input type="checkbox" name="hobby" value="java">Java
    <input type="checkbox" name="hobby" value="js">JavaScript
    <br/>
    
    <button onclick="checkAll()">全选</button>
    <button onclick="checkNo()">全不选</button>
    <button onclick="checkReverse()">反选</button>
</body>
</html>

getElementsByTagName 方法示例

这个例子中没有设置id 和 name
直接用标签名进行操作

<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript">

        // 全选
        function checkAll() {
            alert( document.getElementById("btn01") );
            // document.getElementsByTagName("input");
            // 是按照指定标签名来进行查询并返回集合
            // 这个集合的操作跟数组 一样
            // 集合中都是dom对象
            // 集合中元素顺序 是他们在html页面中从上到下的顺序。
            var inputs = document.getElementsByTagName("input");

            for (var i = 0; i < inputs.length; i++){
                inputs[i].checked = true;
            }
        }
    </script>
</head>
<body>

    <!--as -->
    兴趣爱好:
    <input type="checkbox" value="cpp" checked="checked">C++
    <input type="checkbox" value="java">Java
    <input type="checkbox" value="js">JavaScript
    <br/>
    <button onclick="checkAll()">全选</button>

</body>
</html>

createElement方法示例

使用 js代码来创建 html标签,并显示在页面上

因为可以将html里的一切都视为对象,所以可以通过创建对象的方式
并对当前对象赋子节点的方式操作

<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript">
        window.onload = function () {
            // 现在需要我们使用js代码来创建html标签,并显示在页面上
            // 标签的内容就是:<div>国哥,我爱你</div>
            var divObj = document.createElement("div"); // 在内存中 <div></div>

            var textNodeObj = document.createTextNode("国哥,我爱你"); // 有一个文本节点对象 #国哥,我爱你

            divObj.appendChild(textNodeObj); // <div>国哥,我爱你</div>

            // divObj.innerHTML = "国哥,我爱你"; // <div>国哥,我爱你</div>,但,还只是在内存中
            // 添加子元素
            document.body.appendChild(divObj);
        }
    </script>
</head>
<body>

</body>
</html>

节点的常用属性和方法

属性

  • childNodes
    获取当前节点的所有子节点
  • firstChild
    获取当前节点的第一个子节点
  • lastChild
    获取当前节点的最后一个子节点
  • parentNode
    获取当前节点的父节点
  • nextSibling
    获取当前节点的下一个节点
  • previousSibling
    获取当前节点的上一个节点
  • className
    用于获取或设置标签的 class 属性值
  • innerHTML
    表示获取/设置起始标签和结束标签中的内容
  • innerText
    表示获取/设置起始标签和结束标签中的文本

方法

通过具体的元素节点调用

getElementsByTagName()方法
获取当前节点的指定标签名孩子节点

appendChild( oChildNode )方法
可以添加一个子节点,oChildNode 是要添加的孩子节点

【DOM 查询练习】

<html>
<head>
<meta charset="UTF-8">
<title>dom查询</title>
<link rel="stylesheet" type="text/css" href="style/css.css" />
<script type="text/javascript">
	window.onload = function(){
		//1.查找#bj节点
		document.getElementById("btn01").onclick = function () {
			var bjObj = document.getElementById("bj");
			alert(bjObj.innerHTML);
		}
		//2.查找所有li节点
		var btn02Ele = document.getElementById("btn02");
		btn02Ele.onclick = function(){
			var lis = document.getElementsByTagName("li");
			alert(lis.length)
		};
		//3.查找name=gender的所有节点
		var btn03Ele = document.getElementById("btn03");
		btn03Ele.onclick = function(){
			var genders = document.getElementsByName("gender");
			alert(genders.length)
		};
		//4.查找#city下所有li节点
		var btn04Ele = document.getElementById("btn04");
		btn04Ele.onclick = function(){
			//1 获取id为city的节点
			//2 通过city节点.getElementsByTagName按标签名查子节点
			var lis = document.getElementById("city").getElementsByTagName("li");
			alert(lis.length)
		};
		//5.返回#city的所有子节点
		var btn05Ele = document.getElementById("btn05");
		btn05Ele.onclick = function(){
			//1 获取id为city的节点
			//2 通过city获取所有子节点
			alert(document.getElementById("city").childNodes.length);
		};
		//6.返回#phone的第一个子节点
		var btn06Ele = document.getElementById("btn06");
		btn06Ele.onclick = function(){
			// 查询id为phone的节点
			alert( document.getElementById("phone").firstChild.innerHTML );
		};
		//7.返回#bj的父节点
		var btn07Ele = document.getElementById("btn07");
		btn07Ele.onclick = function(){
			//1 查询id为bj的节点
			var bjObj = document.getElementById("bj");
			//2 bj节点获取父节点
			alert( bjObj.parentNode.innerHTML );
		};
		//8.返回#android的前一个兄弟节点
		var btn08Ele = document.getElementById("btn08");
		btn08Ele.onclick = function(){
			// 获取id为android的节点
			// 通过android节点获取前面兄弟节点
			alert( document.getElementById("android").previousSibling.innerHTML );
		};
		//9.读取#username的value属性值
		var btn09Ele = document.getElementById("btn09");
		btn09Ele.onclick = function(){
			alert(document.getElementById("username").value);
		};
		//10.设置#username的value属性值
		var btn10Ele = document.getElementById("btn10");
		btn10Ele.onclick = function(){
			document.getElementById("username").value = "国哥你真牛逼";
		};
		//11.返回#bj的文本值
		var btn11Ele = document.getElementById("btn11");
		btn11Ele.onclick = function(){
			alert(document.getElementById("city").innerHTML);
			// alert(document.getElementById("city").innerText);
		};
	};
</script>
</head>
<body>
<div id="total">
	<div class="inner">
		<p>
			你喜欢哪个城市?
		</p>

		<ul id="city">
			<li id="bj">北京</li>
			<li>上海</li>
			<li>东京</li>
			<li>首尔</li>
		</ul>

		<br>
		<br>

		<p>
			你喜欢哪款单机游戏?
		</p>

		<ul id="game">
			<li id="rl">红警</li>
			<li>实况</li>
			<li>极品飞车</li>
			<li>魔兽</li>
		</ul>

		<br />
		<br />

		<p>
			你手机的操作系统是?
		</p>

		<ul id="phone"><li>IOS</li><li id="android">Android</li><li>Windows Phone</li></ul>
	</div>

	<div class="inner">
		gender:
		<input type="radio" name="gender" value="male"/>
		Male
		<input type="radio" name="gender" value="female"/>
		Female
		<br>
		<br>
		name:
		<input type="text" name="name" id="username" value="abcde"/>
	</div>
</div>
<div id="btnList">
	<div><button id="btn01">查找#bj节点</button></div>
	<div><button id="btn02">查找所有li节点</button></div>
	<div><button id="btn03">查找name=gender的所有节点</button></div>
	<div><button id="btn04">查找#city下所有li节点</button></div>
	<div><button id="btn05">返回#city的所有子节点</button></div>
	<div><button id="btn06">返回#phone的第一个子节点</button></div>
	<div><button id="btn07">返回#bj的父节点</button></div>
	<div><button id="btn08">返回#android的前一个兄弟节点</button></div>
	<div><button id="btn09">返回#username的value属性值</button></div>
	<div><button id="btn10">设置#username的value属性值</button></div>
	<div><button id="btn11">返回#bj的文本值</button></div>
</div>
</body>
</html>

操作表单

获取值

获得用户输入的值

【input】

// <input type="text" id="email">
var input = document.getElementById('email'); input.value; // '用户输入的值'

这种方法可以应用于text、password、hidden和select

但是,对于单选框和复选框,value属性返回的永远是HTML预设的值
如果需要获取选中的选项,应该先用checked判断

// <label><input type="radio" name="weekday" id="monday" value="1"> Monday</label>
// <label><input type="radio" name="weekday" id="tuesday" value="2"> Tuesday</label>
var mon = document.getElementById('monday'); 
var tue = document.getElementById('tuesday'); 
mon.value; // '1'
tue.value; // '2'
mon.checked; // true或者false 
tue.checked; // true或者false

设置值

设置值和获取值类似,对于text、password、hidden和select 直接进行设置value

对于单选框和复选框,设置checked为 ture 或 false即可

// <input type="text" id="email">
var input = document.getElementById('email'); input.value = 'test@example.com'; // 文本框的内容已更新

提交表单

  1. 通过button的onclick事件
<form id="test-form">
   <input type="text" name="test">
   <button type="button" onclick="doSubmitForm()">Submit</button> 
</form>

<script>
function doSubmitForm() {
   var form = document.getElementById('test-form');    
    // 可以在此修改form的input...
    // 提交form:    
    form.submit(); 
} 
</script>
  1. 通过form的onsubmit事件
<form id="test-form" onsubmit="return checkForm()">   
    <input type="text" name="test">
    <button type="submit">Submit</button> 
</form>
<script>
function checkForm() {
   var form = document.getElementById('test-form');    
       // 可以在此修改form的input...
   // 继续下一步:    return true; 
   }
</script>

在form标签中,用return ture来告诉浏览器继续提交
如果return false 浏览器不会继续提交,所以这里一般用于用户输入错误

提高安全性:

很多登录表单希望用户输入用户名和口令,但是,安全考虑,提交表单时不传输明文口令,而是口令的MD5。

但是提交表单时,密码框中会变成32个*(MD5有32个字符)

利用hidden实现不改变用户的输入:

<script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"> </script>
<!-- HTML -->
<form id="login-form" method="post" onsubmit="return checkForm()">
    <input type="text" id="username" name="username">   
    <input type="password" id="input-password">
    <input type="hidden" id="md5-password" name="password">    
    <button type="submit">Submit</button>
</form> 

<script>
   function checkForm() {
       var input_pwd = document.getElementById('input-password');        
       var md5_pwd = document.getElementById('md5-password');
       // 把用户输入的明文变为MD5:
       md5_pwd.value = md5(input_pwd.value);        // 继续下一步:
       return true;  
    }
</script>
posted @ 2021-03-10 18:23  feifan666  阅读(148)  评论(0)    收藏  举报