乐趣区

关于react.js:React学习简单的React框架

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport"
          content="width=device-width,user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1"/>
    <meta content="black" name="apple-mobile-web-app-status-bar-style"/>
    <meta name="format-detection" content="telephone=no"/>
    <meta name="full-screen" content="yes"/>
    <meta name="x5-fullscreen" content="true"/>
    <meta name="browsermode" content="application"/>
    <meta name="x5-page-mode" content="app"/>
    <meta name="apple-mobile-web-app-capable" content="yes"/>
    <meta name="theme-color" content="#000000"/>
    <meta name="description" content="Web site created using create-react-app"/>
    <title> 电子衰弱卡二维码 </title>
    <style>
        * {
            padding: 0;
            margin: 0;
            font-size: 2.7rem;
            color: #000;
            font-weight: 400;
            font-family: Helvetica;
        }

        html {font-size: 1.7vw;}

        .no_select {
            -moz-user-select: none;
            -webkit-user-select: none;
            -ms-user-select: none;
            -khtml-user-select: none;
            -o-user-select: none;
            user-select: none;
        }

        body:before {
            width: 100%;
            height: 100%;
            content: " ";
            position: fixed;
            z-index: -1;
            top: 0;
            left: 0;
            background: #F9F9F9;
        }

        .main {
            height: 100vh;
            overflow-y: auto;
            overflow-x: hidden;
            padding: 3rem;
            box-sizing: border-box;
        }

        .name_container {padding: 0 1rem;}

        .name {
            font-weight: 600;
            margin-bottom: 0.6rem;
            height: 5rem;
            display: flex;
            align-items: center;
        }

        .name_container .info {
            color: #646464;
            margin: 0.7rem 0;
            font-size: 2.4rem;
            font-weight: 600;
        }

        .name_container .info span {
            color: #646464;
            font-size: 2.4rem;
            font-weight: 600;
        }

        .red_tip {
            font-weight: 800;
            margin-left: -1rem;
            color: #e73827;
            font-size: 3.0rem;
        }

        .time_container {
            display: flex;
            flex-direction: row;

            align-items: center;
            justify-content: center;

        }

        .time_container .time {
            display: flex;
            flex-direction: row;
        }


        .time_container_style {
            color: #4272ee;
            font-weight: 800;
            font-size: 3.3rem;
        }

        .time_container .time div {transform: translateY(-0.2rem);
            margin: 0 0.1rem;
        }
    </style>
</head>
<body>
<div class="main">
    <div class="name_container no_select"></div>
    <div class="time_container"></div>
</div>
</body>
<script type="text/javascript">
    /**
     * utils
     * */
    const randAChar = () => {const n = Math.random() * 10;
        const s = String.fromCharCode(Math.floor(Math.random() * 26) + 'a'.charCodeAt(0));
        if (n > 5) {return s;} else {return (s).toUpperCase();}
    };
    // 随机一个字符串
    const randCode = (n = Math.random() * 5) => {
        let s = '';
        for (let i = 0; i < n; i++) {s += randAChar();
        }
        return (((s + Math.ceil(Math.random() * 100) + Math.ceil(Math.random() * 100)).replace(/0/g, 'h')).replace('9', 'f') + randAChar()).toUpperCase();};
</script>
<script type="text/javascript">
    /**
     * element
     * */
    class Element {constructor(container) {
            this.container = container;
            this.cache = [];
            this.code = randCode();}

        render(nodes = []) {this.cache = this.createElements(nodes);
        }

        createElements(nodes = [], parent = '', container = this.container, cache = this.cache) {switch (typeof nodes) {
                case "number":
                case "boolean":
                case "undefined":
                case 'string':
                    let v = typeof nodes === 'undefined' ? '' : `${nodes}`;
                    const element = {text: v, key: parent + this.code, elementType: 'string'}
                    const {newContainer} = this.renderElements(element, container, cache[0]);
                    return v ? [{...element, element: newContainer}] : [];
                default:
                    return nodes.map((i, index) => {const key = parent + (i.key ? `${i.key}` : `${index}`);
                        switch (typeof i) {
                            case "number":
                            case "boolean":
                            case "undefined":
                            case 'string':
                                let v = typeof i === 'undefined' ? '' : `${i}`;
                                const se = {text: v, key, elementType: 'string'};
                                const res = this.renderElements(se, container, cache[index]);
                                return {...se, element: res.newContainer};
                            default:
                                if (!i.tag || i.hidden) {return;}
                                const te = {...i, key, elementType: 'tag'}
                                const {newContainer, newCache} = this.renderElements(te, container, cache[index]);
                                return {
                                    ...te,
                                    element: newContainer,
                                    children: i.children ? this.createElements(i.children, key + '_', newContainer, newCache) : []}
                        }

                    });
            }
        }

        renderElements(element, container, cacheElement) {if (!container) {
                return {
                    newContainer: undefined,
                    newCache: []};
            }
            if (this.compare(element, cacheElement)) {
                return {
                    newContainer: cacheElement.element,
                    newCache: cacheElement.children || []};
            } else {
                // 创立元素
                let e;
                switch (element.elementType) {
                    case "string":
                        e = document.createTextNode(element.text);
                        e['key'] = element['key']
                        break;
                    case "tag":
                        if (element.tag) {e = document.createElement(element.tag);
                            delete element.children;
                            delete element.element;
                            Object.keys(element).forEach((key) => {e[key] = element[key];
                            });
                        }

                }

                if (e) {if (cacheElement && cacheElement.element) {container.replaceChild(e, cacheElement.element)
                    } else {container.appendChild(e);
                    }
                }
                return {newContainer: e, newCache: []}
            }
        }

        // 比拟对象
        compare(element, cacheElement) {if (cacheElement === undefined) {return false;}
            if (element.elementType === 'string') {return element.text === cacheElement.text && element.key === cacheElement.key;}
            if (element.elementType === 'tag' && element.key !== cacheElement.key) {return false;}
            let bool = true;
            try {(function _compare(element, cacheElement) {Object.keys(element).forEach((key) => {if (element['elementType'] === 'tag' && typeof element[key] !== "object" && element[key] !== cacheElement[key] && key !== 'children') {throw new Error('false');
                        }
                        if (typeof element[key] === "object" && key !== 'element' && key !== 'children') {_compare(element[key], cacheElement[key] || {});
                        }
                    });
                }(element, cacheElement));
            } catch (e) {bool = false;}
            return bool;
        }
    }
