JavaScript基础+JS API(DOM+BOM)

JavaScript基础

一、JS的组成

在这里插入图片描述

二、JS的基础

1. JS输入输出语句

在这里插入图片描述

2. 变量命名规范

在这里插入图片描述

3. 数据类型

3.1 变量类型简介

在这里插入图片描述

3.2 数据类型的分类
1) 简单数据类型(基本数据类型)

在这里插入图片描述

① 数字型 Number

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

② 字符串型 String

在这里插入图片描述
在这里插入图片描述

③ 布尔型 Boolean

在这里插入图片描述

④ 未定义类型 Undefined

在这里插入图片描述

<script>
    var variable = undefined;
    console.log(variable + 'pink'); //undefinedpink
    console.log(variable + 1); //NaN
</script>
⑤ 空类型 Null
<script>
    var variable = null;
    console.log(variable + 'pink'); //nullpink
    console.log(variable + 1); //1
</script>
2) 复杂数据类型(引用数字类型)

详见下方三。

3) 获取变量数据类型
① 获取检测变量的数据类型 typeof
<script>
	    var num = 10;
	    console.log(typeof num); //number
	    var str = 'pink';
	    console.log(typeof str); //string
	    var flag = true;
	    console.log(typeof flag); //boolean
	    var variable = undefined;
	    console.log(typeof variable); //undefined
	    var timer = null;
	    console.log(typeof timer); //object
</script>
② 字面量

在这里插入图片描述

4) 数据类型转换
① 转换为字符串类型

在这里插入图片描述

<script>
	    var num = 10;
	    console.log(typeof num.toString()); //string
	    console.log(typeof String(num)); //string
	    //隐式转换
	    console.log(typeof(num + '')); //string
</script>
② 转换为数字型(重点)

在这里插入图片描述

<script>
	    // 1.parseInt
	    var age = '18';
	    console.log(typeof parseInt(age)); //number
	    console.log(parseInt('3.14')); //3 取整
	    console.log(parseInt('3.94')); //3 取整
	    console.log(parseInt('120px')); //120 会去掉单位
	    // 2.parseFloat
	    console.log(parseFloat('3.14')); //3.14 
	    // 3.Number
	    console.log(Number('123')); //123
	    // 4.利用算术运算 - * / 隐式转换
	    console.log(typeof('12' - 0)); //number
	    console.log('123' - '120'); //3
	    console.log('123' * 1); //123
</script>
③ 转换为布尔型

在这里插入图片描述

5)标志符、关键字、保留字
① 标识zhi符

在这里插入图片描述

② 关键字

在这里插入图片描述

③ 保留字

在这里插入图片描述

4. JavaScript 运算符

① 算数运算符

在这里插入图片描述

② 递增和递减运算符

前置递增运算符:
在这里插入图片描述
后置递增运算符:
在这里插入图片描述
在这里插入图片描述

③ 运算符优先级

在这里插入图片描述

5. 流程控制(顺序结构、分支结构、循环结构)

在这里插入图片描述

6. 数组排序(冒泡排序)

在这里插入图片描述
在这里插入图片描述
从小到大:

<script>
    var arr = [4, 1, 3, 5, 9];
    for (var i = 0; i <= arr.length - 1; i++) {
        for (var j = 0; j < arr.length - -1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
    console.log(arr);//[1,3,4,5,9]
</script>

7. 函数的内置对象 arguments的使用

在这里插入图片描述

function getMax() {
    var max = arguments[0];
    for (var i = 0; i < arguments.length; i++) {
        if (max < arguments[i]) {
            max = arguments[i];
        }
    }
    return max;
}
console.log(getMax(9, 7, 12, 3));

8. 函数的两种声明方式

// 1. 利用函数关键字 自定义函数(命名函数)
// 声明提前
 fn(); //我是自定义函数
 function fn() {
     console.log('我是自定义函数');
 }
 fn(); //我是自定义函数


 fun(); // fun is not a function
 // 2. 函数表达式
 var fun = function() {
     console.log('我是函数表达式');
 };
 fun();

9. 作用域

① 全局变量

在这里插入图片描述

var num = 10;
console.log(num); //10
function fn() {
    console.log(num); //10
    num2 = 20; //全局变量
}
fn();
console.log(num2); //20
② 局部变量

在这里插入图片描述

function fun(aru) {
   var num1 = 10;
}
fun();
console.log(aru); //aru is not defined
console.log(num1); // num1 is not defined
③ 二者的区别

在这里插入图片描述

④ 块级作用域(es5 之前无,es6之后新增的块级作用域)

10. 预解析:变量预解析+函数预解析

JS引擎运行JS时,分为两步:预解析代码执行
(1) 预解析 JS引擎会把JS 里面所有的var还有function提升到当前作用域的最前面。
(2)代码执行 按照代码书写的顺序从上往下执行。

① 变量预解析(变量提升):把所有的变量声明 提升到 当前作用域 的最前面,不提升赋值操作
// 变量提升:把所有的变量声明 提升到 当前作用域 的最前面,不提升赋值操作
// 坑1
console.log(num); //undefined
var num = 10;
// 上诉两行代码相当于执行了以下代码:
var num;
console.log(num);
num = 10;

// 坑2
fun();
var fun = function() {
    console.log(22); // fun is not a function
};
// 上诉三行代码相当于执行了以下代码:
var fun;
fun();
fun = function() {
    console.log(22); // fun is not a function
}
② 函数预解析(函数提升):把所有的函数声明 提升到 当前作用域 的最前面,不调用函数
// 函数提升:把所有的函数声明 提升到 当前作用域 的最前面,不调用函数
fn();

 function fn() {
     console.log(11);
 }
 // 上诉三行代码相当于执行了以下代码:
 function fn() {
     console.log(11);
 }
 fn();

案例:
链接: https://www.bilibili.com/video/BV1hT4y1u7qb?p=141.

//案例1:
f1();
console.log(c);
console.log(b);
console.log(a);

function f1() {
    var a = b = c = 9;
    // 相当于 var a = 9;b=9;c=9 c和b直接赋值 没有var声明 当 全局变量看
    console.log(a);
    console.log(b);
    console.log(c);
}

// 上诉代码相当于执行了以下代码:
function f1() {
    var a;
    a = 9;
    b = 9;
    c = 9
    console.log(a); //9
    console.log(b); //9
    console.log(c); //9
}
f1();
console.log(c); //9
console.log(b); //9
console.log(a); //a is not defined


//案例2:
var a = 18;
f1();
function f1() {
    var b = 9;
    console.log(a);
    console.log(b);
    var a = '123';
}
// 上诉代码相当于执行了以下代码:
var a;
function f1() {
    var b;
    var a;
    b = 9;
    console.log(a); //undefined
    console.log(b); //9
    a = '123';
};
a = 18;
f1();

三、JavaScript 对象

1. 创建对象的三种方式

① 利用对象字面量{}创建对象

在这里插入图片描述

var obj = {
    uname: '吴心怡',
    age: '21',
    sex: '女',
    sayHi: function() {
        console.log('hi');
    }
}
console.log(obj.uname);
console.log(obj['age']);
obj.sayHi();
② 利用new Object创建对象
var obj = new Object();
obj.uname = 'wxy';
obj.age = 21;
obj.sex = '女';
obj.sayHi = function() {
    console.log('hi');
}
console.log(obj.uname);
obj.sayHi();
③ 利用构造函数创建对象
function Star(uname, age, sex) {
    this.uname = uname;
    this.age = age;
    this.sex = sex;
    this.sing = function(sang) {
        console.log(sang);
    }
}
var ldh = new Star('刘德华', 18, '男');
console.log(typeof ldh);
console.log(ldh.uname);
ldh.sing('冰雨');

2. new关键字

在这里插入图片描述

3. 遍历对象属性:for(var k in obj)

<script>
    var obj = {
        uname: 'wxy',
        age: '21',
        sex: '女',
        sayHi: function() {
            console.log('hi');
        }
    }
    for (var k in obj) {
        console.log(k); //uname;k输出得到的是属性名
        console.log(obj[k]); //wxy;obj[k]得到的是属性值
    }
</script>

4. 内置对象

JS中的对象分为3种:自定义对象、内置对象、浏览器对象。
JS提供了多个内置对象:Math、Date、Array、String等。

1) 查文档:MDN

MDN:https://developer.mozilla.org/zh-CN/.

2) Math 数学对象

