运用js模块化开发,实现五星好评小插件的封装
效果图
js代码
//这是导入的一个工具库,下面只用来创建元素
import Utils from "./Utils.js";
export default class FaceStar extends EventTarget {
lable;
list = [];
pos = -1;
constructor(_lable) {
super();
this.lable = _lable;
this.elem = this.createElem();
}
createElem() {
//创建标签,用来盛放span和ul
if (this.elem) return this.elem;
let div = Utils.ce("div", {
height: "32px",
float: "left",
marginLeft: "20px",
position: "relative"
});
// 创建对象后直接传入字符串即可
let span = Utils.ce("span", {
marginRight: "10px",
position: "relative",
top: "-5px"
});
span.textContent = this.lable;
// 创建ul来盛放五颗星星
let con = Utils.ce("ul", {
listStyle:"none",
margin: 0,
padding: 0,
height: "32px",
position: "relative",
//把ul改成行内块,这样方便span和ul一行显示
display: "inline-block"
});
// 生成五颗星星
for (var i = 0; i < 5; i++) {
let star = Utils.ce("li", {
width: "16px",
height: "16px",
float: "left",
marginTop: "16px",
backgroundImage: "url(./img/commstar.png)"
});
// 把创建的li放入数组中,方便下面遍历
this.list.push(star);
// li插入到ul中
con.appendChild(star);
}
// 星星上方表情显示,设置为默认display:none,鼠标放上后显示
this.face = Utils.ce("div", {
width: "16px",
height: "16px",
position: "absolute",
backgroundPositionX: -20 * 4 + "px",
display: "none",
backgroundImage: "url(./img/face-red.png)"
});
con.appendChild(this.face);
div.appendChild(span);
div.appendChild(con);
// 创建侦听事件
con.addEventListener("mouseover", e => this.mouseHandler(e));
con.addEventListener("mouseleave", e => this.mouseLeaveHandler(e));
con.addEventListener("click", e => this.mouseHandler(e));
return div;
}
appendTo(parent) {
if (typeof parent === "string") parent = document.querySelector(parent);
parent.appendChild(this.elem);
}
mouseHandler(e) {
if (e.target.constructor !== HTMLLIElement) return;
var index = this.list.indexOf(e.target);
if (e.type === "mouseover") {
this.face.style.display = "block";
this.face.style.backgroundPositionX = (4 - index) * -20 + "px";
this.face.style.left = e.target.offsetLeft + "px";
this.list.forEach((item, i) => {
if (i <= index) {
item.style.backgroundPositionY = "-16px"
} else if (i > this.pos) {
item.style.backgroundPositionY = "0px"
}
})
} else if (e.type === "click") {
// 利用pos来设置点击后移开鼠标,星星也不会恢复原样
this.pos = index;
this.setStar(this.pos);
var evt = new Event("change");
evt.pos = this.pos;
this.dispatchEvent(evt);
}
}
//设置鼠标移出的时候星星变回原样
mouseLeaveHandler(e) {
this.face.style.display = "none";
this.setStar(this.pos)
}
//设置星星
setStar(index) {
this.list.forEach((item, i) => {
if (i <= index) {
item.style.backgroundPositionY = "-16px"
} else {
item.style.backgroundPositionY = "0px"
}
})
}
}
测试一下
<script type="module">
import FaceStar from "./js/FaceStar.js";
let arr=["快速包装","快递服务","送货上门"];
arr.forEach((item)=>{
let faceStar=new FaceStar(item);
faceStar.appendTo("body");
faceStar.addEventListener("change",changeHandler);
});
function changeHandler(e){
console.log(e.pos+1,this.lable)
}
</script>
js模块化开发对每一位前端工程师来说都是必须掌握的功能,在这里我更新一些写下的一些小插件,封装的对象等等。喜欢的点个赞!