</script>
<script type="text/javascript">
    /**
     * time
     * */
    class Time extends Element {constructor(containerClassName = 'time_container') {super();
            // 工夫符号
            this.units = Object.freeze(['-', '-', '\u00a0', ':', ':']);
            // 工夫容器
            this.container = document.getElementsByClassName(containerClassName)[0];
        }

        // 工夫格局转换
        rdn(number) {if (`${number}`.length === 1) {return `${0}${number}`
            } else {return number;}
        }

        // 获取工夫
        getTimes() {const nowDate = new Date();
            const nowYear = nowDate.getFullYear();
            const nowMonth = nowDate.getMonth() + 1;
            const nowDay = nowDate.getDate();
            const nowHour = nowDate.getHours();
            const nowMinutes = nowDate.getMinutes();
            const nowSeconds = nowDate.getSeconds();
            return [{value: nowYear, name: 'year'},
                {value: this.rdn(nowMonth), name: 'month'},
                {value: this.rdn(nowDay), name: 'day'},
                {value: this.rdn(nowHour), name: 'hour'},
                {value: this.rdn(nowMinutes), name: 'minutes'},
                {value: this.rdn(nowSeconds), name: 'seconds'}
            ];
        }

        renderTimeElement() {const nodes = this.getTimes().map((i, index) => {
                return {
                    tag: 'div',
                    className: 'time time_container_style',
                    children: [`${i.value}`,
                        {tag: this.units[index] ? 'div' : '',
                            children: this.units[index],
                            className: 'time_container_style'
                        }
                    ]
                }
            });
            this.render(nodes);
        }

        run() {this.renderTimeElement();
            setInterval(this.renderTimeElement.bind(this), 1000);
            return this;
        }
    }
</script>
<script type="text/javascript">
    /**
     * user
     * */
    class User extends Element {constructor(userInfo) {super();
            this.userInfo = userInfo;
            this.container = document.getElementsByClassName('name_container')[0];
            this.id = userInfo.id.replace(/(\d{4})\d{10}(\d{4})/, '$1**********$2');
            this.phone = userInfo.phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
        }

        run() {
            this.render([{
                tag: 'div',
                className: 'name',
                children: [
                    this.userInfo.name,
                    {
                        hidden: this.userInfo.isInoculation,
                        tag: 'span',
                        className: 'red_tip',
                        children: '(请尽快接种新冠疫苗)'
                    }
                ]
            }, {
                tag: 'div',
                className: 'info',
                children: [
                    '证件号码:',
                    {
                        tag: 'span',
                        children: this.id
                    }
                ]
            }, {
                tag: 'div',
                className: 'info',
                children: [
                    '电话号码:',
                    {
                        tag: 'span',
                        children: this.phone
                    }
                ]
            }]);
            return this;
        }
    }
</script>
<script type="text/javascript">
    /**
     * router
     * */

</script>
<script type="text/javascript">
    // 用户信息
    const userInfo = {
        id: '000000000000000000',
        phone: '00000000000',
        name: '张三',
        isInoculation: true,
    }

    let time = null;
    let user = null;

    function run() {time = new Time();
        time.run();
        user = new User(userInfo);
        user.run();}

    window.onload = () => {run();
    }

</script>
</html>
退出移动版