Math 不是一个构造函数,不需要new来调用;而是直接使用里面的属性和方法即可。

① Math基本方法跟属性

在这里插入图片描述

<script>
    console.log(Math.PI); //3.141592653589793
    console.log(Math.max(1, 9, 4, 7)); //9
    console.log(Math.max(-10, -20)); //-10
    console.log(Math.max(10, 50, 'wxy')); //NaN
    console.log(Math.max()); //-Infinity 负无穷大
    console.log(Math.abs(-1)); //1 绝对值
    console.log(Math.abs('-1')); //隐式转换 会把 字符串型 -1 转换为整数型
    console.log(Math.abs('pink')); //NaN
    console.log(Math.floor(3.5)); //3 向下取整
    console.log(Math.ceil(3.5)); //4  向上取整
    console.log(Math.round(3.5)); //4 四舍五入 
    console.log(Math.round(3.4)); //3
    console.log(Math.round(-1.1)); //-1
    console.log(Math.round(-1.5)); //-1 其他数字都是四舍五入 但是 .5 往大了取
</script>
② 随机数方法 Math.random()
<script>
   //Math.random(); 返回的是 一个[0,1)的随机小数
    Math.random();
    //得到两个数之间的随机整数 并且包含这两个整数
    function getRandom(min, max) {
        // min = Math.ceil(min);
        // max = Math.floor(max);
        return Math.floor(Math.random() * (max - min + 1) + min); //含最大值、最小值 
    }
    console.log(getRandom(1, 10)); //【1,10】之间的数
</script>
3) Date 日期对象

Date是一个构造函数,必须使用new来调用创建日期对象。

在这里插入图片描述

① Date()方法的使用

在这里插入图片描述

var date = new Date(); //Date没有跟参数返回当前系统的当前时间
console.log(date); //Sun Jul 26 2020 23:18:13 GMT+0800 (中国标准时间)
var date1 = new Date(2020, 7, 26);
console.log(date1); //Wed Aug 26 2020 00:00:00 GMT+0800 (中国标准时间) 返回的是八月不是七月
var date2 = new Date('2020-7-26 23:19:26');
console.log(date2); //Sun Jul 26 2020 23:19:26 GMT+0800 (中国标准时间)
② 日期格式化

在这里插入图片描述

 var year = date.getFullYear(); //年
 var month = date.getMonth() + 1; //月
 var dates = date.getDate(); //日
 var day = date.getDay(); //星期几
 var hours = date.getHours(); //时
 hours = hours < 10 ? '0' + hours : hours;
 var min = date.getMinutes(); //分
 min = min < 10 ? '0' + min : min;
 var s = date.getSeconds(); //秒
 s = s < 10 ? '0' + s : s;
 var days = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
 console.log('今天是' + year + '年' + month + '月' + dates + '日 ' + days[day] + ' ' + hours + ':' + min + ':' + s); //今天是2020年7月26日 星期日 23:51:35
③ 获取日期的总的毫秒形式(距离1970年1月1日的毫秒数)
// 1. 通过 getTime()
console.log(date.getTime());
// 2. 通过 valueOf()
console.log(date.valueOf());
// 3. 通过 +new Date()
var date1 = +new Date();
console.log(date1);
// 4.通过 H5 新增的 获取总的毫秒数
console.log(Date.now());
④ 倒计时案例

在这里插入图片描述

function countDown(time) {
		 var nowTime = +new Date(); //当前秒数
		 var inputTime = +new Date(time); //用户输入的时间
		 var times = (inputTime - nowTime) / 1000; //剩余的秒数
		 var d = parseInt(times / 60 / 60 / 24); //天
		 d = d < 10 ? '0' + d : d;
		 var h = parseInt(times / 60 / 60 % 24); //时
		 h = h < 10 ? '0' + h : h;
		 var m = parseInt(times / 60 % 60); //分
		 m = m < 10 ? '0' + m : m;
		 var s = parseInt(times % 60); //秒
		 s = s < 10 ? '0' + s : s;
		 return d + '天' + h + '时' + m + '分' + s + '秒';
}
console.log(countDown('2020-7-27 15:02:02')); //00天14时14分42秒
4) Array 数组对象
① 创建数组的两种方式:字面量+new Array()
// 1.利用 数组字面量
var arr = [1, 2, 3];
console.log(arr); //[1, 2, 3]
// 2.利用 new Array()
var arr1 = new Array(2, 3);
console.log(arr1); // [2, 3]
var arr1 = new Array(2);
console.log(arr1); // [empty × 2]
② 判断是否为数组的两种方法:instanceof+Array.isArray()
// 1) instanceof 判断arr是否为数组类型
console.log(arr instanceof Array); //true
console.log(arr instanceof String); //false
// 2) H5新增的方法  Array.isArray(参数)
console.log(Array.isArray([1, 2, 3])); //true
console.log(Array.isArray({})); //false
③ 添加删除数组元素的方法:push、pop、shift、unshift、splice、slice

在这里插入图片描述

var arr = [1, 2, 3];
//1. push 在末尾添加一个或多个元素
// (1)返回结果是 新数组的长度
// (2)原数组也会发生变化
arr.push(4);
arr.push(5, 'wxy');
console.log(arr); //[1, 2, 3, 4, 5, "wxy"]
console.log(arr.push(6, 'abc')); //8


//2. unshift 在前面添加一个或多个元素
// (1)返回结果是 新数组的长度
// (2)原数组也会发生变化
var arr = [1, 2, 3];
arr.unshift('red', 'purple');
console.log(arr); // ["red", "purple", 1, 2, 3]
console.log(arr.unshift('green', 4)); //7


//3. pop 一次只能删除一个末尾的元素
// (1)返回结果是 删除的元素
// (2)原数组也会发生变化
//  (3)()里面不能加参数
console.log(arr); //["green", 4, "red", "purple", 1, 2, 3]
arr.pop();
console.log(arr); //["green", 4, "red", "purple", 1, 2]
console.log(arr.pop()); //2 
// console.log(arr.pop()); //返回的是删除的最后一个元素的值


//4. shift  删除数组第一个元素
// (1)返回结果是 删除的元素
// (2)原数组也会发生变化
//  (3)()里面不能加参数
arr.shift();
console.log(arr); //[4, "red", "purple", 1]
console.log(arr.shift()); //4



//5. splice 删除、增加 任意元素
// (1)返回结果是 被删除的元素组成的新数组
// (2)原数组也会发生变化
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
//  (3) 结构:数组 splice(start,deletedCount)
console.log(arr.splice(2, 2)); //[3, 4]
console.log(arr); //[1, 2, 5, 6, 7, 8, 9]
arr.splice(3, 0, 'wxy');
//  (4) 结构:数组 splice(start,deletedCount,item)
console.log(arr); //[1, 2, 5, "wxy", 6, 7, 8, 9]



//6. slice 删除、增加 任意元素
// (1)返回结果是 被删除的元素组成的新数组
// (2)原数组不会发生变化
//  (3) 结构:数组 splice(start,end) 包括atart下标不包括end下标
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(arr.slice(2, 5)); //[3, 4, 5]
console.log(arr); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
④ 数组排序:sort

