ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

纯js实现满屏图标轮播图,自定义图标显示数量

2020-01-28 13:39:30  阅读:364  来源: 互联网

标签:src 自定义 text 满屏 let jpeg https 图标 icon


首页图标轮播图

功能需求:根据图标的数量自动生成页面内容,完成图标按钮的轮播图;随着浏览器窗口的缩放,使页面内容自动缩放;
扩展:可以自定义展示每页、每行的图标数量;
来看一下效果:
纯js实现满屏图标轮播图
纯js实现满屏图标轮播图
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万+ 私信 关注

标签:src,自定义,text,满屏,let,jpeg,https,图标,icon
来源: https://blog.csdn.net/Charissa2017/article/details/104098966

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有