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