在这里插入图片描述

 // 翻转数组
 var arr = ['red', 'green', 'blue'];
 arr.reverse();
 console.log(arr); //["blue", "green", "red"]

 // 排序
 var arr1 = [13, 4, 77, 1, 7];
 console.log(arr1.sort()); //[1, 13, 4, 7, 77]
 arr1.sort(function(a, b) {
     return a - b; //升序 
     // return b - a; //降序
 });
 console.log(arr1); // [1, 4, 7, 13, 77]
⑤ 查询数组索引方法:indexOf、lastIndexOf

在这里插入图片描述

var arr = ['red', 'green', 'blue', 'purple', 'blue'];
// 1. indexof 是从前往后查找
console.log(arr.indexOf('blue')); // 2 
console.log(arr.indexOf('pink')); // -1
// 2. lastIndexof 是从后往前查找
console.log(arr.lastIndexOf('blue')); // 4 
console.log(arr.lastIndexOf('pink')); // -1

案例:数组去重
在这里插入图片描述

function unique(arr) {
     var newArr = [];
     for (var i = 0; i < arr.length; i++) {
         if (newArr.indexOf(arr[i]) === -1) {
             newArr.push(arr[i]);
         }
     }
     return newArr;
 }
 var demo = unique(['a', 'c', 'a', 'd', 'g', 's', 'c', 'd']);
 var demo1 = unique([1, 2, 3, 4, 5, 4, 2, 1]);
 console.log(demo); //["a", "c", "d", "g", "s"]
 console.log(demo1); //[1, 2, 3, 4, 5]
⑥ 数组转换为字符串

在这里插入图片描述

//1.toString()将我们的数组转换为字符串
var arr = [1, 2, 3];
console.log(arr.toString()); // 1,2,3
//2.join(分隔符)
var arr1 = ['blue', 'red', 'green', 'purple'];
console.log(arr1.join()); //默认逗号分隔 blue,red,green,purple
console.log(arr1.join('-')); // blue-red-green-purple
console.log(arr1.join('&')); // blue&red&green&purple
5) String 字符串对象
① 根据字符返回索引 indexOf 的面试题

在这里插入图片描述

var str = "abcoefoxyozzopp";
var index = str.indexOf('o');
var num = 0;
while (index !== -1) {
    num++;
    console.log(index);
    index = str.indexOf('o', index + 1);//3 6 9 12
}
console.log(num);// 4
② 根据索引返回字符 charAt、charCodeAt、str[index](重点)

在这里插入图片描述

<script>
	  var str = 'andy';
	  // 1. charAt(index) 根据位置返回字符串
	  console.log(str.charAt(2)); //2
	  // 遍历所有的字符
	  for (var i = 0; i < str.length; i++) {
	      console.log(str.charAt(i)); // a n d y
	  }
	  // 2. charCodeAt(index) 返回相应索引号字符的ASCILL值
	  console.log(str.charCodeAt(0)); //97
	
	  // 3. str[index] H5新增方法
	  console.log(str[1]); //n
</script>
③ 字符串操作方法 concat、substr、slice、substring(重点)

在这里插入图片描述

var str = 'red';
// 1.拼接
console.log(str.concat('pink')); //redpink
// 2.截取
var str2 = '小猪佩奇真可爱'
console.log(str2.substr(2, 2)); //佩奇 从2号位置开始取两个字符
④ 替换字符串replace、字符串转换为数组split
// 1. 替换字符 replace 只会替换第一个字符
    var str = "andya";
    console.log(str.replace('a', 'b')); //只替换第一个a bndya

    // 2. 字符转换为数组 split('分隔符')
    //join 数组转换为字符串
    var arr = [1, 2, 3];
    var str;
    str = arr.join('-');
    console.log(str); //1-2-3
    //split 字符串转换为数组
    var str1 = 'red&pink&blue';
    console.log(str1.split('&')); //有’&‘的地方就用,分隔开 ["red", "pink", "blue"]

四、简单数据类型 与 复杂数据类型的区别

1. 区别一:值类型和引用类型

在这里插入图片描述
注意:null返回的是object类型,如果有个变量我们以后打算存储为对象,暂时没想好放啥,这个时候就给null。

2. 区别二:栈和堆

在这里插入图片描述
在这里插入图片描述

3. 简单类型传参和复杂类型传参

在这里插入图片描述
在这里插入图片描述
课件视频链接:
链接: https://www.bilibili.com/video/BV1hT4y1u7qb?p=188.

五、Web APIs 阶段

1. JS基础阶段以及 Web APIs阶段

在这里插入图片描述

2. DOM

① 什么是 DOM

在这里插入图片描述

② DOM 树

在这里插入图片描述

3. 获取元素

① 根据ID获取 getElementById

使用 getElementById()方法可以获取带有ID的元素对象。

<body>
    <div id="time">2020-5-13</div>
    <script>
        var timer = document.getElementById('time');
        console.log(timer); //<div id="time">2020-5-13</div>
        console.log(typeof timer); //object 返回的是一个对象
        console.dir(timer);//打印我们返回的元素对象 更好的查看里面的属性和方法 
    </script>
</body>
② 根据标签名获取 getElementsByTagName

使用 getElementsByTagName()方法可以返回带有指定标签名的对象的集合

<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
    </ul>
    <ul id="nav">
        <li>abc</li>
        <li>abc</li>
        <li>abc</li>
        <li>abc</li>
        <li>abc</li>
    </ul>abc
    <script>
        // 1. 返回的是 获取过来元素对象的集合 以伪数组的形式存储
        var lis = document.getElementsByTagName('li');
        console.log(lis); // HTMLCollection(10) [li, li, li, li, li, li, li, li, li, li]
        console.log(lis[0]); // <li>1</li>
        for (var i = 0; i < lis.length; i++) {
            console.log(lis[i]);
        }
        // 2. element.getElementsByTagName() 可以得到这个元素里面的某些标签
        var nav = document.getElementById('nav');
        var navlis = nav.getElementsByTagName('li');
        console.log(navlis); // HTMLCollection(5) [li, li, li, li, li]
    </script>
</body>
③ 通过 HTML5 新增的方法获取

在这里插入图片描述

<body>
    <div class="box">盒子1</div>
    <div class="box">盒子2</div>
    <div class="nav">
        <ul>
            <li>首页</li>
            <li>产品</li>
        </ul>
    </div>
    <script>
        //1. getElementsByClassName 根据类名返回元素对象集合
        var boxs = document.getElementsByClassName('box');
        console.log(boxs); // HTMLCollection(2) [div.box, div.box]
        
        //2. querySelector 根据指定选择器返回第一个元素对象 切记里面的选择器需要加符号
        var box = document.querySelector('.box');
        console.log(box); // <div class="box">盒子1</div>

        //3. querySelectorAll 根据指定选择器返回所有对象
        var boxall = document.querySelectorAll('.box');
        console.log(boxall); //NodeList(2) [div.box, div.box]
    </script>
</body>
④ 获取特殊元素(body , html)

在这里插入图片描述

// 1.获取body元素
var bodyEle = document.body;
console.log(bodyEle);
// 2.获取html元素
var htmlEle = document.documentElement;
console.log(htmlEle);

4. 事件基础

① 事件三要素:事件源+事件类型+事件处理程序

在这里插入图片描述

<body>
    <button id="wxy">吴心怡</button>
    <script>
        // 1. 事件三要素:事件源 事件类型 事件处理程序
        //(1) 事件源 事件被触发的对象
        var wxy = document.getElementById('wxy');
        //(2) 事件类型 点击事件
        //(3) 事件处理程序 通过一个函数赋值的方式 完成
        wxy.onclick = function() {
            alert('无限可能');
        }
    </script>
