Pure js realizes full screen icon rotation chart, and custom icon display quantity

Home icon carousel

Function requirements: automatically generate page content according to the number of icons, complete the rotation chart of icon buttons; with the browser window zooming, make the page content automatically zooming;
Extension: the number of icons per page and line can be displayed by user;
Take a look at the effect:


html structure: list of simulation data.

<!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 is the data, and "path" is the picture path, which can not be transferred,
            //_num is the number of icons displayed on each page. If it is not transmitted, it defaults to 18. If it is not transmitted, it defaults to 6
            let main=new Main({_list:list,_path:"./img/",_num:18,_lineNum:6});
            //Set page background picture
            main.setBgImage("url(./img/bg.jpeg)");
            main.appendTo("body");
        }
    </script>
</body>
</html>

Main.js file: generate the page icon according to the data content to achieve the effect of carousel chart.

import Utils from "./Utils.js";
import Rem from "./Rem.js";
export default class Main{
    static styleCss=false;
    static num;//Number of icon s displayed per page
    static lineNum;//Number of icon s per line
    index=0;//Index representing Icon
    page=0;//There are several pages in total, the default is 0
    position=0;//Subscript for small dot
    prep;
    constructor({_list,_path,_num=18,_lineNum=6}){
        //If there is an incoming path, mosaic the picture path
        if(_path) _list.map(item=>item.icon=_path+item.icon);
        //Set the number of icon s displayed per page and per line
        Main.num=_num;
        Main.lineNum=_lineNum;
        this.elem=this.createElem(_list);
        //Monitor browser zoom, change the marginop of menuList
        window.addEventListener("resize", Main.setMenuListStyle);
    }
    createElem(_list){
        if(this.elem) return this.elem;
        //The outermost div container
        let div=Utils.createE("div");
        div.className="container";
        div.id="container";
        //menuContainer is the container to be moved ul is the dot below
        div.innerHTML=`<div class="menuContainer" id="menuContainer">${this.createMenu(_list)}</div>
        <ul class="iconList" id="iconList">${this.createLi()}</ul>`;
        //Writing style
        Main.styles(_list);
        //Get DOM element
        Utils.getIdElem(div,this);
        //Click event monitored by the small dot below
        this.iconList.addEventListener("click",e=>this.iconClickHandler(e));
        //Default first dot display
        this.iconChange(this.iconList.firstChild);
        return div;
    }
    appendTo(parent){
        Utils.appendTo(this.elem,parent);
    }
    createMenu(_list){
        //Figure out how many pages there are
        this.page=Math.ceil(_list.length/Main.num);
        let str="";
        for(let i=0;i<this.page;i++){
            //menuCon is the parent container of each page
            str+=`<div class="menuCon"><div class="menuList clearfix">`;
            //If j is less than the number to display per page, and the index is less than the length of the array - 1, each icon element is created
            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(){
        //Create small dots below
        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 Mobile
        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){
        //Small circle switching
        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){
        //Set the background picture of the page
        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 style
    static setMenuListStyle(){
        //line indicates how many lines per page
        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 file: implement adaptive layout when browser window zooms.

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 file: is a toolkit file.

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);
        }
    }
}
Published 60 original articles, won praise 29, visited 20000+
Private letter follow

Keywords: less css3 angular xcode

Added by colemanm on Tue, 28 Jan 2020 16:20:09 +0200