JavaScrpt学习笔记

本文总结了JavaScript基础、函数对象、对象属性、构造函数、内存分布、this关键字、原型与继承、数组与函数应用、日期与Math函数、包装类、字符串操作、正则表达式、DOM操作、事件处理、拖拽与键盘事件、BOM与定时任务,以及JSON基础知识。
摘要由CSDN通过智能技术生成

JavaScript 遗忘知识点

第一站

JavaScript 基础知识点

一些基本函数及属性

  • alert("Hello"); 警告框
  • document.write("1111"); 向浏览器网页中书写内容
  • console.log("你好呀!"); 在控制台输出内容
  • prompt("请输入您的用户名:"); 接收用户输入
  • confirm() 操作之前,弹出对话框,让用户进行判断
  • typeof 用于查看变量的数据类型
  • toString 转换数据类型使之为 String 类型
  • String() 将传入的参数转换为字符串类型,返回值为 String 类型
  • Number() 将传入的参数转换为数字类型,返回值为 Number 类型
  • parseInt() 将传入的参数中有效的整数提取出来,返回值为 Number 类型
  • parseFloat() 将传入的参数中有效的浮点数数提取出来,返回值为 Number 类型
  • Boolean() 将传入的参数中转换为布尔值,返回值为 Boolean 类型(除了 0、NaN、空字符串、null 和 undefined 其余都是 true)
  • isNaN() 判断传入的参数是否为NaN,返回值为 Boolean 类型

进制类型及进制转换

  • 16进制数开头以:0x 表示
  • 8进制数开头以:0 表示
  • 2进制数开头以:0b 表示
  • parsetInt(“070”, 8),表示以8进制进行解析,以此类推

= 运算符

  • 当使用 ”==“ 来做相等运算时,如果两个值的类型不同,则会进行自动类型转换,将其转换为相同的类型,再进行比较
  • 当使用 ”===“ 来做相等运算时,不会对两个值进行类型转换,如果两个值的类型不同则直接返回 flase
  • 当使用 ”!==“ 来做相等运算时,不会对两个值进行类型转换,两个值得类型不一样时,则返回 true

第二站

函数

函数提高了复用性,能更加灵活的编写代码

普通函数

当传入的参数多于要接收的参数个数时,多余的部分将不会被接受;当传入的参数少于要接受的参数的个数时,未被赋值的参数将会为undefined

    // 创建一个带参数的函数
    function fun(name, age) {};
    // 将函数赋值给一个变量(使用时直接使用 变量() 的形式)
    var fun = function (var name, var age) {};

    // 此时 "男" 将不会被使用
    fun("小明", 18, "男");

立即执行函数

立即执行函数(将会在创建之后被立即执行,只执行一次)

    // 立即执行函数
    (function (name) {
        alert("Hello!");
    })("小红");

for in 函数

   // for (... in ...) 语法
   for (var i in obj) {
       // 此时输出为每个对象的属性名
       console.log(i);

       // 此时输出为 obj 对象中每个属性值
       console.log(obj[i]);
   }

对象

对象的基本语法
    // 创建对象
    var obj = new Object();
    
    // 使用对象字面量创建对象
    var obj = {};

    // 创建对象并为其设置属性
    var obj = {name: "小明", age: 18};

    // 向 obj 中添加一个 name 属性,并为其赋值
    obj.name = "小明";

    // 读取 obj 对象中的 name 属性
    console.log(obj.name);

    // 修改 obj 对象中的 name属性
    obj.name = "小红";

    // 删除 obj 中的 name 属性
    delete obj.name;
对象属性

如果使用特殊的属性名,不能采用 “.” 的形式,需要用到:对象名[”123“];在 [ ] 中也可以传递一个变量,变量的值将会取出,作为对象的属性名

    // 使用特殊的属性名或变量作为属性名,变量的值将会取出,作为对象的属性名
    obj["123"] = "小刚";
    console.log(obj["123"]);
    
    var a = "123";
    console.log(obj[a]);

对象属性的判断

通过 in 运算符,可以检查一个对象中是否含有指定的属性,返回类型为Boolean

    // 判断 name 属性是否在 obj 对象中
    console.log("name" in obj);