</body>
② 常见的鼠标事件

在这里插入图片描述

5. 操作元素

① 改变元素内容

在这里插入图片描述

<body>
    <button>显示当前系统时间</button>
    <div id="div">某个时间</div>
    <div id="div1">2</div>
    <p>
        我是文字
        <span>123</span>
    </p>
    <script>
        var btn = document.querySelector('button');
        var div1 = document.querySelector('div');
        var div2 = document.getElementById('div1');

        btn.onclick = function() {
            div1.innerText = getDate(); //今天是2020年7月28日星期二
            // innerText 和 innerHTML的区别
            // 1. innerText 不识别html标签 非标准
            div1.innerText = '<strong>今天是</strong>2019'; //<strong>今天是</strong>2019
            // 2. innerHTML 识别html标签 W3C标准
            div2.innerHTML = '<strong>今天是</strong>2019'; //今天是2019
            // 3. 这两个属性是可读写的 可以获取元素里面的内容
            // 3.1 innerText 去除空格和换行
            var p = document.querySelector('p');
            console.log(p.innerText); //我是文字 123
            // 3.2 innerHTML 保留空格和换行
            console.log(p.innerHTML);
            /* 
                    我是文字
                    <span>123</span>
            */

        }
        function getDate() {
            var date = new Date();
            var year = date.getFullYear();
            var month = date.getMonth() + 1;
            var dates = date.getDate();
            var day = date.getDay();
            var days = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
            return '今天是' + year + '年' + month + '月' + dates + '日' + days[day];
        }
    </script>
</body>

结果演示:
在这里插入图片描述

② 常见元素的属性操作

在这里插入图片描述

<body>
    <button id='right'></button>
    <button id='error'></button>
    <img src="../images/right.png" alt="" title="对">
    <script>
        var right = document.getElementById('right');
        var error = document.getElementById('error');
        var img = document.querySelector('img');
        error.onclick = function() {
            img.src = '../images/wrong.png';
            img.title = '错';
        }
        right.onclick = function() {
            img.src = '../images/right.png';
            img.title = '对';
        }
    </script>
</body>
③ 表单元素的属性操作

在这里插入图片描述
仿京东显示密码:

<div class="box">
    <input type="password">
    <span><img src="../images/close.png" alt=""></span>
</div>
<script>
    var img = document.querySelector('img');
    var input = document.querySelector('input');
    var flag = 0;

    img.onclick = function() {
        if (flag == 0) {
            input.type = 'text';
            this.src = '../images/open.png';
            flag = 1;
        } else {
            input.type = 'password';
            this.src = '../images/close.png';
            flag = 0;
        }
    }
</script>

结果演示:
在这里插入图片描述
在这里插入图片描述

④ 样式属性操作

在这里插入图片描述

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>样式属性</title>
    <style>
        div {
            width: 200px;
            height: 200px;
            background-color: pink;
        }
        
        .change {
            background-color: purple;
            font-size: 25px;
            margin-top: 100px;
            color: #fff;
        }
    </style>
</head>

<body>
    <div class="first">文本</div>
    <script>
        var div = document.querySelector('div');
        div.onclick = function() {
            //1. 使用element.style 里面的属性采取驼峰命名法 css的权重更高
            //   样式较少 功能简单的情况下使用
            this.style.backgroundColor = 'blue';
            //2. 通过修改元素的className更改元素的样式 适合于样式较多或者功能复杂的情况下,会覆盖原先的类名
            this.className = 'change';
            //3 .如果要保留原先的类名
            this.className = 'first change';
        }
    </script>
</body>

结果演示:
点击前:
在这里插入图片描述
点击后:
在这里插入图片描述

仿新浪注册页面

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            width: 600px;
            margin: 100px auto;
        }
        
        .message {
            display: inline-block;
            font-size: 12px;
            color: #999;
            background: url(../images/mess.png) no-repeat left center;
            padding-left: 20px;
        }
        
        .wrong {
            color: red;
            background-image: url(../images/wrong.png);
        }
        
        .right {
            color: green;
            background-image: url(../images/right.png);
        }
    </style>
</head>

<body>
    <div class="register">
        <input type="password" class="ipt">
        <p class="message">请输入6~16位密码</p>
    </div>
    <script>
        var ipt = document.querySelector('.ipt');
        var message = document.querySelector('.message');
        ipt.onblur = function() {
            if (ipt.value.length < 6 || ipt.value.length > 16) {
                message.className = 'message wrong';
                message.innerHTML = '您输入的位数不对,要求6~16位';
            } else {
                message.className = 'message right';
                message.innerHTML = '您输入的正确';
            }


        }
    </script>
</body>

结果演示:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

⑤ 经典案例:

隔行变色:

<body>
    <table>
        <thead>
            <tr>
                <th>编号</th>
                <th>姓名</th>
                <th>年龄</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>001</td>
                <td>wxy</td>
                <td>21</td>
            </tr>
            <tr>
                <td>002</td>
                <td>wxy</td>
                <td>21</td>
            </tr>
            <tr>
                <td>003</td>
                <td>wxy</td>
                <td>21</td>
            </tr>
            <tr>
                <td>004</td>
                <td>wxy</td>
                <td>21</td>
            </tr>
            <tr>
                <td>005</td>
                <td>wxy</td>
                <td>21</td>
            </tr>
        </tbody>
    </table>
    <script>
        var trs = document.querySelector('tbody').querySelectorAll('tr');
        for (var i = 0; i < trs.length; i++) {
            // 鼠标经过
            trs[i].onmousemove = function() {

                this.style.backgroundColor = 'pink';
            };
            // 鼠标离开
            trs[i].onmouseout = function() {
                this.style.backgroundColor = '';
            }
        }
    </script>
</body>

结果演示:
在这里插入图片描述

表单全选取消全选:

<body>
    <div class="wrap">
        <table>
            <thead>
                <tr>
                    <th>
                        <input type="checkbox" id="j_cbAll">
                    </th>
                    <th>商品</th>
                    <th>价格</th>
                </tr>
            </thead>
            <tbody id="j_tb">
                <tr>
                    <td>
                        <input type="checkbox">
                    </td>
                    <td>iphone8</td>
                    <td>8000</td>
                </tr>
                <tr>
                    <td>
                        <input type="checkbox">
                    </td>
                    <td>iphone8</td>
                    <td>8000</td>
                </tr>
                <tr>
                    <td>
                        <input type="checkbox">
                    </td>
                    <td>iphone8</td>
                    <td>8000</td>
                </tr>
                <tr>
                    <td>
                        <input type="checkbox">
                    </td>
                    <td>iphone8</td>
                    <td>8000</td>
                </tr>
            </tbody>
        </table>
    </div>
    <script>
        var j_cbAll = document.getElementById('j_cbAll');
        var j_tbs = document.getElementById('j_tb').getElementsByTagName('input');
        j_cbAll.onclick = function() {
            for (var i = 0; i < j_tbs.length; i++) {
                j_tbs[i].checked = this.checked;
            }
        }
        for (var j = 0; j < j_tbs.length; j++) {
            j_tbs[j].onclick = function() {
                var flag = true;
                for (var k = 0; k < j_tbs.length; k++) {
                    if (j_tbs[k].checked == false) {
                        flag = false;
                        break;
                    }
                }
                j_cbAll.checked = flag;
            }
        }
    </script>
</body>

结果演示:
在这里插入图片描述
在这里插入图片描述

⑥ 自定义属性的操作 element.getAttribute()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
案例:tab栏切换(重点案例)

