1.手写前端路由
手写路由两个核心
1)改变url地址,页面不刷新
2)如何检测url变化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
class HistoryRoute { constructor() { this.current = null } } class VueRouter { constructor(options) { this.mode = options.mode || "hash" this.routes = options.routes || [] this.routesMap = this.createMap(this.routes) this.history = new HistoryRoute(); this.init()
} init() { if (this.mode === "hash") { location.hash ? '' : location.hash = "/"; window.addEventListener("load", () => { this.history.current = location.hash.slice(1) }) window.addEventListener("hashchange", () => { this.history.current = location.hash.slice(1) }) } else { location.pathname ? '' : location.pathname = "/"; window.addEventListener('load', () => { this.history.current = location.pathname }) window.addEventListener("popstate", () => { this.history.current = location.pathname }) } }
createMap(routes) { return routes.reduce((pre, current) => { pre[current.path] = current.component return pre; }, {}) } }
|
2、字符串格式化
实现下面的字符串格式化函数 format( String, Object),避免出现XSS :
1 2 3 4 5 6 7
| document .body .innerHTML = format('<div>I am {name}, my website is <a href="{website}">{website}</a></div>',{ name: 'James', website: 'https://www.qq.com' })
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| const str = '<div>I am { name }, my website is <a href="{website}">{website}</a></div>' const data = { name: 'James', website: 'https://www.qq.com' } function format(str, data) { return str .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/ /g, ' ') .replace(/\'/g, ''') .replace(/\"/g, '"') .replace(/\{(.*?)\}/g, (i, k) => data[k.trim()]) } format(str, data)
|
3、数组渲染Dom
通过JS在下面的ul中插入10000条 li 节点,并在点击 li 时打印其下标
1 2 3 4 5 6 7 8 9 10 11 12 13
| const ul = document.querySelector('#ul') const fragment = document.createDocumentFragment() ul.innerHTML= '' for (let i = 0; i < 10000; i++) { const li = document.createElement('li') li.innerText = i li.setAttribute('data-index', i) fragment.appendChild(li) } ul.appendChild(fragment) ul.addEventListener('click', (e) => { console.log(e.target.dataset.index) })
|
4.网址判断
在输入框中如何判断输入的是一个正确的网址
1 2 3 4 5 6 7 8 9
| var url = 'https://www.abc.com' function checkUrl(url) { try { return new URL(url) } catch(e) { return false } } checkUrl(url)
|
5、页面布局
请按照如下布局在pc端实现htm和css样式,要求:
a)A区域是 header部分,高度100像素,宽度根据屏幕自适应,居顶部展示
b)B区域固定宽度200像素,居左侧展示
c)C区域根据屏幕宽度自适应
d)D区域固定宽度200像素,居右侧展示
e)E区域高度80像素,宽度自适应,当整体内容不够满屏展示,E居屏幕底部展示
f)当整体内容超出屏幕高度,出现垂直滚动
demo:
https://www.epoos.com/demo/learn/layout1.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| <style> .header { background:#396; position: fixed; left: 0; top: 0; width: 100%; height: 60px; z-index: 2; } .header-none { height: 60px; } .left { background:#963; position: absolute; left: 0; top: 60px; width: 200px; } .content { background:#693; width: 100%; min-height: 100%; padding: 60px 200px 30px 200px; margin-top: -60px; box-sizing: border-box; } .right { position: absolute; right: 0; top: 60px; background:#369; width: 200px; } .footer { background:cornsilk; float: left; width: 100%; height: 30px; margin-top: -30px; } </style>
<body> <div class="header">header</div> <div class="header-none"></div> <div class="left">left</div> <div class="content" contenteditable="true"></div> <div class="right">right</div> <div class="footer">footer</div> </body>
|