<!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>