<body>
    <div class="tab">
        <div class="tab_list">
            <ul>
                <li class="current">商品介绍</li>
                <li>规格与包装</li>
                <li>售后保障</li>
                <li>商品评价</li>
                <li>手机社区</li>
            </ul>
        </div>
        <div class="tab_con">
            <div class="item" style="display: block;">
                商品介绍模块内容
            </div>
            <div class="item">
                规格与包装模块内容
            </div>
            <div class="item">
                售后保障模块内容
            </div>
            <div class="item">
                商品评价模块内容
            </div>
            <div class="item">
                手机社区模块内容
            </div>
        </div>
    </div>
    <script>
        var tab_list = document.querySelector('.tab_list');
        var items = document.querySelectorAll('.item');
        var lis = tab_list.querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {
            //给五个li设置index自定义属性
            lis[i].setAttribute('index', i);
            lis[i].onclick = function() {
                for (var j = 0; j < lis.length; j++) {
                    lis[j].className = '';
                }
                this.className = 'current';
                for (var k = 0; k < items.length; k++) {
                    items[k].style.display = 'none';
                }
                //找到相应的index 将其显示出来
                items[this.getAttribute('index')].style.display = 'block';
            }
        }
    </script>
</body>

结果演示:
在这里插入图片描述

⑦ H5 自定义属性 data- 开头

在这里插入图片描述

在这里插入图片描述

<body>
    <div gettime="18" data-index="2" data-list-name="wxy"></div>
    <script>
        var div = document.querySelector('div');
        console.log(div.gettime); //undefined gettime不是元素本身自带的属性
        console.log(div.getAttribute('gettime')); //18
        console.log(div.dataset.index); //2
        console.log(div.dataset['index']); //2
        console.log(div.getAttribute('data-list-name')); //wxy
        // 如果自定义属性有多个短横线连接的单词,获取时要采取驼峰命名
        console.log(div.dataset.listName); //wxy
        console.log(div.dataset['listName']); //wxy
    </script>
</body>

6. 节点操作

1) 为什么学节点操作

在这里插入图片描述

2) 节点概述

在这里插入图片描述

3) 节点层级
① 父节点 parentNode

在这里插入图片描述

② 子节点 childNodes和children(重点掌握)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
案例:下拉菜单


<body>
    <ul class="box">
        <li>
            <a href="">微博</a>
            <ul>
                <li>私信</li>
                <li>评论</li>
                <li>@我</li>
            </ul>
        </li>
        <li>
            <a href="">微博</a>
            <ul>
                <li>私信</li>
                <li>评论</li>
                <li>@我</li>
            </ul>
        </li>
        <li>
            <a href="">微博</a>
            <ul>
                <li>私信</li>
                <li>评论</li>
                <li>@我</li>
            </ul>
        </li>
        <li>
            <a href="">微博</a>
            <ul>
                <li>私信</li>
                <li>评论</li>
                <li>@我</li>
            </ul>
        </li>
    </ul>
    <script>
        var box = document.querySelector('.box');
        var lis = box.children;
        for (var i = 0; i < lis.length; i++) {
            lis[i].onmouseover = function() {
                this.children[1].style.display = 'block';
            }
            lis[i].onmouseout = function() {
                this.children[1].style.display = 'none';
            }
        }
    </script>
</body>

结果演示:
在这里插入图片描述

③ 兄弟节点

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

④ 创建节点

创建元素:在这里插入图片描述
添加元素:在这里插入图片描述
在这里插入图片描述

⑤ 删除节点

在这里插入图片描述

⑥ 复制节点(克隆节点)

在这里插入图片描述
案例:动态生成表格

<body>
    <table cellspacing="0">
        <thead>
            <tr>
                <th>姓名</th>
                <th>科目</th>
                <th>成绩</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody></tbody>
    </table>
    <script>
        var datas = [{
            name: '魏璎珞',
            subject: 'html',
            score: 100
        }, {
            name: '弘历',
            subject: 'javascript',
            score: 100
        }, {
            name: '傅恒',
            subject: 'css',
            score: 100
        }, {
            name: '明玉',
            subject: 'vue',
            score: 100
        }, {
            name: '大猪蹄子',
            subject: 'vue',
            score: 100
        }];
        var tbody = document.querySelector('tbody');
        for (var i = 0; i < datas.length; i++) {
            //根据对象个数创建行
            var tr = document.createElement('tr');
            tbody.appendChild(tr);
            //根据属性创建列
            for (var k in datas[i]) {
                var td = document.createElement('td');
                td.innerHTML = datas[i][k];
                tr.appendChild(td);
            }
            var operater = document.createElement('td');
            operater.innerHTML = '<a href="javascript:;">删除</a>';
            tr.appendChild(operater);
        }
        //删除操作
        var as = document.querySelectorAll('a');
        for (var j = 0; j < as.length; j++) {
            as[j].onclick = function() {
                tbody.removeChild(this.parentNode.parentNode);
            }
        }
    </script>
</body>

结果演示:
在这里插入图片描述

⑦ 3种动态创建元素的区别

在这里插入图片描述

7. DOM 重点核心

关于dom操作,我们主要针对于元素的操作。主要有创建、增、删、改、查、属性操作、事件操作。

① 创建:innerHTML+createElement

在这里插入图片描述

② 增:appendChild+insertBefore

在这里插入图片描述

③ 删:removeChild
④ 改

在这里插入图片描述

⑤ 查

在这里插入图片描述

⑥ 属性操作

在这里插入图片描述

⑦ 事件操作

在这里插入图片描述

8. 事件高级

1)注册事件(绑定事件)
① 注册事件概述

在这里插入图片描述

② addEventListener 事件监听方式

在这里插入图片描述

在这里插入图片描述

③ 注册事件兼容性解决方案

在这里插入图片描述

2)删除事件(解绑事件)
① 删除事件的方式

在这里插入图片描述

② 删除事件兼容性解决方案

在这里插入图片描述

3)DOM事件流

在这里插入图片描述
在这里插入图片描述

4)事件对象
① 什么是事件对象

在这里插入图片描述
在这里插入图片描述

② 事件对象的兼容性方案

在这里插入图片描述

③ 事件对象的常见属性和方法

在这里插入图片描述

<body>
    <ul>
        <li>123</li>
        <li>123</li>
        <li>123</li>
        <li>123</li>
    </ul>
    <a href="http://www.baidu.com">百度</a>
    <script>
        var ul = document.querySelector('ul');
        ul.addEventListener('click', function(e) {
            // 1. 谁绑定了该事件,this就指向谁
            console.log(this); //ul 
            // 2. 谁被点击,e.target就指向谁
            console.log(e.target); //li 
            // 3. 返回事件类型 不带on
            console.log(e.type); //click 
        });
        // 4. 阻止默认行为:让链接不跳转 或者 让表单不提交
        var a = document.querySelector('a');
        a.addEventListener('click', function(e) {
            e.preventDefault();
        });
        // 5. 阻止冒泡
        var lis = document.querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {
            lis[i].addEventListener('click', function(e) {
                alert('li');
                e.stopPropagation();
            })
        }
    </script>
</body>
5)事件委托(代理、委派)

在这里插入图片描述
链接: https://www.bilibili.com/video/BV1hT4y1u7qb?p=256.

6)常用的鼠标事件 MouseEvent
① 禁止鼠标右键菜单 contextmenu

在这里插入图片描述

② 禁止选中文字 selectstart

在这里插入图片描述

//1. 禁止鼠标右键菜单
document.addEventListener('contextmenu', function(e) {
    e.preventDefault();
});
//2. 禁止选中文字
document.addEventListener('selectstart', function(e) {
    e.preventDefault();
})
③ 鼠标事件对象

在这里插入图片描述

document.addEventListener('click', function(e) {
    console.log(e.clientX); //距离可视区顶部
    console.log(e.clientY);

    console.log(e.pageX); //距离顶部
    console.log(e.pageY);

    console.log(e.screenX);//距离电脑屏幕
    console.log(e.screenY);
})
④ mouseenter 和 mouseover 的区别