构造函数
  • 构造函数的执行流程:
    • 1、立刻创建一个新的对象
    • 2、将新建的对象设置为函数中的 this;在新建的对象中可以使用 this 来引用新建的对象
    • 3、逐行执行函数中的代码
    • 4、将新建的对象作为返回值返回
  • instanceof 用来说明一个对象是否为一个类的实例
    // 创建一个构造函数
    function Person(name, age, gender){
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    // per为Person的一个实例
    var per = new Person("张三", 25, "男");

    // 判断 per 是否为 Person 的实例
    console.log(per instanceof Person); // true

有关内存分布

  • JS中的变量都是保存在栈内存中
  • 基本数据类型的值,直接在栈内存中储存,值与值之间独立存在,修改一个变量,不会影响其他变量
  • 对象保存在堆内存中,每创建一个新对象,就会在堆内存中开辟一个新的空间,而变量保存的是对象的内存地址(对象的引用),当修改一个对象的属性时,另一个引用此对象的属性值也将会被改变
  • 当比较两个基本数据类型时,比较的时其值,比较引用数据类型时,比较的是内存地址

第三站

this 关键字

  • this 指向的是一个对象(函数执行的上下文),根据函数调用的方式不同,this 会指向不同的对象。
  • 以函数调用时,this 永远都是 window,
  • 以对象的方式调用时,this 就是调用方法的那个对象
  • 以构造函数的形式调用时,this 就是新创建的那个对象

原型:prototype

  • 我们所创建的每一个函数,解析器都会向函数中添加一个 prototype 属性
    • 这个属性对应着每一个对象,这个对象就是我们所谓的原型对象;当函数以构造函数的形式调用时,他所创建的对象中都会有一个隐含属性,指向该对象的原型对象,我们可以通过 __proto__ 来访问该属性

各个 __proto__ 之间的关系

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

    function Person(name, age) {
        this.name = name;
        this.age = age;
    }

    function Dog(name, age) {
        this.name = name;
        this.age = age;
    }

    var person1 = new Person("小红", 18);
    var person2 = new Person("小明", 18);
    var dog = new Dog("旺财", 18);

    // 判断 person1 的原型是否和 person2 的原型为同一个
    console.log(person1.__proto__ == person2.__proto__);    // true
    // 判断 dog 的原型是否和 person2 的原型为同一个
    console.log(dog.__proto__ == person2.__proto__);    // false

__proto__ 的使用

当我们访问一个对象的属性或方法时他会现在对象自身中寻找,如果有则使用,如果没有则回去原型对象中寻找,如果找到,则直接使用(最多原型只有两级,即只到原型的原型)

    function Person(name, age) {
        this.name = name;
        this.age = age;
    }

    Person.prototype.gender = "男";

    var person1 = new Person("小明", 18);
    
    console.log(person1.gender);    // 男
  • 当使用 in 检查某个对象中是否含有某个属性,当对象中没有,原型中有时,也会返回true
  • 当使用 in 检查某个对象中是否含有某个属性,当对象中没有,原型中没有时,会去原型的原型中寻找,如果有也会返回true
  • 可以使用另一个方法检验对象中是否有自己的属性(非原型内有):hasOwnProperty() 返回值,Boolean类型

第四站

数组

数组用于存储多个元素,存储的元素可以为任意类型

数组基本使用
    // 创建一个新数组
    var arr = new Array();

    // 使用字面量创建数组
    var arr = [];
    
    // 使用字面量创建数组,并为其赋值
    var arr = [1, 2, 3, 4, 5, 6, 7];
    
    // 检查一个对象是否为一个数组
    console.log(Array.isArray(arr));  // true

    // 每次向数组中最后一个元素添加新元素
    arr[0] = 0;
    arr[1] = 1;
    arr[2] = 2;
    arr[3] = 3;
        .    .
        .    .
        .    .
    arr[arr.length] = arr.length;
数组函数的应用

使用 length 方法可以查看数组的长度,同时也可以通过 length 方法来设置数组的长度.
如果修改的长度大于原长度,则多余部分会空出来
如果修改的长度小于原长度,则多出部分会空被删除

  • length 可以查看数组的长度
  • push() 向数组的末尾添加一个或多个元素,并返回数组的新长度,参数为要添加的元素(参数可以为多个)
  • unshift() 向数组的开头添加一个或多个元素,并返回数组的新长度,参数为要添加的元素(参数可以为多个)
  • arr.pop() 删除数组中最后一个元素,并返回删除的元素
  • arr.shift() 删除数组中第一个元素,并返回删除的元素
  • forEach() 用于遍历一个数组,参数为函数
  • slice() 从数组中截取指定元素(不会改变原素组)返回所截取到的数组
  • splice() 为数组中 删除/添加 指定位置的新元素(会改变原素组),并将删除的元素返回
  • concat() 可以连接两个或多个数组(不会改变原素组),并将新的数组返回
  • join() 将数组转换为字符串(不会改变原素组),并将转换后的结果返回
  • reverse() 反转数组中的元素(会改变原素组)
  • sort() 对数组中元素进行排序(会改变原素组),默认按照Unicode编码进行排序
  • isArray() 判断一个变量是否为数组
    // 向数组的末尾添加一个或多个元素,并返回数组的新长度,参数为要添加的元素
    arr.push("你好!", "Hello", "good morining");

    // 向数组的开始添加一个或多个元素,并返回数组的新长度,参数为要添加的元素
    arr.unshift("你好!", "Hello", "good morining");

    // 删除数组中最后一个元素,并返回删除的元素
    arr.pop();

    // 删除数组中第一个元素,并返回删除的元素
    arr.shift();

    // 遍历数组的方法
    arr.forEach(function (value, index, array) {
        /** 参数一为所要遍历的每个值,
         *  参数二为,数组的每个下标,
         *  参数三为该数组对象
         */
        concole.log("下标:" + index + ",值:" + value + ",正在遍历的数组:" + array);
    });
    // 另一种写法
    arr.forEach((value, index, array) => {
        concole.log("下标:" + index + ",值:" + value + ",正在遍历的数组:" + array);
    })

    /** 从数组中截取指定元素(不会改变原数组);
     *      参数一:开始截取位置的索引(包含开始索引),
     *      参数二:截取结束位置的索引(不包含结束索引);
     *   返回所截取到的数组
     *   当第二个参数没有时,会截取开始到之后所有的的数值
     *   如果传递一个负值,则会从后往前计算
     *      -1:表示最后一个元素,以此类推
     */
    arr.slice(1, 3);

    /** 删除数组中指定元素(会改变原素组),并将删除的元素返回
     *      参数一:
     *          开始位置的索引
     *      参数二:
     *          删除元素的个数
     *      第三个及以后参数:
     *          可以传递一些新的元素,这些元素将会自动插入到开始位置索引前面
     */
    arr.splice();
    
    // 可以连接两个或多个数组,并将新的数组返回(不会改变原素组)
    arr.concat(arr2, arr3, "小玉", "小强");

    // 将数组转换为字符串(不会改变原素组),并将转换后的结果返回,参数为元素之间的符号,默认为“,”
    arr = ["小明", "小红", "小刚"];
    var result = arr.join("-");
    console.log(result);    // "小明-小红-小刚"

    // 对数组中元素进行排序(会改变原素组),默认按照Unicode编码进行排序
    arr.sort();
    /**
     * 对于纯数字进行排序可能会产生错误的结果
     *  我们可以在sort中添加一个回调函数,指定排序的规则
     *  浏览器会根据回调函数的返回值来决定元素的顺序,
     *      如果返回值大于0则元素会交换位置,
     *      如果返回值小于0则元素位置不变,
     *      如果返回值等于0则元素位置也会不变
     *      a始终在b的前一个
     */
    arr.sort(function (a, b) {
        // 升序排列
        return a - b;

        // 降序排列
        return b - a;
    })
    

函数的方法

call() 和 apply()

  • 这两个方法都是函数对象的方法需要通过函数对象来调用
  • 当对函数调用call()和apply()都会调用函数执行
  • 在调用call()和apply()可以将一个对象指定为第一个参数
  • 此时这个对象将会成为函数执行时的this
  • call() 方法可以将实参在对象之后依次传递
  • apply() 方法需要将实参封装到一个数组中统一传递
    /**
     * -this的情况
     *  1、以函数形式调用时,this永远都是window
     *  2、以方法形式调用时,this是调用方法的对象
     *  4、使用call和apply调用时,this是指定的那个对象
     */
    function fun (a, b) {
        console.log("a = " + a = ", b = " + b); // a = 1, b = 2
    }

    fun.call(obj, 1, 2);
    fun.apply(obj, [1, 2]);

arguments 封装实参的对象

arguments是一个类数组对象,它可以通过索引来操作数据,也可以获取长度

  • 在调用函数时,我们所传递的实参都会在arguments中保存
  • arguments.length 可以用来获取实参的长度
  • 他里面还有一个属性叫callee
    • 这个属性对应一个函数对象,就是当前正在执行的函数的对象
    function fun(){
        console.log(arguments);
        console.log(arguments.length);
        console.log(arguments.callee);
    }

第五站

日期函数

    // 格式 月份/日期/年份 小时:分钟:秒
    var date3 = new Date("12/04/2020 11:10:30");

    // 获取当前是几日
    var d = date3.getDate();

    // 获取星期,会返回一个0-6的值;0 表示星期日,以此类推
    date.getDay();

    // 获取当前月份;会返回一个0-11的数 11表示12月,0表示1月,以此类推
    date.getMonth();

    // 获取年份
    date.getFullYear();

    // 获取当前的时间戳:即从1970年1月1日0时0分0秒到当前时间的毫秒数
    date.getTime();

    // 获取当前时间戳
    time = Date.now();

Math 函数

Math 和其他的对象不同,他不是一个构造函数.
它属于一个工具类,不用创建对象,它里面封装了数学运算的属性和方法

    // 数学中的Π
    Math.PI;

    // 绝对值
    Math.abs(-101);

    // 上舍: 向上取整
    Math.ceil(4.21);

    // 下舍:向下取整
    Math.floor(4.89);

    // 满5进一
    Math.round(1.4);
    Math.round(1.5);

    // 生成0-1之间的随机数
    Math.random();

    // 生成x-y之间的随机数:
    Math.round(Math.random() * (y - x) + x);

    // 取最大值
    Math.max(10, 30, 1.4, 39, 29, 20, 39);
    // 取最小值
    Math.min(10, 30, 1.4, 39, 29, 20, 39);

    // 返回2的3次方
    Math.pow(2, 3);

    // 16的开平方
    Math.sqrt(16);

有关包装类

将一些数据类型转换为类的形式,使用 new + 数据类型的形式

    // 创建一个包装类
    var num = new Number(3);
    var num2 = new Number(3);
    var str = new String("asf");
    var bool = new Boolean(true);
    var bool2 = true;

    console.log(num == num2);   // false,其比较的内存地址

    console.log(bool == bool2); // 未true,因为其做了类型转换

    console.log(bool === bool2);    // false,其类型不一样

字符串的方法

  • length 用于获取字符串的长度
  • charAt() 返回字符串中指定位置的字符
  • charCodeAt() 返回字符串中指定位置的编码
  • fromCharCode() 根据字符编码获取字符
  • concat() 连接字符数组,和加号的效果一样
  • indexOf() 返回所在字符的第一次出现的下标, 找不到则返回-1
  • lastIndexOf() 指定从末尾位置开始查找
  • slice() 截取字符串
  • substring() 截取字符串,和slice()类似
  • substr() 截取字符串
  • splice() 拆分字符串
  • toUpperCase() 将字符串全部变为大写
  • toLowerCase() 将字符串全部变为小写
    var str = "niahao ya!";

    // 可以获取字符串的长度s
    console.log(str.length);    // 10

    // 可以返回字符串中指定位置的字符
    var n = str.charAt(3);
    console.log(n); // h

    // 获去指定位置的编码
    console.log(str.charCodeAt(3)); // 104 (h的ASCII编码)

    // 可以根据字符编码获取字符
    console.log(String.fromCharCode(104));   // h

    // 连接字符数组,和加号的效果一样
    var str1 = str.concat("niaho!");

    // 返回所在字符的第一次出现的下标, 找不到则返回-1
    str1 = str.indexOf("f");

    // 指定开始查找的位置
    str1 = str.indexOf("a", 1);

    // 也可指定从某个位置开始查找
    str1 = str.lastIndexOf("a");

    /** slice()可以截取字符串
    *   0未开始位置包括0所走字符串,
    *   2代表结束位置不包含2所在位置
    */
    str1 = str.slice(0, 2);

    // 表示1之后的都要
    str1 = str.slice(1);

    // 从1开始截取,到最后一个位置结束,-1表示最后一个位置,-2 表示倒数第二个,以此递归
    str1 = str.slice(1, -1);

    /** subString()和slice()类似
    *   1表示开始位置,
    *   3表示结束位置的索引, 这个方法不能接受负数,如果传递了一个负数则默认为0
    *   可以自动调整参数位置,如果第一个参数小于第二个,则进行自动交换
    */
    str1 = str.substring(1, 3);

    // 1为开始位置的索引,3为截取的长度
    str1 = str.substr(1, 3);

    // 该表达式表示用,拆分该字符串,如果传递一个空串,则每个字符都是一个整体
    str = "sdf,sfs,dfgffg,ffgggfd";
    str1 = str.split(",");
    console.log(str1);  // ["sdf", "sfs", "dfgffg", "ffgggfd"]
    console.log(typeof str1);   // object
    console.log(Array.isArray(str1));   // true

    // 变大写
    var str3 = str1.toUpperCase();

    // 转换为小写
    str1 = str.toLowerCase();

第六站

正则表达式

正则表达式用于适配字符串,通过正则表达式,可以对字符串进行一系列操作

正则表达式的创建
  • var 变量 = new RegExp(“正则表达式”, “匹配模式”);
  • 匹配模式可以为:
    • i:表示忽略大小写
    • g:全局匹配模式
  • 使用字面量创建正则表达式,语法:(不用加引号)
    • var 变量 = /正则表法式/匹配模式;
    // 创建正则表达式对象
    var reg = new RegExp("a");   // 区分大小写
    var reg = /ads/i;   // 不区分大小写
正则表达式的匹配
  • test() 用于测试是否于正则表达式匹配
    // 测试是否符合规则
    var reg = a;
    var result = reg.test("a");
    console.log(result);    // true

    result = reg.test("abcd");
    console.log(result);    // true

    reg = new RegExp("a", "i");
    result = reg.test("Agjsdkl");
    console.log(result);    // true

    reg = new RegExp("a", "g");
    result = reg.test("Adgkljh");
    console.log(result);    // false

正则表达式匹配规则
  • |[ ]
    • 表示或
  • -
    • 表示介于之间
  • [^a]
    • 表示非a即不出现a
  • /^a/
    • 表示以a开头
  • { }
    • 表示出现的次数
  • +
    • 表示至少为一个
  • *
    • 表示0个或多个
  • ?
    • 表示0个或一个
  • $
    • 表示以结尾
  • \w
    • 任意字母、数字、_ == [A-z0-9_]
  • \W
    • 除了字母、数字、_ == [^A-z0-9_]
  • \d
    • 任意数字 == [0-9]
  • \D
    • 除了数字 == [^0-9]
  • \s
    • 空格
  • \S
    • 除了空格
  • \b
    • 单词边界
  • \B
    • 除了单词边界
    // 表示a或者b或者c
    reg = /a|b|c/i;
    result = reg.test("aljkljk");
    console.log(result);    // true

    // 中括号也是或的意识 /[ab]/ == /a|b/
    reg = /[ab]/;
    result = reg.test("gfdsgddfg");
    console.log(result);    // false

    // 表示a-z之间的包含a和z(任意小写字母)
    reg = /[a-z]/;
    result = reg.test("adadsjfgz");
    console.log(result);    // true

    // 表示任意的大写字母
    reg = /[A-Z]/;
    result = reg.test("ASFDsdfsf");
    console.log(result);    // true

    // 表示任意字母
    reg = /[A-z]/;

    // 表示任意数字
    reg = /[0-9]/;

    // /a[bde]c/ == /abc|adc|aec/
    reg = /a[bde]c/;
    result = reg.test("abc");
    console.log(result);    // true

    /**
     * [^ab] 表示除了ab
     */
    reg = /[^ab]/;
    result = reg.test("abc");
    console.log(result);    // true (因为含有 c ,即除了ab以外的元素)

    // 表示a连续出现3次, 量词只对它前面的一个字符起作用
    var reg = /ba{3}/;
    var result = reg.test("adsdbaaaasdfsfaaa");
    console.log(result);    // true

    // 表示为一组,且ab连续出现3次
    reg = /(ab){3}/;
    result = reg.test("asasabababdfs");
    console.log(result);    // true

    // 表示b出现1次到3次
    reg = /ab{1,3}c/;
    result = reg.test("adsfaabbc");
    console.log(result);    // true

    // 表示b出现3次以上
    reg = /ab{3,}c/;
    result = reg.test("asdabbbbbbbc");
    console.log(result);    // true

    // 表示b至少一个
    reg = /ab+c/;
    result = reg.test("abbbbbc");
    console.log(result);    //true

    // *表示0个或多个
    reg = /ab*c/;
    result = reg.test("ac");
    console.log(result);    //true

    // ?表示0个或一个
    reg = /ab?c/;
    result = reg.test("abbc");
    console.log(result);    // false

    /**
     * 检查是否以a开头
     *  /^a/
     * [^a]:表示非a即不出现a
     * 检查是否以a结尾
     *  /a$/
     */
    reg = /^a/;
    result = reg.test("adfs");
    console.log(result);    // true

    reg = /a$/;
    result = reg.test("dsfa");
    console.log(result);    // true

    // 表示只含有a
    reg = /^a$/;
    result = reg.test("a");
    console.log(result);    // true

    /**
     * 检查一个字符中是否含有 ”.“
     * “.”:表示任意字符
     * 正则表达式中使用\表示转义字符
     * . 即为\.
     * \\ 表示 \
     */
    reg = /./;
    result = reg.test("asdfafs");
    console.log(result);    // true

    reg = /\./;
    result = reg.test("asdf");
    console.log(result);    //false

    // 注意:在使用构造函数时,由于它的参数是一个字符串,而 \ 是字符串中的转义字符
    //    如果使用  \则需使用 \\ 来表示
    reg = new RegExp("\\.");
    console.log(reg);   // \.

    reg = /child/;
    result = reg.test("hellochildone");
    console.log(result);    // true

    reg = /\bchild\b/;
    result = reg.test("hellochildone");
    console.log(result);    // false

    result = reg.test("hello child one");
    console.log(result);    // true

正则表达式的使用
  • match() 可以根据正则表达式,从一个字符中将符合条件的内容提取出来
    // 表示根据字母拆分字符串(默认为全局的,不用添加g)
    var str = "1a2cx4c5g546gf";
    var result = str.split(/[A-z]/);
    console.log(result);    // 1,2,4,5,546

    // 查询world所在的第一次出现的位置, 找不到则返回-1(即使设置全局也没用)
    str = "hello world hello wc";
    result = str.search("world");
    console.log(result);    //6

    str = "adf adf adc cea ajc";
    result = str.search(/a[dj]c/);
    console.log(result);    // 8

    /**
     * match()可以根据正则表达式,从一个字符中将符合条件的内容提取出来
     * 默认情况下match只会寻找一个符合条件的,找到之后就停止
     *      我们可以设置正则表达式为全局匹配模式
     *      可以为一个正则表达式设置多个匹配模式,且顺序无所谓
     */
    str = "1a2b3c4d5e6f";
    // 提取任意一个字母
    result = str.match(/[A-z]/);
    console.log(result);    // a

    // 搜索所有符合条件的, 返回一个数组
    result = str.match(/[A-z]/g);
    console.log(Array.isArray(result)); // true
    console.log(result);    // a,b,c,d,e,f

    /**
     * replace()
     *  可以进行替换操作
     *  参数:
     *      第一个:被替换的内容
     *      第二个:新的内容
     */
    str = "asfdaf2w23sdf23dsf";
    result = str.replace(/[0-9]/g, "-");
    console.log(result);    // asfdaf-w--sdf--dsf

    // 接收用户输入
    var str = prompt("请输入您的用户名:");
    // 替换用户输入的空格
    result = str.replace(/\s/g, "");

    // 不去除中间的空格,去除前面的空格
    result = str.replace(/^\s*/g, "");

    // 去除结尾的空格
    result = str.replace(/\s*$/, "");

    // 去除开头和结尾的空格
    result = str.replace(/^\s*|\s*$/g, "");

    // 判断是否为合法的手机号
    reg = /^1[3-9][0-9]{9}$/;
    result = reg.test("13300791520");
    console.log(result);    // true

    /**
     * 电子邮箱:
     *      hello.nihao@abc.com.cn
     */
    var reg = /^[A-z]*\.[A-z]{1,9}@[A-z]{1,5}\.[A-z]{1,5}\.[A-z]{1,5}$/;

    reg = /^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/
    var result = reg.test("sasdf@fas.com.cm");
    console.log(result);    // true

第七站

DOM(Document Object Model)

节点的属性

节点nodeNamenodeTypenodeValue
文档节点#document9null
元素节点标签名1null
属性节点属性名2属性值
文本节点#text3文本内容
通过DOM获取元素

浏览器已经为我们提供文档节点对象这个对象是window属性可以在页面中直接使用,文档节点代表整个页面

  • document.documentElement 获取html根标签
  • document.body 获取body标签
  • getElementsByTagName() 通过标签名获取元素
  • getElementsByClassName() 通过 class 属性值获取元素
  • getElementById() 通过 id 属性值获取元素
  • document.querySelector() 根据元素属性获取标签,只能获取一个满足条件的元素
  • document.querySelectorAll() 根据元素属性获取标签,可以查询多个满足条件的,并返回多个满足条件的结果

document.querySelector()
需要一个选择器的字符串作为参数,可以根据一个 CSS 选择器来查询一个元素节点对象
虽然IE8中没有 document.getElementbyClassName() 方法,但有document.querySelector() 方法,但该方法只会返回唯一的一个元素
document.querySelectorAll() 可以查询多个满足条件的,并返回多个满足条件的结果

    // 获取 id="btn" 对象
    var btn = document.getElementById("btn");

    // 修改btn的名字
    var inner = btn.innerHTML;
    btn.innerHTML = "修改后的按钮";

    // 获取body标签的方法
    var body = document.getElementsByTagName("body")[0];
    // 另一种
    body = document.body;

    // 获取html根标签
    var html = document.documentElement;

    // 获取页面中所有的div
    var divs = document.getElementsByTagName("div");

    // 获取所有标签
    var all = document.all;
    all = document.getElementsByTagName("*");

    // 获取元素的class属性值,查询一组元素节点对象,不支持IE8及以下的版本
    var box = document.getElementsByClassName("box");

    // 获取对应属性的div标签
    var div = document.querySelector(".box div");

    // 查询一个属性为 test1 的标签
    divs = document.querySelector(".test1")

    // 查询所有属性为 test1 的标签
    divs = document.querySelectorAll(".test1");

由已知标签获取其余标签

  • childNodes 属性会获取包含文本在内节点在内的所有子节点(包含文本节点)
  • children 属性可以获取当前元素的所有子元素(不包含文本节点)
  • firstChild 属性可以获取当前元素的第一个子节点 (包括空白文本)
  • firstElementChild 属性可以获取当前元素的第一个子元素 (不包括空白文本)
  • lastChild 属性可以获取当前元素的最后一个子节点 (包括空白文本)
  • parentNode 属性可以获取当前元素父节点 (不包括空白文本)
  • previousSibling 属性可以获取当前元素前一个兄弟节点 (包括空白文本)
  • previousElementSibling 属性可以获取当前元素前一个兄弟元素 (不包括空白文本)
  • nextSibling 属性可以获取当前元素后一个兄弟节点 (包括空白文本)
  • innerText 属性可以获取当前元素的文本域
    // 查找 class 为 box 下的所有 li 节点
    var box = document.getElementsByClassName("box");
    box.getElementsByTagName("li");

    // 查找 class 为 box 下的所有子节点
    var box = document.getElementsByClassName("box");
    
    // 属性不需加括号
    box.childNodes;
    box.children;
通过元素对象对元素进行一系列操作
  • document.createElement() 可用于创建一个元素节点对象
  • document.createTextNode() 可用于创建一个文本节点对象
  • appendChild() 可用于将一个元素节点添加到另一个元素节点下
  • insertBefore() 会在指定的节点前插入新的子节点
  • replaceChild() 可以用指定的子节点替换已有的子节点
  • removeChild() 删除指定的节点
    // 由于 class 是 js 的保留字,读取元素节点的 class 属性时需要将 class 换成 className
    var li = document.getElementsByTagName("li")[0];
    consoloe.log(li.className);

    // 选框的状态
    var input_checkbox = document.getElementsByClassName("checkbox")[0];
    // 选择框设置为选中状态
    input_checkbox.checked = true;
    // 选择框设置为非选中状态
    input_checkbox.checked = false;

    /**
     * document.createElement()
     *  可用于创建一个元素节点对象,他需要一个标签名作为参数,将会根据该标签名创建元素节点对象,并将创建好的元素节点对象作为返回值返回
     */
    var li = document.createElement("li");
    console.log(li);

    // 创建文本节点元素
    var text = document.createTextNode("新创建的节点");
    // 将文本节点添加到新建的元素节点下
    li.appendChild(text);

    /** insertBefore()会在指定的节点前插入新的子节点
     *  语法:
     *      父节点.insertBefore(新节点, 旧节点);
    **/ 
   // 将li节点添加到p节点前
    ul.insertBefore(li, p);

    /**
     * replaceChild()
     *  可以用指定的子节点替换已有的子节点
     *  语法:
     *      父节点.replaceChild(新节点, 旧节点);
     */
    ul.replaceChild(li, p);

    /** 删除子节点
     * removeChild()
     *  语法:
     *      父节点.removeChild(子节点);
     */
    ul.removeChild(p);

    // 另一种删除方式(删除p节点)
    p.parentNode.removeChild(p);

    // 在原来的基础上新加一个节点
    ul = document.getElementsByTagName("ul")[0];

    ul.innerHTML += "<li>新创建的节点</li>"

    /**
     * 推荐的方法
     *      两种结合添加子元素的方法
     */
    li =  document.getElementsByTagName("li")[0];
    // 向li中设置文本
    li.innerHTML = "新创建的节点";
    // 将li添加到ul中
    ul.appendChild(li);

    /**
     * 操作之前,弹出对话框,让用户判断是否要删除
     *  confirm()
     *  返回值为true或者false
     *
     * 获取文本框中的文字用该对象.value()
     **/
    var text = confirm("确认要删除?");
    
    // 获取输入框中的值
    var input = document.getElementsByTagName("input")[0];
    input.value;

    // 当超链接点击后会发生跳转现象。如果想要避免这种默认行为,可以采用如下方法
    var a = document.getElementsByTagName("a");
    a.onclick = function () {
        
        // 代码区···

        return false;
    }
通过 JS 对样式进行操作
  • 在网页加载完后执行,需要将 JavaScript 代码写入到 window.onload = function( ) { } 函数里面

    • onload 函数将会在整个页面加载完后才执行
  • 如果 CSS 的样式中有 “-” 则需要将这种样式名修改为驼峰命名法,例: background-color --> backgroundColor

    /** 通过 js 修改元素的样式
     * 语法:
     *      元素.style.样式名 = 值
     */
    var box = document.getElementsByClassName("box");
    box.style.backgroundColor = "red";
  • 通过style属性设置和读取的都是内联样式,无法读取样式表中的样式而内联样式有较高的优先级,所以通过 JS 修改的样式往往会立即显示
    • 但是如果在样式中写了 !important ,则此时样式会有最高的优先级
    • 即使通过 JS 也不能覆盖改样式,此时会导致 JS 修改样式失效
    • 所以尽量不要为样式添加 !important
    /** 读取元素的样式
     * 语法:
     *  元素.style.样式名
     */
    box.style.width;
  • currentStyle 获取当前元素显示的样式
    • 如果当前元素没有设置该样式,则获取它的默认值
    • 该语法只有IE浏览器支持,别的浏览器不支持
  • getComputedStyle() 获取当前元素显示的样式,这个方法是window的方法(在其他浏览器中可以使用)需要两个参数:
    • 第一个:要获取样式的元素
    • 第二个:可以传递一个为元素,一般都传递null
    • 该方法返回一个对象,对象中封装了该元素对应的样式可以通过:
      • 对象 . 样式名 来获取
    • 如果获取的样式没有设置,则会获取真实的值,而不是默认值
    • 该方法不支持IE8及以下
  • 通过 currentStyle 和 getComputedStyle() 读取到的样式都是只读的,不能修改
    • 如果要修改,必须通过style属性
    // 获取元素当前显示的样式
    alert(box1.currentStyle.width);

    // 获取当前元素显示的样式
    var style = getComputedStyle(box1, null);

    // 调用下面的函数
    alert(getStyle(box1, "width"));

一个通用函数

    /**
     * 定义一个函数,用来获取指定元素的当前的样式
     * 参数:
     *      obj:要获取样式的元素
     *      name:要获取的样式名
     */
    function getStyle(obj, name){
        // 正常浏览器的方式
        // return getComputedStyle(obj, null)[name];

        // IE8的方式
        // return obj.currentStyle[name];

        if (window.getComputedStyle){
            return getComputedStyle(obj, null)[name];
        } else {
            return obj.currentStyle[name];
        }

        // 改进
        return window.getComputedStyle?getComputedStyle(obj, null)[name]:obj.currentStyle[name];
    }

元素的固有属性

  • clientWidth 获取元素的可见宽度
  • clientHeight 获取元素的可见高度
  • offsetWidth 获取元素的整个宽度包括内容区
  • offsetHeight 获取元素的整个高度包括内容区
  • offsetParent 获取当前元素的定位父元素
  • offsetLeft 当前元素相对于其定位的父元素的水平偏移量
  • offsetTop 当前元素相对于其定位父元素的垂直偏移量
  • scrollHeight 获取整个滚动区域的高度
  • scrollWidth 获取整个滚动区域的宽度
    // 可见宽度和可见高度,不带有px,返回的是值(数值数字)可以直接进行计算, 包括内容区和内边距,这些属性都是只读的
    box1.clientHeight;
    box1.clientWidth;

    // 获取元素的整个大小包括内容区和内边距和外边距
    box1.offsetWidth;
    box1.offsetHeight;

    /**
     * offsetParent
     *  可以用来获取当前元素的定位父元素
     *  会获取到离最近的开启了定位的元素当前元素
     *  如果所有的祖先元素都没有开启定位则返回body
     */
    var op = box1.offsetParent;
    alert(op.id);

    /**
     * offsetLeft
     *  当前元素相对于其定位的父元素的水平偏移量
     * offsetTop
     *  当前元素相对于其定位父元素的垂直偏移量
     */
    box1.offsetLeft;
    box1.offsetTop;

    // 获取整个滚动区域的高度和宽度
    box4.scrollHeight;
    box4.scrollWidth;

    // 获取滚动条移动的距离
    box4.offsetTop;
    box4.offsetWidth;

滚动条

  • document.onscroll 滚动条滚动时会触发此函数
    /** 当满足scrollHeight - scrollTop == clientHeight时说明垂直滚公条已到底
     *  当满足scrollWidth -  scrollWidth == clientWidth时说明水平滚动条已到底0
     **/

    var inputs  = document.getElementsByTagName("input");

    // 当滚动条滚动时会触发此函数 onscroll
    document.onscroll = function() {}

    /** 设置input可用
     * disable属性可以设置一个元素是否可用
     *  如果设置true则该元素禁用
     *  如果设置false则该元素可用
     */
    inputs[0].disabled = false;

事件对象

  • 事件对象
    • 当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进响应函数
    • 在事件对象中封装了当前事件相关的一切信息,比如:鼠标的坐标、键盘那个按键被按下、鼠标滚轮移动的方向…
    • 在IE8中,响应函数被触发时,浏览器不会传递事件对象
    • 在IE8及以下浏览器中,是将事件作为window对象的属性来保存的
属性描述
onclick当用户点击某个对象时调用的事件句柄
oncontextmenu在用户点击鼠标右键打开上下文菜单时触发
ondblclick当用户双击某个对象时调用的事件句柄
onmousedown鼠标按钮被按下
onmouseenter当鼠标指针移动到元素上时触发
onmouseleave当鼠标指针移出元素时触发
onmousemove鼠标移动时触发
onmouseover鼠标移到某元素之上
onmouseout鼠标从某元素移开
onmouseup鼠标按键被松开
    area.onmousemove = function (event){

        // 解决兼容性问题
        if (!event){
            event = window.event;
        }
        // 改进   解决事件兼容性问题
        event = event || window.event;

        // IE8中的使用方法
        var x = event.clientX;
        var y = event.clientY;

        // 火狐浏览器中直接是event : event.clientX;
    }

一个示例

    // 使 box1 可以跟着鼠标进行移动
    var box1 = document.getElementById("box1");

    document.onmousemove = function(event){
        // 提高兼容性
        var scrollX = document.body.scrollTop || document.documentElement.scrollTop;
        var scrollY = document.body.scrollLeft || document.documentElement.scrollLeft;

        /** 获取鼠标位置 event.pageX、event.pageY
         *  鼠标相对于整个页面的坐标
         *  IE8及以下浏览器不支持,如果需要进行兼容IE8则,此方法不能用
         * 改进:将 box1 往下挪
         */
        var x = event.clientX + scrollY;
        var y = event.clientY + scrollX;

        // 设置box1的坐标
        box1.style.left = x + "px";
        box1.style.top = y + "px";

        /** chrome认为滚动条是 body 的可以通过 body.scrollTop 来获取:
         *      document.body.scrollTop;
         * 火狐等浏览器认为滚动条是 html 的可以通过 html.scrollTop 来获取:
         *      document.documentElement.scrollTop;
         */

        var st = document.body.scrollTop || document.documentElement.scrollTop;
    };

冒泡(Bubble)

指的就是事件的向上传达,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发;
在开发中大部分情况冒泡都是有效的,如果不希望发生事件冒泡,可以通过事件对象来取消冒泡

一个示例

box1 与 box 和 body 的关系为:body 为 box 的父元素,box 为 box1 的父元素

    // 为box设置单击响应
    var box = document.getElementById("box");

    box.onclick = function (event){
        // 提高兼容性
        event = event || window.event;
        alert("我是span的单击相应函数");

        // 可以将事件的cancelBubble设置为true,即可取消冒泡
        event.cancelBubble = true;
    };

    // 为box1设置单击相应
    var box1 = document.getElementById("box1");
    box1.onclick = function (event){
        event = event || window.event;

        alert("我是div的单击相应函数");

        event.cancelBubble = true;
    };

    // 为body绑定一个单及相应函数
    var body = document.getElementsByTagName("body")[0];
    body.onclick = function (){
        alert("我是body的单击响应函数");
    };

委派

事件的委派指将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件出发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件事件;委派利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能

一个示例

    ul.onclick = function (event){
        event = event || window.event;
        // 如果触发事件的对象是我们期望的,则执行,否则不执行

        /**
         * target
         *  event中的target表示的是触发事件的对象
         */
        if (event.target.className == "link"){
            alert("我是一个超链接");
        }
    };

事件的绑定

使用 对象.事件 = 函数 的形式绑定响应函数。它只能同时为一个函数的一个事件绑定一个响应函数,不能绑定多个,如果绑定了多个,则后面的会覆盖前面的

  • 添加事件的另一种形式:
    • addEventListener()
    • 通过这个方法也可以为元素绑定响应函数
    • 参数:
      • 1、时间的字符串,不要on
      • 2、回调函数,当事件触发时该函数会被调用
      • 3、是否在捕获阶段出发,需要一个布尔值,一般都传false
    • 在IE8及以下不支持
    btn.addEventListener("click", function (){
        alert(1);
    }, false);
    btn.addEventListener("click", function (){
        alert(2);
    }, false);
  • IE8中特有的方法
    • attachEvent()
    • 参数(就两个):
      • 1、时间的字符串,要on
      • 2、回调函数,当事件触发时该函数会被调用
    • 这个方法也可以同时为一个时间绑定多个处理函数
    • 不同的是它是后绑定先执行,执行顺序和addEventListener()相反
    bind(btn1, "click", function (){
        alert("hello");
    })

addEventListener() 中的 this 是绑定事件的对象,attachEvent() 中的 this 是 window 。需要统一两个方法的 this

一个通用函数

    /** 定义一个函数,用来为指定元素绑定响应函数
     * 参数:
     *      obj:要绑定事件的对象
     *      eventStr:时间的字符串
     *      callback: 回调函数
     */
    function bind(obj, eventStr, callback){

        if (obj.addEventListener){
            // 大部分浏览器兼容的方式
            obj.addEventListener(eventStr, callback, false);
        } else {
            /** IE8及以下兼容的方式
             * this是谁由调用方式决定
             * callback.call(obj)
             */
            obj.attachEvent("on" + eventStr, function () {
                // 在匿名函数中调用回调函数
                callback.call(obj);
            });
        }
    };

第八站

拖拽事件

一个拖拽事件的函数

  • 对鼠标相关事件(鼠标按下)进行捕获,当调用一个元素的setCapture() 方法后,这个元素会把下一次所有鼠标按下相关事件捕获到自身上
    • setCapture()方法只有IE支持,但在火狐中调用时不会报错而如果使用chrome时会报错
  • 别的浏览器支持的属性:setCapture
  • 当鼠标松开时,取消对事件的捕获 obj.releaseCapture();
    • 只有 IE8 支持
  • 别的浏览器支持的属性:obj.releaseCapture
    /**
     * 提取一个专门设置拖拽的函数
     *  参数:开启拖拽的元素
     */
    function drag (obj){
        obj.onmousedown = function(event){
            /*if(box1.setCapture){
                box1.setCapture();
            }*/
            // 改进
            obj.setCapture && obj.setCapture();

            // 求出div的偏移量 鼠标.clientX - 元素.offsetLeft
            var mx = event.clientX - obj.offsetLeft;
            // 求出div的偏移量 鼠标.clientY - 元素.offsetTop
            var my = event.clientY - obj.offsetTop;

            document.onmousemove = function (event){
                event = event || window.event;

                var x = event.clientX - mx;
                var y = event.clientY - my;

                obj.style.left = x + "px";
                obj.style.top = y + "px";
            };

            document.onmouseup = function (){
                // 取消document的onmousemove事件
                document.onmousemove = null;
                // 取消document的onmouseup事件
                document.onmouseup = null;

                // 当鼠标松开时,取消对事件的捕获
                obj.releaseCapture && obj.releaseCapture();

                /**
                 * 当我们拖拽一个网页中的内容时浏览器会默认去搜索引擎中搜索内容
                 *  此时会导致我们的拖拽功能异常
                 *  如果不希望发生这个行为,则可以通过return false;取消
                 *
                 * 这种办法对IE8不起作用
                 */
                return false;
            };
        };
    }

鼠标的滚轮事件

  • onmousewheel鼠标滚轮滚动的事件,会在滚轮滚动时触发
    • 但火狐不支持该属性
  • 在火狐中需要使用 DOMMouseScroll 来绑定滚动事件
    • 该事件需要通过 addEventListener() 方法来绑定

一个示例

    /**
     * 当鼠标滚轮向下滚动时,box1变长
     *  当滚轮向上移动时,box1变短
     */
    var box1 = document.getElementById("box1");

    // 为box1绑定一个鼠标滚动事件
    box1.onmousewheel = function (event){
        event = event || window.event;
        // 判断滚轮滚动的方向
        // 向上滚动是150,向下滚是-150,我们是看正负,不看大小
        // wheelDelta在火狐中不支持
        // 在火狐中使用event.detail来获取方向

        if(event.detail < 0 || event.wheelDelta > 0){
            // 向上滚动
            box1.style.height = box1.clientHeight - 10 + "px";
        } else {
            // 向下滚动
            box1.style.height = box1.clientHeight + 10 + "px";
        }

        /**
         * 使用addEventListener()方法绑定响应函数,取消默认行为时不能使用return false;
         * 需要使用event来取消默认行为
         **/
        event.preventDefault && event.preventDefault();

        /**
         * 当滚轮滚动时,如果浏览器有滚动条,滚动条会随之滚动
         *  这是浏览的默认行为,如果不希望发生,则可以取消这个默认行为
         */
        return false;
    };

    bind(box1, "DOMMouseScroll", box1.onmousewheel);

    function bind(obj, eventStr, callback){
        if (obj.addEventListener){
            odj.addEventListener(eventStr, callback, false);
        } else {
            obj.attachEvent("on" + eventStr, function(){
                callback.call(obj);
            });
        }
    }

键盘事件

  • 键盘事件

    • onkeyup
    • onkeydown
      • 如果按着某个按键不松手,则事件会被一直触发
      • 当onkeydown连续触发时,第一次和第二次之间会间隔稍微长一点,其他的会非常的快
        • 这种设计是为了防止误操作
        • 在文本框中输入内容,属于onkeydowm的默认行为
        • 如果在onkeydown中取消了默认行为,则输入的内容不会出现在文本框中
    • 键盘事件一般都会绑定给能获取焦点的对象,或者是document
  • 可以通过keyCode来获取案件的编码

    • 通过它可以判断那个按键被按下
    • 除了keyCode,事件对象中话提供了几个属性
      • altKey
      • ctrlKey
      • shiftKey
    • 这三个用来判断其对应的键是否被按下
    • 如果按下则返回true,否则返回false
    var input = document.getElementsByTagName("input")[0];

    input.onkeydown = function (event){
        event = event || window.event;
        console.log(event.keyCode);

        // 使文本框不能输入数字; 0是48,9是57
        if (event.keyCode >= 48 && event.keyCode <= 57){
            alert("输入有误,请重新输入");

            // 取消默认行为,输入框输入不进字符
            return false;
        }
    }

第九站

BOM(Broswer Object Model)

浏览器对象模型,可以通过 JS 操作浏览器

BOM浏览器对象模型

  • BOM可以使我们通过js操作浏览器
  • 在BOM中为我们提供了一组对象,用来完成对浏览器的操作
    • BOM对象
    • Window
      • 代表整个浏览器的窗口,同时window也是网页中的全局对象
    • Navigator
      • 代表当前浏览器的信息,通过该对象能识别不同的浏览器
    • Location
      • 代表当前浏览器的地址栏的信息,通过Location可以获取地址栏信息,或者操作浏览器跳转页面
    • History
      • 代表浏览器的历史记录,可以通过该对象操作浏览器的历史记录
      • 由于隐私的原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页
      • 而且该操作旨在当此访问时有效
    • Screen
      • 代表用户的屏幕信息,通过该对象可以获取到用户的显示器的相关的信息
  • 这些BOM对象在浏览器中都是作为window对象的属性保存的。可以通过window对象来使用,也可以直接使用
    • 在IE11中已经将微软和IE相关的标识都去除了,所以我们已经基本不能根据UserAgent来识别一个浏览器是否为IE了
    • 但可以根据浏览器一些特有的对象来判断浏览器的信息
    • 例如:
      • ActiveXObject

对不同的浏览器进行判断

    if (/firefox/i.test(navigator.userAgent)){
        console.log("火狐浏览器");
    } else if (/chrome/i.test(navigator.userAgent)){
        console.log("google浏览器");
    } else if (/msie/i.test(navigator.userAgent)){
        console.log("IE浏览器");
    }
    // 此方法在IE11中无效
    else if (window.ActiveXObject){
        console.log("IE浏览器");
    }
    // 改进
    if("ActiveXObject" in window){
        console.log("IE11浏览器");
    }
History
    /**
     * History
     *  该对象可以用来操作浏览器向前或向后翻页
     */

    window.onload = function() {
        var btn1 = document.getElementById("btn1");

        btn1.onclick = function() {
            /**
             * length可以获取到当前访问的链接的数量
             */
            console.log(history.length);

            /**
             * back()
             *  可以回退到上一个页面,作用和浏览器的回退按钮一样
             */
            history.back();

            /**
             * history.forward()
             *  可以跳转到下一个页面
             */
            history.forward();

            /**
             * go()
             *  可以用来跳转到指定的页面
             *  他需要一个整数作为参数
             *      1:向前跳转一个页面,相当于forward()
             *      2:向前跳转两个页面
             *      -1:表示向后跳转一个页面
             *      -2:向后跳转两个页面
             */
        };
    };
Location
    /**
     * Location
     *  该对象中封装了浏览器的地址栏的信息
     *  修改之后会跳到修改之后的页面
     */

    window.onload = function (){

        var btn1 = document.getElementById("btn1");

        btn1.onclick = function (){

            alert(location);

            // 改路径
            location = "http://www.baidu.com";

            /**
             * assign()
             *  用来跳转到其他的页面,作用和之际我修改location一样
             */
            location.assign("http://www.baidu.com");

            // 重新加载此页面和刷新一样,参数设置为true会强制刷新,清掉缓存
            location.reload(true);

            // replace()
            // 可以使用一个新的页面替换当前页面,调用完毕也会跳转页面
            // 不会生成历史记录,不能使用回退按钮回退
            location.replace("http://www.baidu.com");

        };

    }

定时调用

  • setInterval()
    • 定时调用,可以将一个函数每隔一段时间执行一次
    • 参数:
      • 1、回调函数,该函数会每隔一段时间被调用一次
      • 2、每次调用间隔,单位是毫秒
    • 返回值:
      • 返回一个Number类型的数据
      • 这个数字用来作为定时器的唯一标识
  • clearInterval();
    • 方法中需要一个定时器的标识来作为参数,这样将关闭标识对应的定时器
    • 可以接收任意参数
      • 如果参数是一个有效的定时器的标识,则停止对应的定时器
      • 如果参数不是一个有效的标识,则什么也不做

一个例子

    // 使图片可以自动切换
    var img1 = document.getElementById("img1");
    var imgArr = ["img/1.jpg", "img/2.jpg", "img/3.jpg", "img/4.jpg", "img/5.PNG"];
    var index = 0;

    var btn1 = document.getElementById("btn1");
    var btn2 = document.getElementById("btn2");

    var no;
    btn1.onclick = function (){
        /**
         * 开启定时器,来自动切换图片
         * 我们每点击一次按钮就会开启一个定时器
         * 点击多次就会开启多个定时器,这就导致图片的切换速度会过快
         * 并且我们每次只能关闭最后一次开启的定时器
         */

        // 在开启定时器之前,先将当前元素上的其他定时器关闭
        clearInterval(no);
        no = setInterval(function() {
            // 使索引要自增
            index ++;
            img1.src = imgArr[index];

            // 索引大于数组长度时, 将index设置为0
            /*if (index === imgArr.length - 1){
                index = 0;
            }*/
            // 改进
            index = index % imgArr.length;
        }, 1000);

        btn2.onclick = function (){
            // 取消定时器
            clearInterval(no);
        };
    };

一个例子

使div可以根据不同的方向键向不同的方向移动

    /**
     *  按左键向左移(37)
     *  按右键向右移(39)
     *  按上键向上移(38)
     *  按下键向下移(40)
     */
    var box1 = document.getElementById("box1");

    // 定义一个变量来表示移动的速度
    var speed = 10;

    // 创建一个变量来表示方向
    var dir = 0;

    // 定时器标识
    var no;

    document.onkeydown = function (event){
        event = event || window.event;

        clearInterval(no);
        // 开启一个定时器,来控制div的移动
        no = setInterval(function(){
            switch(dir){
                case 37:
                    // alert("hello");
                    box1.style.left = box1.offsetLeft - speed + "px";
                    break;
                case 38:
                    box1.style.top = box1.offsetTop - speed + "px";
                    break;
                case 39:
                    box1.style.left = box1.offsetLeft + speed + "px";
                    break;
                case 40:
                    box1.style.top = box1.offsetTop + speed + "px";
                    break;
                default:
                    return ;
            }
        }, 30);

        // 当用户按了ctrl之后速度加快
        if (event.ctrlKey){
            speed += 50;
        } else {
            speed = 10;
        }

        dir = event.keyCode;
    };

    document.onkeyup = function(){
        dir = 0;
    }

延时调用

延时调用和定时调用是可以互相替代的,在开发中根据需要去选择

    var num = 1;

    // 延时调用, 3秒之后将会执行此函数, 延时调用会执行一次
    var timer = setTimeout(function(){
        console.log(num ++);
    }, 3000);

    // 关闭延时调用
    clearTimeout(timer);

定时器

定时器函数

    /**
     * 参数:
     *  obj:要执行动画的对象
     *  speed:移动的速度(正数左移,负数右移)
     *  target:执行的目标位置
     *  attr:要执行动画的样式; left、top、width、height
     *  callback:回调函数,这个函数将会在动画执行完毕以后执行
     */
    function move(obj, speed, target, attr, callback){
        clearInterval(obj.timer);

        // 获取元素目前的位置
        var current = parseInt(getStyle(obj, attr));

        // 判断速度的正负值
        // 如果从0到800移动则speed为正
        // 如果从800到0移动则speed为负
        if (current > target){
            // 此时速度为负值
            speed = -speed;
        }

        // 开启定时器
        obj.timer = setInterval(function(){
            // 获取box1原来的位置
            var oldValue = parseInt(getStyle(obj, attr));

            var newValue = oldValue + speed;

            // 判断newValue是否大于800
            // 当向左移动时需要判断newValue是否小于target
            if ((speed < 0 && newValue < target) || (speed > 0 && newValue > target)){
                newValue = target;
            }

            obj.style[attr] = newValue + "px";

            // 当元素移动到800像素时,使其停止移动
            if (newValue === target){
                clearInterval(obj.timer);
                // 动画执行完毕,调用回调函数
                callback && callback();
            }
        }, 30);
    }

JSON(Javascript Object Notation)

  • JSON:
    • Javascript Object Notation JS对象表示法
    • JSON和JS对象的格式一样,只不过JSON字符串中的属性名必须加双引号
    • 其他的和JS语法一致
  • JSON分类:
    • 1、对象 {}
    • 2、数组 []
  • JSON中允许的值:
    • 1、字符串
    • 2、数值
    • 3、布尔值
    • 4、null
    • 5、对象
    • 6、数组

JSON (在IE7及以下版本不支持,会报错)
JS中的对象只有JS自己认知,其他的语言都不认识
JSON就是一个特殊格式的字符串,这个字符串可以被任意的语言识别
并且可以转换为任意语言中的对象,JSON在开发中主要用域数据的交互

    // 创建一个对象
    var obj = '{"name" : "孙悟空", "age" : 18, "gender" : "男"}';

    var arr = '[1, 2, 3, 4, "hello", true]';

    var obj2 = '{"arr" : [1, 32, 4]}';

    var arr2 = '[{"name" : "孙悟空", "age" : 18, "gender" : "男"}, {"name" : "孙悟空", "age" : 18, "gender" : "男"}]';

    console.log(obj.name);
  • 将JSON字符串转换为JS中的对象,在JS中为我们提供了一个工具类,就叫JSON,这个可以将JSON转换为JS对象,也可以将JS对象转换为JSON
    • JSON.parser():
      • 可以将JSON字符串转换为JS对象
        • 需要一个字符串作为参数,会将该字符串转换为JS对象并返回
    • JSON.stringify()
      • 可以将JS对象转化为JSON字符串
        • 需要一个JS对象作为参数,会将该对象转换为JSON字符串并返回
    obj = JSON.parse(obj);

    console.log(obj);

    console.log(typeof obj);

    var obj3 = {name : "猪八戒", age : 18, gender : "男"};

    obj3 = JSON.stringify(obj3);

    console.log(obj3);

    console.log(typeof obj3);
  • eval()
    • 这个函数可以用来执行一段字符串形式的JS代码,并将执行结果返回
    • 如果使用eval执行的字符串中含有{},它会将{}当成代码块
    • 如果不希望将其当成代码块解析,则需在字符串前后各加一个()
    • 这个函数的功能很强大,可以直接执行一个字符串中的JS代码
    • 但是在开发中尽量不要使用,它的执行性能比较差,还具有安全隐患

如果需要兼容IE7及以下的JSON操作,则可以通过引入一个外部的JS文件来处理

    var str = 'alert("hello");';

    var obj4 = '({"name" : "孙悟空", "age" : 18, "gender" : "男"}';

    eval(str);

    obj4 = eval(obj4);

    console.log(obj4);

    console.log(typeof obj4);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值