首页图标轮播图
功能需求:根据图标的数量自动生成页面内容,完成图标按钮的轮播图;随着浏览器窗口的缩放,使页面内容自动缩放;
扩展:可以自定义展示每页、每行的图标数量;
来看一下效果:
html结构:模拟数据列表。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>index</title>
</head>
<body>
<script type="module">
var list=[
{icon:"angular.jpg",text:"angular",src:"https://angular.cn/"},
{icon:"axure.jpeg",text:"axure",src:"https://www.axure.com.cn/"},
{icon:"baidu.jpeg",text:"baidu",src:"https://www.baidu.com"},
{icon:"bootstrap.jpg",text:"bootstrap",src:"https://www.bootcss.com"},
{icon:"csdn.jpeg",text:"csdn",src:"https://www.csdn.net"},
{icon:"css3.jpg",text:"css3",src:"https://www.runoob.com/css3/css3-tutorial.html"},
{icon:"es6.jpeg",text:"es6",src:"https://blog.csdn.net/Charissa2017/article/details/103926266"},
{icon:"github.jpeg",text:"github",src:"https://github.com"},
{icon:"google.jpeg",text:"google",src:"https://www.google.cn"},
{icon:"grunt.jpeg",text:"grunt",src:"https://www.gruntjs.net"},
{icon:"gulp.jpeg",text:"gulp",src:"https://www.gulpjs.com.cn"},
{icon:"hbuilder.jpeg",text:"hbuilder",src:"https://www.dcloud.io"},
{icon:"html5.jpeg",text:"html5",src:"https://www.w3school.com.cn/html5/index.asp"},
{icon:"javascript.jpg",text:"javascript",src:"https://www.w3school.com.cn/js/index.asp"},
{icon:"jquery.jpeg",text:"jquery",src:"https://jquery.cuishifeng.cn"},
{icon:"less.jpg",text:"less",src:"http://lesscss.cn/"},
{icon:"node.jpeg",text:"node",src:"http://nodejs.cn/"},
{icon:"npm.jpg",text:"npm",src:"https://npmjs.org"},
{icon:"ps.jpeg",text:"ps",src:"localhost"},
{icon:"react.jpeg",text:"react",src:"https://react.docschina.org"},
{icon:"sass.jpg",text:"sass",src:"https://www.sass.hk"},
{icon:"sublime.jpeg",text:"sublime",src:"https://www.sublimetext.com"},
{icon:"svn.jpeg",text:"svn",src:"https://tortoisesvn.net"},
{icon:"typescript.jpeg",text:"typescript",src:"www.tslang.cn"},
{icon:"vscode.jpg",text:"vscode",src:"https://code.visualstudio.com"},
{icon:"vue.jpeg",text:"vue",src:"https://cn.vuejs.org"},
{icon:"webpack.jpg",text:"webpack",src:"https://www.webpackjs.com"},
{icon:"xcode.jpg",text:"xcode",src:"https://developer.apple.com/xcode/"},
{icon:"xmind.jpeg",text:"xmind",src:"https://www.xmind.cn/"},
{icon:"webstorm.jpg",text:"webstorm",src:"https://www.jetbrains.com/webstorm/"},
]
import Rem from './js/Rem.js';
import Main from './js/Main.js';
init();
function init(){
Rem.init();
//_list为数据,_path为图片路径,可不传,
//_num为每页显示的图标数量,不传的话默认为18,_lineNum为第行显示的图标数量,不传默认为6
let main=new Main({_list:list,_path:"./img/",_num:18,_lineNum:6});
//设置页面背景图片
main.setBgImage("url(./img/bg.jpeg)");
main.appendTo("body");
}
</script>
</body>
</html>
Main.js文件:根据数据内容生成页面图标,实现轮播图效果。
import Utils from "./Utils.js";
import Rem from "./Rem.js";
export default class Main{
static styleCss=false;
static num;//每页展示的icon数量
static lineNum;//每行显示的icon数量
index=0;//表示图标的索引
page=0;//一共有几页,默认为0
position=0;//表示小圆点的下标
prep;
constructor({_list,_path,_num=18,_lineNum=6}){
//如果有传入路径,则拼接图片路径
if(_path) _list.map(item=>item.icon=_path+item.icon);
//设置每页显示的icon数和每行显示的icon数
Main.num=_num;
Main.lineNum=_lineNum;
this.elem=this.createElem(_list);
//监听浏览器缩放,更改menuList的marginTop
window.addEventListener("resize", Main.setMenuListStyle);
}
createElem(_list){
if(this.elem) return this.elem;
//最外层的div容器
let div=Utils.createE("div");
div.className="container";
div.id="container";
//menuContainer是需要移动的容器 ul是下方的小圆点
div.innerHTML=`<div class="menuContainer" id="menuContainer">${this.createMenu(_list)}</div>
<ul class="iconList" id="iconList">${this.createLi()}</ul>`;
//写样式
Main.styles(_list);
//获取到DOM元素
Utils.getIdElem(div,this);
//下方的小圆点监听点击事件
this.iconList.addEventListener("click",e=>this.iconClickHandler(e));
//默认第一个小圆点显示
this.iconChange(this.iconList.firstChild);
return div;
}
appendTo(parent){
Utils.appendTo(this.elem,parent);
}
createMenu(_list){
//计算出一共有几页
this.page=Math.ceil(_list.length/Main.num);
let str="";
for(let i=0;i<this.page;i++){
//menuCon 是每一页的父容器
str+=`<div class="menuCon"><div class="menuList clearfix">`;
//如果j小于每页要展示的数量,并且index小于数组的长度-1,那么就创建每个图标元素
for(let j=0;j<Main.num&&this.index<_list.length-1;j++){
str+=`<dl class="menuDl"><a href="${_list[this.index].src}" target="_blank">
<dt><img class="menuIcon" src="${_list[this.index].icon}"></dt>
<dd>${_list[this.index].text}</dd>
</a></dl>`
this.index++;
}
str+=`</div></div>`;
if(this.index===_list.length-1) return str;
}
}
createLi(){
//创建下方的小圆点
let str="";
for(let i=0;i<this.page;i++){
str+=`<li></li>`
}
return str;
}
iconClickHandler(e){
this.menuContainerMove(e);
this.iconChange(e.target);
}
menuContainerMove(e){
let clientW=document.documentElement.clientWidth;
//menuContainer移动
if(e.target.nodeName!=="LI") return;
let index=Array.from(e.currentTarget.children).indexOf(e.target);
this.position=index;
this.menuContainer.style.left=-Rem.getRem(clientW*this.position)+"rem";
}
iconChange(_target){
//小圆点切换
if(_target.nodeName!=="LI") return;
if(this.prep) this.prep.style.backgroundColor="#ccc";
this.prep=_target;
this.prep.style.backgroundColor="rgba(255,0,0,1)";
}
setBgImage(_img){
//设置页面的背景图片
this.container.style.backgroundImage=_img;
}
static styles(_list){
if(Main.styleCss) return;
Main.styleCss=true;
let page=Math.ceil(_list.length/Main.num);
let clientW=Rem.getRem(document.documentElement.clientWidth);
Utils.insertCss(".container",{
width:clientW+"rem",
height:"100%",
position:"relative",
overflow:"hidden",
backgroundSize:"100% 100%"
})
Utils.insertCss(".menuContainer",{
width:clientW*page+"rem",
height:"100%",
position:"absolute",
left:"0",
transition:"all .3s"
})
Utils.insertCss(".menuCon",{
width:Math.floor(clientW)+"rem",
height:"100%",
float:"left"
})
Main.setMenuListStyle()
Utils.insertCss(".menuDl",{
listStyle:"none",
padding:"0rem",
margin:`0rem ${(11-1.4*Main.lineNum)/(Main.lineNum*2)}rem`,
float:"left"
})
Utils.insertCss(".menuDl a",{
width:"0.8rem",
padding:"0.2rem 0.3rem",
float:"left",
color:"#333",
textDecoration:"none"
})
Utils.insertCss(".menuDl .menuIcon",{
width:"0.8rem",
height:"0.8rem",
borderRadius:"50%"
})
Utils.insertCss(".menuDl dd",{
margin:"0rem",
textAlign:"center",
color:"#fff",
fontSize:"0.16rem"
})
let leftIconList=(clientW-0.4*page)/2;
Utils.insertCss(".iconList",{
height:"0.2rem",
listStyle:"none",
padding:"0rem",
margin:"0rem",
position:"absolute",
left:leftIconList+"rem",
bottom:"0.3rem"
})
Utils.insertCss(".iconList li",{
width:"0.2rem",
height:"0.2rem",
borderRadius:"50%",
backgroundColor:"#ccc",
float:"left",
margin:"0rem 0.1rem",
cursor:"pointer"
})
Utils.insertCss(".clearfix::after",{
content:"\".\"",
display:"block",
overflow:"hidden",
visibility:"hidden",
height:"0",
clear:"both"
})
}
//menuList设置样式
static setMenuListStyle(){
//line 表示每页有几行
let clientH=document.documentElement.clientHeight;
let line=Math.ceil(Main.num/Main.lineNum);
let fs = parseFloat(getComputedStyle(document.documentElement).fontSize);
let topMenuList=Rem.getRem((clientH-1.42*line*fs)/2);
Utils.insertCss(".menuList",{
width:"11rem",
fontSize:"0",
margin:`${topMenuList}rem auto 0`,
})
}
}
Rem.js文件:当浏览器窗口缩放时,实现自适应布局。
export default class Rem {
static init(){
Rem.defaultStyle();
Rem.resizeHandler();
window.addEventListener("resize", Rem.resizeHandler);
}
static resizeHandler() {
let contW = Math.floor(document.documentElement.clientWidth);
let fontS = (contW / screen.width) * 100;
document.documentElement.style.fontSize = fontS + "px";
}
static defaultStyle(){
document.documentElement.style.fontSize = "100px";
document.documentElement.style.height = "100%";
document.body.style.height = "100%";
document.body.style.fontSize = "16px";
document.body.style.padding = "0";
document.body.style.margin = "0";
}
static getRem(size) {
var fontSize = parseFloat(getComputedStyle(document.documentElement).fontSize);
return size / fontSize;
}
}
Utils.js文件:是一个工具包文件。
export default class Utils{
static createE(elem,style,prep){
this.elem=document.createElement(elem);
if(style) for(let prop in style) elem.style[prop]=style[prop];
if(prep) for(let prop in prep) elem[prop]=prep[prop];
return this.elem;
}
static appendTo(elem,parent){
if(parent.constructor===String) document.querySelector(parent).appendChild(elem);
else parent.appendChild(elem);
}
static randomNum(min,max){
return Math.floor(Math.random*(max-min)+min);
}
static randomColor(alpha){
alpha=alpha||Math.random().toFixed(1);
if(isNaN(alpha)) alpha=1;
if(alpha>1) alpha=1;
if(alpha<0) alpha=0;
let col="rgba(";
for(let i=0;i<3;i++){
col+=Utils.randomNum(0,256)+",";
}
col+=alpha+")";
return col;
}
static insertCss(select,styles){
if(document.styleSheets.length===0){
let styleS=Utils.createE("style");
Utils.appendTo(styleS,document.head);
}
let styleSheet=document.styleSheets[document.styleSheets.length-1];
let str=select+"{";
for(var prop in styles){
str+=prop.replace(/[A-Z]/g,function(item){
return "-"+item.toLocaleLowerCase();
})+":"+styles[prop]+";";
}
str+="}"
styleSheet.insertRule(str,styleSheet.cssRules.length);
}
static getIdElem(elem,obj){
if(elem.id) obj[elem.id]=elem;
if(elem.children.length===0) return obj;
for(let i=0;i<elem.children.length;i++){
Utils.getIdElem(elem.children[i],obj);
}
}
}
蒲公英芽
发布了58 篇原创文章 · 获赞 29 · 访问量 2万+
私信
关注