在这里插入图片描述

7)常用的键盘事件 KeyboardEvent

在这里插入图片描述
在这里插入图片描述

9. BOM

1)什么是BOM

在这里插入图片描述

2)BOM 的构成

在这里插入图片描述
在这里插入图片描述

3)window 对象的常见事件
① 窗口加载事件 onload + addEventListener

在这里插入图片描述
在这里插入图片描述

② 调整窗口大小事件 onresize

在这里插入图片描述

4)定时器
① setTimeout() 定时器

在这里插入图片描述

在这里插入图片描述

//5秒后自动关闭广告
var ad = document.querySelector('.ad');
 setTimeout(function() {
     ad.style.display = 'none';
 }, 5000);
② 停止定时器 clearTimeout()

在这里插入图片描述

//停止定时器
 var btn = document.querySelector('button');
 var timer = setTimeout(function() {
     console.log('爆炸了');
 }, 5000);
 btn.addEventListener('click', function() {
     clearTimeout(timer);
 })
③ setInterval() 定时器

在这里插入图片描述
案例:倒计时

<body>
    <span class="hour">1</span>
    <span class="minute">2</span>
    <span class="second">3</span>
    <script>
        var hour = document.querySelector('.hour');
        var minute = document.querySelector('.minute');
        var second = document.querySelector('.second');
        var inputTime = +new Date('2020-8-1 00:00:00'); //用户输入的时间:目标时间
        countDown(); // 先调用一次这个函数,防止第一次刷新页面有空白 
        setInterval(countDown, 1000);

        function countDown() {
            var nowTime = +new Date(); //当前毫秒数
            var times = (inputTime - nowTime) / 1000; //剩余的秒数

            var h = parseInt(times / 60 / 60 % 24); //时
            h = h < 10 ? '0' + h : h;
            hour.innerHTML = h;
            var m = parseInt(times / 60 % 60); //分
            m = m < 10 ? '0' + m : m;
            minute.innerHTML = m;
            var s = parseInt(times % 60); //秒
            s = s < 10 ? '0' + s : s;
            second.innerHTML = s;
        }
    </script>
</body>
④ 停止定时器 clearInterval()

在这里插入图片描述

案例:短信发送倒计时

<body>
    手机号码:<input type="number"><button>发送</button>
    <script>
        var btn = document.querySelector('button');
        var time = 10; //剩下的秒数
        btn.addEventListener('click', function() {
            btn.disabled = true; //禁用
            var timer = setInterval(function() {
                if (time == 0) {
                    clearInterval(timer);
                    btn.disabled = false;
                    btn.innerHTML = '发送';
                    time = 10; //需要重新赋值
                } else {
                    btn.innerHTML = '还剩下' + time + '秒';
                    time--;
                }
            }, 1000);
        });
    </script>
</body>

结果演示:
在这里插入图片描述

5)JS 执行队列
① JS是单线程

在这里插入图片描述

② 同步和异步

在这里插入图片描述
在这里插入图片描述

③ JS 执行机制

在这里插入图片描述
在这里插入图片描述

6)location 对象
① 什么是 location 对象

在这里插入图片描述

② URL

在这里插入图片描述

③ location 对象的属性

在这里插入图片描述

案例:5秒钟之后自动跳转页面

<body>
    <button>点击</button>
    <div></div>
    <script>
        var btn = document.querySelector('button');
        var div = document.querySelector('div');
        var time = 5;
        // fn();
        var timer = setInterval(fn, 1000);

        function fn() {
            if (time == 0) {
                location.href = 'http://www.baidu.com';
                // clearInterval(timer);
            } else {
                div.innerHTML = '您将在' + time + '秒钟之后跳转到首页';
                time--;
            }
        }
    </script>
</body>
④ location 对象的方法

在这里插入图片描述

btn.addEventListener('click', function() {
  //1. 记录浏览历史,可以后退
    // location.assign('http://www.baidu.com');
    //2. 不记录浏览历史,不能后退
    // location.replace('http://www.baidu.com');
    //3. 重新加载
    location.reload(); //默认不填是f5,填写true是强制刷新 ctrl+f5
})
7)navigator 对象

在这里插入图片描述

8)history 对象

在这里插入图片描述

10. PC端网页特效

1)元素偏移量 offset 系列
① offset 概述

在这里插入图片描述

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>offset 属性</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        .father {
            /* position: relative; */
            width: 200px;
            height: 200px;
            background-color: pink;
            margin: 150px;
        }
        
        .son {
            width: 100px;
            height: 100px;
            background-color: purple;
            margin-left: 45px;
        }
        
        .w {
            width: 200px;
            height: 200px;
            background-color: skyblue;
            margin: 0 auto 200px;
            padding: 10px;
            border: 15px solid red;
        }
    </style>
</head>

<body>
    <div class="father">
        <div class="son"></div>
    </div>
    <div class="w"></div>
    <script>
        // offset 系列
        var father = document.querySelector('.father');
        var son = document.querySelector('.son');
        // 1.可以得到元素的偏移 位置 返回的不带单位的数值  
        console.log(father.offsetTop); //150
        console.log(father.offsetLeft); //150
        // 它以带有定位的父亲为准  如果没有父亲或者父亲没有定位 则以 body 为准
        console.log(son.offsetLeft); // 195

        var w = document.querySelector('.w');
        // 2.可以得到元素的大小 宽度和高度 是包含padding + border + width 
        console.log(w.offsetWidth); //250 
        console.log(w.offsetHeight); //250

        // 3. 返回带有定位的父亲 否则返回的是body
        console.log(son.offsetParent); //body 返回带有定位的父亲 否则返回的是body
        console.log(son.parentNode); //<div class="father"> 返回父亲 是最近一级的父亲 亲爸爸 不管父亲有没有定位
    </script>
</body>
② offset 与 style 区别

在这里插入图片描述

③ 案例:仿京东放大镜效果
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>仿京东放大镜效果</title>
    <style>
        .preview_img {
            position: relative;
            width: 400px;
            height: 400px;
            border: 1px solid #ccc;
            margin: 100px 100px;
        }
        
        .preview_img img {
            width: 100%;
        }
        
        .mask {
            display: none;
            position: absolute;
            top: 0;
            left: 0;
            width: 300px;
            height: 300px;
            background-color: #ffde4f;
            /* 半透明 */
            opacity: .5;
            border: 1px solid #ccc;
            cursor: move;
        }
        
        .big {
            display: none;
            position: absolute;
            left: 410px;
            top: 0;
            width: 500px;
            height: 500px;
            background-color: pink;
            border: 1px solid #ccc;
            overflow: hidden;
        }
        
        .big img {
            position: absolute;
            top: 0;
            left: 0;
            width: 800px;
            height: 800px;
        }
    </style>

</head>

