js
export default class Utils{
static ce(type,style){
let elem=document.createElement(type);
Object.assign(elem.style,style);
return elem;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script type="module">
import Utils from "./js/Utils.js";
// 1、当鼠标到哪个星星,这个星星包括之前的星星变红,其他变白
// 2、当离开大容器让所有星星变白
// 3、点击定位第几个星星,并且离开时定位之前不变白
var list=[];
var pos=-1;
var face=-1;
init();
function init(){
// 创建一个div容器
var div=Utils.ce("div",{
// 设置内样样式
width:"80px",
height:"16px",
position:"relative",
cursor: "pointer"
});
// 创建一个星星容器
var starCon=Utils.ce("div",{
position:"absolute",
top:"16px",
width:"80px",
height:"16px"
})
// 循环五次,创建五个的div
// 给每个div添加星星的背景图
for(var i=0;i<5;i++){
var star=Utils.ce("div",{
width:"16px",
height:"16px",
backgroundImage:"url(./img/commstar.png)",
float:"left"
});
// 将每个创建好的容器添加到数组里
list.push(star);
starCon.appendChild(star);
}
// 创建笑脸div容器
face=Utils.ce("div",{
width:"16px",
height:"16px",
position:"absolute",
top:"0px",
display:"none",
backgroundImage:"url(./img/face-red.png)"
});
div.appendChild(face);
div.appendChild(starCon);
// 给div添加鼠标滑过事件
div.addEventListener("mouseover",mouseHandler);
// 给div添加鼠标离开事件
div.addEventListener("mouseleave",mouseHandler);
// 给div添加鼠标进入事件
div.addEventListener("mouseenter",mouseHandler);
// 鼠标点击事件
div.addEventListener("click",mouseHandler);
// 将创建好的容器添加到body中
document.body.appendChild(div);
}
function mouseHandler(e){
// 判断事件类型
switch(e.type){
// 当事件类型是mouseenter时
case "mouseenter":
// 就是鼠标进入时,只要在里面笑脸就显示
face.style.display="block";
break;
// 当事件类型是mouseover时
case "mouseover":
// 查找鼠标滑过的目标对象的下标赋给变量index
var index=list.indexOf(e.target);
// 如果未找到直接跳出
if(index<0) return;
// 执行forEachList函数,将匿名函数作为参数带入进去
forEachList(function(i){
// return返回是一个bool值,进入forEachList函数的判断条件
return i<=index || i<=pos;
});
// 当鼠标滑过星星是,对应的笑脸要同时变化
// 笑脸的变化背景是从右到左,所以用下标最大值去减每次滑过的下标再*宽度
// 得到每次滑过星星改变对应的笑脸图
face.style.backgroundPositionX=-20*(4-index)+"px";
// 当鼠标划过时,通过index的下标位置去设置笑脸背景图移动的位置
face.style.left=index*16+"px";
break;
case "click":
// 查找鼠标滑过的目标对象的下标赋给变量index
var index=list.indexOf(e.target);
// 如果未找到直接跳出
if(index<0) return;
pos=index;
// 点击事件执行函数进行穿透
case "mouseleave":
forEachList(function(i){
return i<=pos;
});
// 当事件类型是鼠标离开时,设置笑脸隐藏
if(e.type==="mouseleave") face.style.display="none";
break;
}
}
// 桥接模式
function forEachList(fn){
for(var i=0;i<list.length;i++){
// 把循环的条件放在外面去做
if(fn(i)){
list[i].style.backgroundPositionY="-16px";
}else{
list[i].style.backgroundPositionY="0px";
}
}
}
// var lists=[24,18,37,56,92,6,10]
// function map(fn){
// var a=[];
// var b=[];
// for(var i=0;i
// var bool=fn(lists[i])
// if(bool){
// a.push(lists[i]);
// }else{
// b.push(lists[i]);
// }
// }
// return [a,b];
// }
// function fns(item){
// var bool=item<50 && item>20;
// return bool;
// }
// // var arr=map(fns);
// var arr=map(function(item){
// var bool=item<50 && item>20;
// return bool;
// });
// var arr=map(function(item){
// return item>50;
// });
// console.log(arr);
</script>
</body>
</html>
js文档
import Utils from "./Utils.js";
export default class RedFace{
elem;
face;
list=[];
pos=-1;
label="";
grade;
// _labe就是var arr=["快递包装","送货速度","配送员服务"]
constructor(_label){
this.label=_label;
this.elem=this.createElem();
}
createElem(){
// 创建一个div容器
var div=Utils.ce("div",{
// 设置内样样式
height:"32px",
position:"relative",
// 改变鼠标样式
cursor: "pointer"
});
// 创建一个星星容器
var starCon=Utils.ce("div",{
marginTop:"16px",
width:"80px",
height:"16px",
display:"inline-block"
})
// 循环五次,创建五个的div
// 给每个div添加星星的背景图
for(var i=0;i<5;i++){
var star=Utils.ce("div",{
width:"16px",
height:"16px",
backgroundImage:"url(./img/commstar.png)",
float:"left"
});
// 将每个创建好的容器添加到数组里
this.list.push(star);
starCon.appendChild(star);
}
// 创建笑脸div容器
this.face=Utils.ce("div",{
width:"16px",
height:"16px",
position:"absolute",
top:"0px",
display:"none",
backgroundImage:"url(./img/face-red.png)"
});
div.appendChild(this.face);
div.appendChild(starCon);
// 创建span标签
var labelSpan=Utils.ce("span",{
display:"inline-block",
marginRight:"10px",
});
// 给创建好的span标签内添加文本内容
labelSpan.textContent=this.label;
// 将文本内容插入到div的前面
div.insertBefore(labelSpan,div.firstElementChild);
// 创建span标签,作为平分显示
this.grade=Utils.ce("span",{
display:"inline-block",
marginLeft:"15px",
color:"red",
width:"40px"
})
div.appendChild(this.grade);
// 给div添加鼠标滑过事件
div.addEventListener("mouseover",e=>this.mouseHandler(e));
// 给div添加鼠标离开事件
div.addEventListener("mouseleave",e=>this.mouseHandler(e));
// 鼠标点击事件
div.addEventListener("click",e=>this.mouseHandler(e));
return div;
}
appendTo(parent){
if(typeof parent==="string"){
parent=document.querySelector(parent);
}
parent.appendChild(this.elem)
}
mouseHandler(e){
// 判断事件类型
switch(e.type){
// 当事件类型是mouseover时
case "mouseover":
// 查找鼠标滑过的目标对象的下标赋给变量index
var index=this.list.indexOf(e.target);
// 如果未找到直接跳出
if(index<0) return;
// 执行forEachList函数,将匿名函数作为参数带入进去
// 进入forEachList函数的判断条件
this.forEachList(i=> i<= index || i <= this.pos);
this.face.style.display="block";
// 当鼠标滑过星星是,对应的笑脸要同时变化
// 笑脸的变化背景是从右到左,所以用下标最大值去减每次滑过的下标再*宽度
// 得到每次滑过星星改变对应的笑脸图
this.face.style.backgroundPositionX=-20*(4-index)+"px";
// 当鼠标划过时,通过index的下标位置去设置笑脸背景图移动的位置
this.face.style.left=e.target.offsetLeft+"px";
this.grade.textContent=index+1+"分"
break;
case "click":
// 查找鼠标滑过的目标对象的下标赋给变量index
var index=this.list.indexOf(e.target);
// 如果未找到直接跳出
if(index<0) return;
this.pos=index;
// 点击事件执行函数进行穿透
case "mouseleave":
this.forEachList(i=>i <= this.pos);
// 当事件类型是鼠标离开时,设置笑脸隐藏
if(e.type==="mouseleave") this.face.style.display="none";
// 当鼠标离开时,评分清空
this.grade.textContent=""
break;
}
}
forEachList(fn){
for(var i=0;i<this.list.length;i++){
// 把循环的条件放在外面去做
if(fn(i)){
this.list[i].style.backgroundPositionY="-16px";
}else{
this.list[i].style.backgroundPositionY="0px";
}
}
}
}
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
ul{
list-style: none;
margin: 0;
padding: 0;
}
.faceList{
float: left;
padding: 10px 40px;
}
</style>
</head>
<body>
<ul>
<li class="faceList"></li>
<li class="faceList"></li>
<li class="faceList"></li>
</ul>
<script type="module">
import RedFace from "./js/RedFace.js";
var arr=["快递包装","送货速度","配送员服务"];
var lis=Array.from(document.querySelectorAll(".faceList"));
lis.forEach((item,index)=>{
// new RedFace就是执行类里面constructor构造函数
// 将数组的下标作为参数带入进去
var face=new RedFace(arr[index]);
face.appendTo(item);
})
</script>
</body>
</html>