今日学习任务总结
01-ES6语法新特性介绍
-
1.ES6全称:ECMAScript-2015, 是2015年推出的全新的js语法
-
2.一定要切记: 语法的更新,其实就是在原有的语法基础上
新增了几个新
的语法。 而不是说把我们之前学习的js语法给完全替换覆盖
。- 因此,我们学习ES6语法之后,相当于就是在之前的语法基础上,在额外多学几个js语法而已。 现在几乎很少有人会把ES5与ES6分的非常清楚。 基本上直接拿来用就可以了,哪个方便用哪个。
-
ES6文档推荐:https://es6.ruanyifeng.com/
1.1-变量声明let与const
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<script>
/*
1.学习目标 : 掌握ES6新增两个关键字 let 与 const
* let 与 const的作用是声明变量,类似于ES5的let关键字
2.学习路线(对比法学习)
(1) 复习ES5的let关键字两个特点
(2) 介绍ES6的let与const关键字的两个特点
(3) 介绍let与const的区别 与 注意点
*/
/* 1.ES5语法变量特点 */
// 1.1 变量会提升
console.log(num) //undefined
var num = 10
// 1.2 没有块级作用域
for (var i = 1; i < 5; i++) {
console.log('循环内' + i)
}
console.log('循环外' + i) //5
/* 2.ES6新增两种变量声明方式(let与const),类似于let
(1).不会提升
(2).有块级作用域
*/
// (1)如果打印undefined,说明提升了 (2)如果报错,说明没有提升
// console.log(a);//报错
// let a = 10;
// (2)如果打印5,说明没有块级作用域 (2)如果报错,说明有块级作用域
for (let j = 1; j < 5; j++) {
console.log(j)
}
// console.log(j);
/* 3.let与const区别
* 注意点:ES6中变量不能重复声明,否则会报错
*/
//let声明:变量,允许修改
let a = 10
a = 20
// let a = 30;//程序报错,不允许重复声明
console.log(a)
//const声明:常量,只可以声明的时候赋值一次,之后无法修改
const b = 100
// b = 200;//程序报错
console.log(b)
</script>
</body>
</html>
1.2-解构赋值语法
- 解构赋值语法 : 其实就是变量赋值语法的简写形式
1.2.1-对象的解构赋值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<script>
/*
1.学习目标:掌握对象的解构赋值语法
* 解构赋值本质 就是 变量赋值语法的简写形式
2.学习路径 : 对比法学习(ES5与ES6对比)
(1)取出 对象的属性值 赋值给 变量
(2)取出 变量的值 赋值给 对象的属性
(3)设置 解构赋值语法 的默认值
*/
//解构赋值语法 : 其实就是变量赋值语法的简写形式
//1:取出 对象的属性 赋值 给变量
let obj = {
name: '张三',
age: 18,
sex: '男'
}
/* ES5 */
// let name = obj.name;
// let age = obj.age;
// let sex = obj.sex;
// console.log(name,age,sex);
/* ES6 */
/* a.这行代码本质:声明三个变量 name,age,sex。取出右边obj对象对应的属性名赋值给左边的变量*/
// let {name,age,sex} = obj;
// console.log(name,age,sex);
/* b.由于obj对象没有score属性,所以变量score的值为undefined。 */
// let {name,score} = obj;
// console.log(name,score);
/* c. sex:gender 的含义 : let gender = obj.sex */
// let {name,sex:gender} = obj;
// console.log(name,gender);
//2:取出变量的值 赋值给对象的属性
// let name = '李四';
// let age = 20;
// let sex = '男';
// let sayHi = function(){
// console.log('你好');
// };
/* ES5 */
// let person = {
// name : name,
// age : age,
// gender : sex,
// sayHi :sayHi
// };
// console.log(person);
/* ES6 */
// let person = {
// name,//等价于 name:name
// age,
// gender:sex,//如果属性名和变量名不一致,还是按照以前ES5的写法来赋值
// sayHi,
// play(){//等价于:play:function(){}
// console.log('学习使我快乐');
// }
// };
// console.log(person);
//3. 设置 解构赋值语法 的默认值
let student = {
name: '班长',
age: 38,
sex: '女'
}
/*
(1) name = '坤哥'
a. 声明变量name : let name;
b. 取出student对象的name属性值赋值给name : student.name
c. 如果student对象没有name属性则赋值坤哥 : if(student.name){ name = student.name }else{ name = '坤哥' }
(2) sex:gender = '男'
a. 声明变量gender : let gender;
b. 取出student对象的sex属性值赋值给gender : student.sex
c. 如果student对象没有sex属性则赋值男 : if(student.sex){ gender = student.sex }else{ gender = '男' }
*/
let { name = '坤哥', score = 88, sex: gender = '男' } = student
console.log(name, score, gender) //班长 88 女
</script>
</body>
</html>
1.2.2-数组解构赋值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<script>
//数组解构赋值
let arr = [10, 20, 30]
/* ES5 */
// let n1 = arr[0];
// let n2 = arr[1];
// let n3 = arr[2];
// console.log(n1,n2,n3);
/* ES6 */
let [n1, n2, n3 = 50, n4 = 100] = arr
console.log(n1, n2, n3, n4) // 10 20 30 100
</script>
</body>
</html>
1.2.3-函数参数解构赋值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<script>
/*
1.学习目标 : 掌握函数参数的解构赋值
2.学习路线
(1)复习 函数 传参的本质是 实参给形参赋值的过程
(2)使用解构赋值语法 给函数传参
(3)使用解构赋值语法 设置 函数的默认参数
*/
/* (1) ES5 :函数传参 */
/**
* @description:
* @param {Object} obj:对象类型 {name:名字 age:年龄 sex:性别}
* @return:
*/
// function fn(obj){
// console.log(obj);
// //声明三个变量接收对象的参数值
// let name = obj.name;
// let age = obj.age;
// let sex = obj.sex;
// console.log(name,age,sex);
// };
// fn({
// name:'黑马李宗盛',
// age:32,
// sex:'男'
// });
/* (2) ES6 :函数传参 */
// function fn1({name,age,sex}){
// //声明三个变量接收对象的参数值
// console.log(name,age,sex);
// };
// fn1({
// name:'黑马李宗盛',
// age:32,
// sex:'男'
// });
//添加解构语法默认值
// function fn2({name = '班长',age = 38,sex:gender='女'}){
// //声明三个变量接收对象的参数值
// console.log(name,age,gender);
// };
// fn2({
// name:'黑马李宗盛',
// });
/* (3)函数默认参数 */
/* ES5:使用逻辑或短路运算实现 */
// function fn(n1,n2,n3){
// n1 = n1 || 10;
// n2 = n2 || 20;
// n3 = n3 || 30;
// console.log(n1,n2,n3);
// };
// fn(5,8);
// fn();
/* ES6:使用解构赋值语法默认值实现 */
function fn (n1 = 10, n2 = 20, n3 = 30) {
console.log(n1, n2, n3)
}
fn(5, 8)
fn()
</script>
</body>
</html>
1.3-箭头函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<script>
/*
1.学习目标:学会使用ES6的箭头函数
* 箭头函数 => 其实是 function 关键字的简写形式
* 写法: 将function关键字使用 => 符号代替
2.学习路线
(1)介绍箭头函数的常见用法 : 重点
(2)介绍箭头函数的其他用法 : 了解
*/
//1.箭头函数常见用法
//1.1 无参无返回函数
/* ES5 */
let fn = function () {
console.log('111')
}
fn()
/* ES6
箭头函数规则: (1)function变成 箭头符号 => (2)形参小括号写到箭头 => 左边
*/
let fn1 = () => {
console.log('222')
}
fn1()
//1.2 有参有返回函数
/* ES5 */
let add = function (a, b) {
return a + b
}
console.log(add(10, 20))
/* ES6 */
let add1 = (a, b) => {
return a + b
}
console.log(add1(100, 200))
//2.箭头函数其他用法
//2.1 如果函数只有一个形参,则可以省略形参小括号
let fn2 = a => {
return a * 2
}
console.log(fn2(20)) //40
//2.2 如果函数体只有一行代码,则可以省略函数体大括号
//注意点: 如果省略函数体大括号,则返回值也要省略return
//下面代码等价于: let fn3 = function(a){ return a*2 }
let fn3 = a => a * 2
console.log(fn3(30)) //60
</script>
</body>
</html>
1.4-箭头函数中的this
- (1)
箭头函数
中没有this
: 这意味着 call() apply() bind()无法修改箭头函数中的this
- (2)箭头函数中的this指向 :
访问上一个作用域的this
- 说人话:函数在哪个作用域声明,this就是谁 (本质是通过作用域链访问上一个作用域中的this)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
/*ES6箭头函数中的this
(1)箭头函数中没有this : 这意味着 call() apply() bind() 无法修改箭头函数中的this
(2)箭头函数中的this指向 :访问上一个作用域的this
说人话:函数在哪个作用域声明,this就是谁 (本质是通过作用域链访问上一个作用域中的this)
*/
//1.全局函数 : window
let fn = () => {
console.log(this);
};
fn();//window
fn.call({ a: 11 });//window 箭头函数中的this无法修改,因为箭头函数没有this
//2.对象方法: window (因为对象无法开辟作用域,obj所在作用域还是window)
let obj = {
sayHi: () => {
console.log('学习使我快乐');
console.log(this);
}
};
obj.sayHi();//window
//3.局部函数
let person = {
play: function () {
console.log('play中的this');
console.log(this);//person
//在局部作用域声明一个箭头函数
let fn2 = () => {
console.log('fn2在一级链中被声明,我的this就是一级链中的this');
console.log(this);//person
};
fn2();
}
};
person.play();
</script>
</body>
</html>
1.5-展开运算符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<script>
/* 学习目标
1.拓展运算符: ...
2.作用:类似于 对象遍历的一种简写形式
3.应用场景介绍
*/
//1.基本使用
let person = {
name: '班长',
age: 38,
sex: '男'
}
let student = {
score: 99,
girlFriend: '代码'
}
let banzhang = {
...person, //相当于遍历person的属性名和属性值 赋值给班长对象
...student,
hobby: '学习'
}
console.log(banzhang) //{ name: '班长',age: 38,sex: '男',score: 99,girlFriend: '代码',hobby: '学习' }
//2.应用场景
//2.1 连接两个数组
let arr1 = [10, 20, 30]
let arr2 = [40, 50, 60]
/* ES5写法 */
//concat:连接数组
// let arr3 = arr1.concat(arr2);
//连接之后 想要继续添加元素 需要继续调用push
// arr3.push(70);
// console.log(arr3);
/* ES6写法 */
let arr3 = [...arr1, ...arr2, 70]
console.log(arr3)
//2.2 求数组最大值和最小值
let arr = [88, 25, 60, 90, 100]
/* ES5写法 */
//利用apply传参特点 : 自动遍历arr,逐个传参
// let max = Math.max.apply(Math,arr);
// console.log(max);
/* ES6写法 */
let max = Math.max(...arr)
console.log(max)
</script>
</body>
</html>
1.6-数据类型Set
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<script>
/*
1. Set :集合。 ES6新增的数据类型,类似于ES5的数组
2. Set与Array最大的区别 : Set不支持重复元素
3. Set经典应用场景 : 数组去重
*/
//1.基本使用
let set1 = new Set([10, 20, 30, 40, 10, 40])
console.log(set1) //Set(4) {10, 20, 30, 40}
//2.经典场景:数组去重
// let arr = [...set1];
// console.log(arr);//[ 10, 20, 30, 40 ]
//经典面试题:请使用一行代码实现数组去重
let arr = [20, 60, 88, 50, 20, 66, 100]
let arr1 = [...new Set(arr)]
console.log(arr1) //[ 20, 60, 88, 50, 66, 100 ]
</script>
</body>
</html>
02-数组迭代方法
官网文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array
以下所有的方法,都可以使用传统的for循环来代替,只是语法不同而已
数组几种遍历介绍(共同点:回调函数一样) | 应用场景 | 回调执行次数 | 函数返回值 | 回调是否需要return |
---|---|---|---|---|
map遍历 | 映射数组 | == 原数组长度 | 新数组(==) | 一定要return(当前元素) |
filter遍历 | 过滤数组 | == 原数组长度 | 新数组(!=) | return true(元素添加到新数组) |
forEach遍历 | 遍历数组 | == 原数组长度 | 无 | 无 |
some遍历 | 找出符合条件的数 | != 原数组长度 | 布尔类型 | return true;循环结束 |
every遍历 | 判断所有元素是否符合条件 | != 原数组长度 | 布尔类型 | return true; 循环继续 |
findIndex遍历 | 获取符合条件的第一个元素位置(下标) | != 原数组长度 | 数字 | return true; 循环结束 |
includes方法(底层是遍历) | 判断数组/字符串是否包含某一个值 | 无回调 | 布尔类型 | 无回调 |
1.1-数组map遍历
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
/*
1.map应用场景:利用某种规则映射得到一个新数组
说人话:遍历每一个元素,并对每一个元素做对应的处理,返回一个新数组
例如:将数组中的每一个元素+1
例如:将数组中每一个元素 * 2
例如:100以上的商品打八折
2.注意点:
a. 回调函数执行次数 == 数组长度
* 数组中有多少个元素,回调函数就会执行几次
b. map函数返回的新数组长度 == 原数组长度
c. 回调函数中一定要return,返回的是当前遍历的元素值
* 如果不return,新数组中每一个元素都变成了undefined
*/
let arr = [23, 31, 60, 88, 90, 108, 260];
//(1)需求:数组中每一个元素+1
/**
* @description: 数组map遍历
* @param {Function}:回调函数 (元素,下标)=>{ return 新元素 }
* @return: 返回一个新数组
*/
let arr1 = arr.map((value, index) => {
return value + 1;//让每一个元素的值+1
});
console.log(arr1);
//(2)需求:数组中每一个元素*2
let arr2 = arr.map((value, index) => {
return value * 2;//让每一个元素的值 * 2
});
console.log(arr2);
//(3)需求3: 超过100的商品打八折
let arr3 = arr.map((value, index) => {
if(value > 100){
return value*0.8;
}else{
return value;
}
});
console.log(arr3);
</script>
</body>
</html>
1.2-数组filter遍历
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
/*
1.filter应用场景:用于筛选数组中满足条件的元素,返回筛选后的新数组
例如:找出数组中的偶数
2.注意点:
a. 回调函数执行次数 == 数组长度
* 数组中有多少个元素,回调函数就会执行几次
b. filter函数返回的新数组长度 != 原数组长度
c. 回调函数一定要return, 返回一个布尔类型值
结果为true: 当前遍历元素就会添加到新数组中
结果为false:当前遍历元素不会添加到新数组中
*/
let arr = [23, 31, 60, 88, 90, 108, 260];
//(1)需求:找出数组中的偶数
/**
* @description: 数组filter遍历
* @param {Function}:回调函数 (元素,下标)=>{}
* @return: 返回一个新数组
*/
let arr1 = arr.filter((item) => {
return item %2 == 0;
});
console.log(arr1);//[60, 88, 90, 108, 260]]
</script>
</body>
</html>
1.3-数组forEach遍历
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
/*
1.forEach应用场景:用于遍历数组,相当于for循环另一种写法
2.注意点:
a. 回调函数执行次数 == 数组长度
* 数组中有多少个元素,回调函数就会执行几次
b. forEach函数没有返回值
c. 回调函数不需要return
* 就算手动return,也不会结束循环
*/
let arr = [23, 31, 60, 88, 90, 108, 260];
/**
* @description: 数组forEach遍历
* @param {Function}:回调函数 (元素,下标)=>{}
* @return: 无
*/
arr.forEach((item,index) => {
console.log(`下标为${index}的元素是${item}`);
});
</script>
</body>
</html>
1.4-数组some遍历
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
/*
1.some应用场景:用于判断数组中是否存在满足条件的元素
2.注意点:
a. 回调函数执行次数 != 数组长度
* some函数在遍历的时候可以中途结束
b. some函数返回一个布尔类型值
c. 回调函数返回布尔类型值用于结束遍历
return true; //遍历结束,且some函数返回值为true
(默认) return false; //遍历继续,且some函数返回值为false
*/
//需求:判断数组中没有负数
let arr = [23, 31, 60, 88,-50, 90, 108, 260];
/**
* @description: 数组some遍历
* @param {Function}:回调函数 (元素,下标)=>{}
* @return: 布尔类型值
*/
let arr1 = arr.some((item,index) => {
console.log(`下标为${index}的元素是${item}`);
// if(item < 0){
// return true;//循环结束
// };
//简写成
return item<0;
});
console.log(arr1);
</script>
</body>
</html>
1.5-数组every遍历
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
/*
1.every应用场景:用于判断数组中是否所有元素都满足条件
* every与some功能类似,只是写法不同
2.注意点:
a. 回调函数执行次数 != 数组长度
b. every函数返回一个布尔类型值
c. 回调函数返回布尔类型值用于结束遍历
return true; //遍历继续,且every函数返回值为true
(默认)return false; //遍历结束,且every函数返回值为false
*/
//需求:判断数组中没有负数
let arr = [23, 31, 60, 88,-50, 90, 108, 260];
/**
* @description: 数组every遍历
* @param {Function}:回调函数 (元素,下标)=>{}
* @return: 布尔类型值
*/
let arr1 = arr.every((item,index) => {
console.log(`下标为${index}的元素是${item}`);
// if(item > 0){
// return true;//如果是正数,循环继续
// }
//简写成
return item>0;
});
console.log(arr1);
</script>
</body>
</html>
1.6-数组findindex方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
/*
1.数组findIndex方法
1.1 作用 : 获取符合条件的第一个元素位置(下标)
1.2 语法 : arr.findIndex( (item,index)=>{ return true/false } )
返回值: 符合则返回元素下标,不符合则返回-1
1.3 应用场景 : 适用于数组中元素为对象类型,比传统for循环要高效
*/
let arr1 = [
{ name: '张三', age: 20 },
{ name: '李四', age: 30 },
{ name: '王五', age: 25 },
{ name: '赵六', age: 33 },
{ name: '小七', age: 10 },
];
//1.数组findIndex方法 : 获取符合条件的第一个元素位置(下标)
//示例:查找arr1中第一个未成年在什么位置
let res1 = arr1.findIndex((item,index)=>{
/* 回调函数
return true : 循环中断,findIndex方法返回值为当前index值
return false: 循环继续,如果数组全部遍历完还是没有返回true,则finedIndex方法最终返回-1
*/
// if(item.age<18){
// return true;
// }else{
// return false;
// };
return item.age < 18;
});
console.log(res1);
</script>
</body>
</html>
1.7-数组reduce方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
/*
1.数组reduce方法
1.1 作用 : 遍历数组元素,为每一个元素执行一次回调函数
1.2 语法 : arr.reduce( (sum,value)=>{ return sum + value } )
返回值: 最终sum值
1.3 应用场景 : 数组求和/平均值/最大值/最小值
1.4 注意点:最好给一个初始值,避免空数组报错
*/
let arr1 = [20, 55, 80, 70, 92, 35];
//sum : 初始值,默认为数组第一个元素
//value : 数组得每一个元素,默认为数组第二个元素
//res1 :
let res1 = arr1.reduce((sum, value) => {
//这里必须要return,相当于把本次计算得结果赋值给下一次得sum : sum = sum + value;
return sum + value;
},0);
console.log(res1);
//下面这种写法与上面等价,ES6箭头函数如果只有一行代码则可以省略大括号,且省略return
console.log(arr1.reduce((sum, value) => sum + value),0);
//求最大值
let res2 = arr1.reduce((sum, value) => Math.max(sum, value),0);
console.log( res2 );
</script>
</body>
</html>
03-实战案例
1.1 some场景:小兔仙非空判断与正则判断
- some作用: 判断数组中是否有满足条件的元素
1.2-every场景: 全选框
1.3-filter场景:筛选数组
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>商品渲染</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.list {
width: 990px;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
}
.item {
width: 240px;
margin-left: 10px;
padding: 20px 30px;
transition: all 0.5s;
margin-bottom: 20px;
}
.item:nth-child(4n) {
margin-left: 0;
}
.item:hover {
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2);
transform: translate3d(0, -4px, 0);
cursor: pointer;
}
.item img {
width: 100%;
}
.item .name {
font-size: 18px;
margin-bottom: 10px;
color: #666;
}
.item .price {
font-size: 22px;
color: firebrick;
}
.item .price::before {
content: "¥";
font-size: 14px;
}
.filter {
display: flex;
width: 990px;
margin: 0 auto;
padding: 50px 30px;
}
.filter a {
padding: 10px 20px;
background: #f5f5f5;
color: #666;
text-decoration: none;
margin-right: 20px;
}
.filter a.active {
background: #05943c;
color: #fff;
}
</style>
</head>
<body>
<div class="filter">
<a href="javascript:;">0-100元</a>
<a href="javascript:;">100-300元</a>
<a href="javascript:;">300元以上</a>
<a href="javascript:;" class="active">全部区间</a>
</div>
<div class="list">
<!-- <div class="item">
<img src="" alt="">
<p class="name"></p>
<p class="price"></p>
</div> -->
</div>
<script>
// 1. 初始化数据
const goodsList = [
{
id: "4001172",
name: "称心如意手摇咖啡磨豆机咖啡豆研磨机",
price: "289.00",
picture:
"https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg"
},
{
id: "4001594",
name: "日式黑陶功夫茶组双侧把茶具礼盒装",
price: "288.00",
picture:
"https://yanxuan-item.nosdn.127.net/3346b7b92f9563c7a7e24c7ead883f18.jpg"
},
{
id: "4001009",
name: "竹制干泡茶盘正方形沥水茶台品茶盘",
price: "109.00",
picture:
"https://yanxuan-item.nosdn.127.net/2d942d6bc94f1e230763e1a5a3b379e1.png"
},
{
id: "4001874",
name: "古法温酒汝瓷酒具套装白酒杯莲花温酒器",
price: "488.00",
picture:
"https://yanxuan-item.nosdn.127.net/44e51622800e4fceb6bee8e616da85fd.png"
},
{
id: "4001649",
name: "大师监制龙泉青瓷茶叶罐",
price: "139.00",
picture:
"https://yanxuan-item.nosdn.127.net/4356c9fc150753775fe56b465314f1eb.png"
},
{
id: "3997185",
name: "与众不同的口感汝瓷白酒杯套组1壶4杯",
price: "108.00",
picture:
"https://yanxuan-item.nosdn.127.net/8e21c794dfd3a4e8573273ddae50bce2.jpg"
},
{
id: "3997403",
name: "手工吹制更厚实白酒杯壶套装6壶6杯",
price: "99.00",
picture:
"https://yanxuan-item.nosdn.127.net/af2371a65f60bce152a61fc22745ff3f.jpg"
},
{
id: "3998274",
name: "德国百年工艺高端水晶玻璃红酒杯2支装",
price: "139.00",
picture:
"https://yanxuan-item.nosdn.127.net/8896b897b3ec6639bbd1134d66b9715c.jpg"
}
]
//1.获取a标签
let aList = document.querySelectorAll(".filter>a")
//2.注册事件
for (let i = 0; i < aList.length; i++) {
aList[i].onclick = function() {
//3.排他
//(1)类选择器 干掉兄弟
document.querySelector("a.active").classList.remove("active")
//(2)复活自己
this.classList.add("active")
//筛选
if (i == 0) {// 0 - 100
renderData( goodsList.filter(item => item.price < 100) )
} else if (i == 1) {
//100-300
renderData( goodsList.filter(item => item.price >= 100 && item.price < 300) )
} else if( i == 2){
renderData( goodsList.filter(item => item.price >= 300) )
}else{
renderData( goodsList )
}
}
}
const renderData = arr => {
document.querySelector(".list").innerHTML = arr.map(item => `<div class="item">
<img src="${item.picture}" alt="">
<p class="name">${item.name}</p>
<p class="price">${item.price}</p>
</div>`).join("")
}
//页面一加载,默认渲染所有数据
renderData( goodsList )
</script>
</body>
</html>
1.4-reduce场景:购物车求和
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.list {
width: 990px;
margin: 100px auto 0;
}
.item {
padding: 15px;
transition: all .5s;
display: flex;
border-top: 1px solid #e4e4e4;
}
.item:nth-child(4n) {
margin-left: 0;
}
.item:hover {
cursor: pointer;
background-color: #f5f5f5;
}
.item img {
width: 80px;
height: 80px;
margin-right: 10px;
}
.item .name {
font-size: 18px;
margin-right: 10px;
color: #333;
flex: 2;
}
.item .name .tag {
display: block;
padding: 2px;
font-size: 12px;
color: #999;
}
.item .price , .item .sub-total{
font-size: 18px;
color: firebrick;
flex: 1;
}
.item .price::before, .item .sub-total::before, .amount::before {
content: "¥";
font-size: 12px;
}
.item .spec {
flex: 2;
color: #888;
font-size: 14px;
}
.item .count {
flex: 1;
color: #aaa;
}
.total {
width: 990px;
margin: 0 auto;
display: flex;
justify-content: flex-end;
border-top: 1px solid #e4e4e4;
padding: 20px;
}
.total .amount {
font-size: 18px;
color: firebrick;
font-weight: bold;
margin-right: 50px;
}
</style>
</head>
<body>
<div class="list">
<!-- <div class="item">
<img src="https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg" alt="">
<p class="name">称心如意手摇咖啡磨豆机咖啡豆研磨机 <span class="tag">【赠品】10优惠券</span></p>
<p class="spec">白色/10寸</p>
<p class="price">289.90</p>
<p class="count">x2</p>
<p class="sub-total">579.80</p>
</div> -->
</div>
<div class="total">
<div>合计:<span class="amount">1000.00</span></div>
</div>
<script>
const goodsList = [
{
id: '4001172',
name: '称心如意手摇咖啡磨豆机咖啡豆研磨机',
price: 289,
picture: 'https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg',
count: 2,
},
{
id: '4001009',
name: '竹制干泡茶盘正方形沥水茶台品茶盘',
price: 109,
picture: 'https://yanxuan-item.nosdn.127.net/2d942d6bc94f1e230763e1a5a3b379e1.png',
count: 3,
},
{
id: '4001874',
name: '古法温酒汝瓷酒具套装白酒杯莲花温酒器',
price: 488,
picture: 'https://yanxuan-item.nosdn.127.net/44e51622800e4fceb6bee8e616da85fd.png',
count: 1,
},
{
id: '4001649',
name: '大师监制龙泉青瓷茶叶罐',
price: 139,
picture: 'https://yanxuan-item.nosdn.127.net/4356c9fc150753775fe56b465314f1eb.png',
count: 1,
}
]
//1.以前的思路:dom驱动。 遍历数组,创建dom元素,逐一添加
// for(let i = 0;i<goodsList.length;i++){
// //(1)创建空标签
// let div = document.createElement('div')
// //(2)设置内容
// div.innerHTML = `<div class="item">
// <img src="${goodsList[i].picture}" alt="">
// <p class="name">${goodsList[i].name} <span class="tag">【赠品】10优惠券</span></p>
// <p class="price">${goodsList[i].price}</p>
// <p class="count">x${goodsList[i].count}</p>
// <p class="sub-total">${goodsList[i].price * goodsList[i].count}</p>
// </div>`
// //(3)添加到页面
// document.querySelector('.list').appendChild(div)
// }
//2.以后的思路:数据驱动。 遍历数组,拼接html字符串,然后替换元素的innerHTML
//(1) map : 把数组中的数据 映射成 对应的html字符串
// let res = goodsList.map(item=>{
// return `<div class="item">
// <img src="${item.picture}" alt="">
// <p class="name">${item.name} <span class="tag">【赠品】10优惠券</span></p>
// <p class="price">${item.price}</p>
// <p class="count">x${item.count}</p>
// <p class="sub-total">${item.price * item.count}</p>
// </div>`
// })
// console.log( res )
// //(2)拼接字符串
// let htmlStr = res.join('')
// console.log( htmlStr )
// //(3)替换元素的innerHTML
// document.querySelector('.list').innerHTML = htmlStr
document.querySelector('.list').innerHTML = goodsList.map(item=>{
return `<div class="item">
<img src="${item.picture}" alt="">
<p class="name">${item.name} <span class="tag">【赠品】10优惠券</span></p>
<p class="price">${item.price}</p>
<p class="count">x${item.count}</p>
<p class="sub-total">${item.price * item.count}</p>
</div>`
}).join('')
//求所有商品总价格
document.querySelector('.amount').innerText = goodsList.reduce((sum,item)=>sum+item.price*item.count,0)
</script>
</body>
</html>