<body>
    <div class="preview_img">
        <img src="s.png" alt="">
        <div class="mask"></div>
        <div class="big">
            <img src="big.jpg" alt="" class='bigimg'>
        </div>
    </div>
    <script>
        window.addEventListener('load', function() {
            var preview_img = document.querySelector('.preview_img');
            var mask = document.querySelector('.mask');
            var big = document.querySelector('.big');
            preview_img.addEventListener('mousemove', function() {
                mask.style.display = 'block';
                big.style.display = 'block';
            })
            preview_img.addEventListener('mouseout', function() {
                mask.style.display = 'none';
                big.style.display = 'none';
            })
            preview_img.addEventListener('mousemove', function(e) {
                var x = e.pageX - this.offsetLeft; //鼠标在盒子内的位置
                var y = e.pageY - this.offsetTop;
                var maskX = x - mask.offsetWidth / 2;
                var maskY = y - mask.offsetHeight / 2;
                var maskMaxx = this.offsetWidth - mask.offsetWidth;
                var maskMaxy = this.offsetHeight - mask.offsetHeight;
                if (maskX <= 0) {
                    maskX = 0;
                } else if (maskX >= maskMaxx) {
                    maskX = maskMaxx;
                }
                if (maskY <= 0) {
                    maskY = 0;
                } else if (maskY >= maskMaxy) {
                    maskY = maskMaxy;
                }
                mask.style.left = maskX + 'px';
                mask.style.top = maskY + 'px';
                //大图片的最大移动距离
                var bigimg = document.querySelector('.bigimg');
                var bigMaxx = bigimg.offsetWidth - big.offsetWidth;
                var bigMaxy = bigimg.offsetHeight - big.offsetHeight;
                //大图片移动距离x
                var bigX = maskX * bigMaxx / maskMaxx;
                //大图片移动距离y
                var bigY = maskY * bigMaxy / maskMaxx;
                bigimg.style.left = -bigX + 'px';
                bigimg.style.top = -bigY + 'px';
            })
        })
    </script>
</body>
2)元素可视区 client 系列

在这里插入图片描述
在这里插入图片描述

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>client</title>
    <style>
        div {
            width: 200px;
            height: 200px;
            background-color: pink;
            border: 10px solid red;
            padding: 10px;
        }
    </style>
</head>

<body>
    <div></div>
    <script>
        // client 宽度 和我们offsetWidth 最大的区别就是 包含padding、内容的宽度,不包含边框 
        var div = document.querySelector('div');
        console.log(div.clientWidth);//220
        console.log(div.clientTop); //10 上边框大小
    </script>
</body>
3)元素滚动 scroll 系列
① 元素 scroll 系列属性

在这里插入图片描述

在这里插入图片描述

② 元素被卷去的头部

在这里插入图片描述

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>scroll属性</title>
    <style>
        div {
            width: 200px;
            height: 200px;
            background-color: pink;
            border: 10px solid red;
            padding: 10px;
            /* 自动显示滚动条 */
            overflow: auto;
        }
    </style>
</head>

<body>
    <div>
        我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容 我是内容
    </div>
    <script>
        // scroll 系列
        var div = document.querySelector('div');
        console.log(div.scrollHeight); //311     实际内容的大小:包含padding
        console.log(div.clientHeight); //220     设置的大小:包含padding
        // scroll滚动事件当我们滚动条发生变化会触发的事件
        div.addEventListener('scroll', function() {
            console.log(div.scrollTop); //该元素内容被卷去的顶部部分
        })
    </script>
</body>
③ 案例分析

在这里插入图片描述

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>仿淘宝固定侧边栏</title>
    <style>
        .slider-bar {
            position: absolute;
            left: 50%;
            top: 300px;
            margin-left: 600px;
            width: 45px;
            height: 130px;
            background-color: pink;
        }
        
        .w {
            width: 1200px;
            margin: 10px auto;
        }
        
        .header {
            height: 150px;
            background-color: purple;
        }
        
        .banner {
            height: 250px;
            background-color: skyblue;
        }
        
        .main {
            height: 1000px;
            background-color: yellowgreen;
        }
        
        span {
            display: none;
            position: absolute;
            bottom: 0;
        }
    </style>
</head>

<body>
    <div class="slider-bar">
        <span class="goBack">返回顶部</span>
    </div>
    <div class="header w">头部区域</div>
    <div class="banner w">banner区域</div>
    <div class="main w">主体部分</div>
    <script>
        var slider_bar = document.querySelector('.slider-bar');
        var banner = document.querySelector('.banner');
        // console.log(banner.offsetTop);
        var bannerTop = banner.offsetTop;
        var slider_barTop = slider_bar.offsetTop - bannerTop;
        var main = document.querySelector('.main');
        var mainTop = main.offsetTop;
        var goback = document.querySelector('.goBack');
        document.addEventListener('scroll', function() {
            console.log(window.pageYOffset); //页面被卷去的头部部分
            if (window.pageYOffset >= bannerTop) {
                slider_bar.style.position = 'fixed';
                slider_bar.style.top = slider_barTop + 'px';
            } else {
                slider_bar.style.position = 'absolute';
                slider_bar.style.top = 300 + 'px';

            }
            if (window.pageYOffset >= mainTop) {
                goback.style.display = 'block';
            } else {
                goback.style.display = 'none';
            }
        })
    </script>
</body>
④ 页面被卷去的头部兼容性解决方案

在这里插入图片描述

4) 三大系列总结

在这里插入图片描述
在这里插入图片描述

5) 动画函数封装
① 缓动动画原理

在这里插入图片描述
在这里插入图片描述

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>缓动动画公式:(目标值-现在的位置)/10</title>
    <style>
        div {
            position: absolute;
            left: 0;
            width: 100px;
            height: 100px;
            background-color: pink;
        }
    </style>
</head>

<body>
    <button class="btn400">点击走到400</button>
    <button class="btn800">点击走到800</button>

    <div></div>
    <script>
        // 简单动画函数封装obj目标对象 target 目标位置
        function animate(obj, target, callback) {
            // 避免在内存中开辟空间
            clearInterval(obj.timer); //只有一个定时器运行
            obj.timer = setInterval(() => {
                var step = (target - obj.offsetLeft) / 10;
                step = step > 0 ? Math.ceil(step) : Math.floor(step);
                if (obj.offsetLeft == target) {
                    //停止定时器
                    clearInterval(obj.timer);
                    if (callback) {
                        callback(); //调用函数
                    }
                }
                obj.style.left = obj.offsetLeft + step + 'px';
            }, 15);
        }

        var div = document.querySelector('div');
        var btn400 = document.querySelector('.btn400');
        var btn800 = document.querySelector('.btn800');


        btn400.addEventListener('click', function() {
            animate(div, 400);
        })
        btn800.addEventListener('click', function() {
            animate(div, 800, function() {
                div.style.backgroundColor = 'purple';
            });
        })
    </script>
</body>
② 动画函数封装到单独JS文件里面 animate.js
// 简单动画函数封装obj目标对象 target 目标位置
function animate(obj, target, callback) {
    // 避免在内存中开辟空间
    clearInterval(obj.timer); //只有一个定时器运行
    obj.timer = setInterval(() => {
        var step = (target - obj.offsetLeft) / 10;
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        if (obj.offsetLeft == target) {
            //停止定时器
            clearInterval(obj.timer);
            if (callback) {
                callback(); //调用函数
            }
        }
        obj.style.left = obj.offsetLeft + step + 'px';
    }, 15);
}
6) 常见网页特效案例
① 网页轮播图

在这里插入图片描述

第一步:
在这里插入图片描述

第二步:
在这里插入图片描述
第三步:
在这里插入图片描述

第四步:
在这里插入图片描述

第五步:

在这里插入图片描述

第六步:

在这里插入图片描述

第七步:
在这里插入图片描述
第八步:
按照右侧按钮,修改左侧按钮。

第九步:
在这里插入图片描述

② 节流阀

在这里插入图片描述
完整代码:
index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>轮播图</title>
    <link rel="stylesheet" href="./index.css">
    <script src="./animate.js"></script>
    <script src="./index.js"></script>
</head>

<body>
    <!-- 焦点图模块 -->
    <div class="focus">
        <!-- 左侧按钮 -->
        <a href="javascript:;" class="arrow-l">&lt;</a>
        <!-- 右侧按钮 -->
        <a href="javascript:;" class="arrow-r"> &gt; </a>
        <!-- 核心的滚动区域 -->
        <ul>
            <li>
                <a href="#"><img src="../img/focus.png" alt=""></a>
            </li>
            <li>
                <a href="#"><img src="../img/focus1.jpg" alt=""></a>
            </li>
            <li>
                <a href="#"><img src="../img/focus2.jpg" alt=""></a>
            </li>
            <li>
                <a href="#"><img src="../img/focus3.jpg" alt=""></a>
            </li>
        </ul>
        <!-- 小圆圈 -->
        <ol class="circle"></ol>
    </div>
</body>

</html>

index.css

* {
    margin: 0;
    padding: 0;
}

li {
    list-style: none;
}

a {
    text-decoration: none;
}

.focus {
    position: relative;
    width: 721px;
    height: 455px;
    margin: 100px auto;
    background-color: purple;
    overflow: hidden;
}

.focus ul {
    /* 加了定位之后才能使用动画函数 */
    position: absolute;
    top: 0;
    left: 0;
    width: 600%;
}

.focus ul li {
    float: left;
}

.arrow-l,
.arrow-r {
    display: none;
    position: absolute;
    top: 50%;
    margin-top: -20px;
    width: 24px;
    height: 40px;
    background: rgba(0, 0, 0, .3);
    text-align: center;
    line-height: 40px;
    color: #fff;
    font-family: 'icomoon';
    font-size: 18px;
    z-index: 2;
}

.arrow-r {
    right: 0;
}

.circle {
    position: absolute;
    bottom: 10px;
    left: 50px;
}

.circle li {
    float: left;
    width: 8px;
    height: 8px;
    /* background-color: #fff; */
    border: 2px solid rgba(255, 255, 255, 0.5);
    margin: 0 3px;
    border-radius: 50%;
    /*鼠标经过显示小手*/
    cursor: pointer;
}

.current {
    background-color: #fff;
}

animate.js

// 简单动画函数封装obj目标对象 target 目标位置
function animate(obj, target, callback) {
    // 避免在内存中开辟空间
    clearInterval(obj.timer); //只有一个定时器运行
    obj.timer = setInterval(() => {
        var step = (target - obj.offsetLeft) / 10;
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        if (obj.offsetLeft == target) {
            //停止定时器
            clearInterval(obj.timer);
            /*  if (callback) {
                 callback(); //调用函数
             } */
            //短路运算
            callback && callback();
        }
        obj.style.left = obj.offsetLeft + step + 'px';
    }, 15);
}

index.js

window.addEventListener('load', function() {
    //1. 获取元素
    var focus = document.querySelector('.focus');
    var arrow_l = document.querySelector('.arrow-l');
    var arrow_r = document.querySelector('.arrow-r');
    // 获取图片的宽度
    var focusWidth = focus.offsetWidth;
    //2. 鼠标经过focus 就显示隐藏左右按钮,并清除自动播放定时器
    focus.addEventListener('mouseenter', function() {
        arrow_l.style.display = 'block';
        arrow_r.style.display = 'block';
        clearInterval(timer);
        timer = null; //清除定时器变量
    })
    focus.addEventListener('mouseleave', function() {
        arrow_l.style.display = 'none';
        arrow_r.style.display = 'none';
        //鼠标离开,开启自动播放定时器
        timer = setInterval(function() {
            //手动调用 右侧按钮点击事件
            arrow_r.click();
        }, 2000)
    })

    //3. 动态生成小圆圈
    var ol = document.querySelector('.circle');
    var ul = focus.querySelector('ul');
    for (var i = 0; i < ul.children.length; i++) {
        //3.1 创建li,并设置自定义属性:索引,插入到ol
        var li = document.createElement('li');
        //为小圆圈设置自定义属性:索引
        li.setAttribute('data-index', i);
        ol.appendChild(li);
        //4. 创建li的同时,为它绑定事件

        li.addEventListener('click', function() {
            for (var j = 0; j < ol.children.length; j++) {
                ol.children[j].className = '';
            }
            this.className = 'current';

            //5. 点击小圆圈,移动图片 当然移动的是ul
            //获取当前小圆圈的索引
            var index = this.getAttribute('data-index');
            //当点击 某个小圆圈的时候,就要把当前索引号给num,和circle
            num = this.getAttribute('data-index');
            circle = this.getAttribute('data-index');
            //移动图片
            animate(ul, -(index * focusWidth));
        })
    }
    ol.children[0].className = 'current';
    //6. 克隆第一张图片,放到ul最后面
    var first = ul.children[0].cloneNode(true);
    ul.appendChild(first);
    //7. 点击右侧按钮,滚动一张照片(无缝滚动)
    var num = 0;
    //8.1 控制小圆圈的播放
    var circle = 0;
    //11.节流阀
    var flag = true;
    //8. 右侧按钮做法
    arrow_r.addEventListener('click', function() {
        if (flag) {
            //11.1 关闭节流阀
            flag = false;
            // 如果走到了最后复制的一张图片,此时ul要快速复原,left改为0
            if (num == ul.children.length - 1) {
                ul.style.left = 0;
                num = 0;
            }
            num++;
            animate(ul, -(num * focusWidth), function() {
                flag = true; //打开节流阀
            });
            // 8.1 点击右侧按钮,小圆圈跟随一起变化
            circle++;
            //8.2 如果circle==4说明走到克隆的最后一张图片了,circle复原为0
            if (circle == ol.children.length) {
                circle = 0;
            }
            circlrChange();
        }

    });
    //9. 左侧按钮做法
    arrow_l.addEventListener('click', function() {
        if (flag) {
            flag = false;
            //如果走到了第一张图片,此时ul要快速定位到最后一张,left改为0
            if (num == 0) {
                ul.style.left = -(ul.children.length - 1) * focusWidth + 'px';
                num = ul.children.length - 1;
            }
            num--;
            animate(ul, -(num * focusWidth), function() {
                flag = true;
            });
            // 8. 点击左侧按钮,小圆圈跟随一起变化
            circle--;
            //8.2 如果circle<0,说明走到第一张图片了,circle置为最后一个小圆圈的索引
            if (circle < 0) {
                circle = ol.children.length - 1;
            }
            circlrChange()
        }
    });

    function circlrChange() {
        //清除其余小圆圈的current类名
        for (var j = 0; j < ol.children.length; j++) {
            ol.children[j].className = '';
        }
        //留下当前小圆圈的current类名
        ol.children[circle].className = 'current';
    }
    //10. 自动播放轮播图
    var timer = setInterval(function() {
        //手动调用 右侧按钮点击事件
        arrow_r.click();
    }, 2000)
})

11. 本地存储

1) 本地存储的概述

在这里插入图片描述

2) window.sessionStorage

在这里插入图片描述

<body>
    <input type="text">
    <button class="set">存储数据</button>
    <button class="get">获取数据</button>
    <button class="remove">删除数据</button>
    <button class="del">清空所有数据</button>
    <script>
        var ipt = document.querySelector('input');
        var set = document.querySelector('.set');
        var get = document.querySelector('.get');
        var remove = document.querySelector('.remove');
        var del = document.querySelector('.del');
        // 1. 存储数据
        set.addEventListener('click', function() {
            // 当我们点击了之后,就可以把表单里面的值存储起来
            var val = ipt.value;
            sessionStorage.setItem('uname', val);
            sessionStorage.setItem('pwd', val);
        });
        // 2. 获取数据
        get.addEventListener('click', function() {
            // 当我们点击了之后,就可以把表单里面的值获取过来
            console.log(sessionStorage.getItem('uname'));
        });
        // 3. 删除数据
        remove.addEventListener('click', function() {
            sessionStorage.removeItem('uname');
        });
        // 4. 清除所有数据
        del.addEventListener('click', function() {
            // 当我们点击了之后,清除所有的
            sessionStorage.clear();
        });
    </script>
</body>
3) window.localStorage

在这里插入图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值