DOM操作
- 创建节点
createDocumentFragment()
createElement() // 创建元素节点
createTextNode() // 创建文本节点
- 添加, 移除,替换,插入
appendChild()
removeChild()
replaceChild()
insertChild()
- 查找
getElementsByTagName()
getElementsByName()
getElementsById()
eg
事件机制
事件的触发过程是怎么样的?知道什么是事件代理嘛?
- window向下寻找注册事件,直到找到注册事件
- 触发注册事件,向上冒泡
- 触发父级冒泡事件
- preventDefault 阻止默认事件
- stopPropagation 阻止冒泡事件
- cancelBublle ie阻止冒泡事件
事件代理:
由父节点来产生子节点的响应事件
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
let ul = document.querySelector('ul');
ul.addEventListener('click', (event)=> {
console.log(event)
})
</script>
请写出兼容各种浏览器版本的事件绑定函数?
function addHandler(element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler,false) // w3c
} else if (element.attachEvent) {
element.attachEvent(`on${type}`, handler) // ie
} else {
element[`on${type}`] = handler // other
}
跨域
什么是跨域,怎么解决?
由于浏览器出于安全考虑,有同源策略。也就是说,如果协议、域名或者端口有一个不同就是跨域
解决策略:
- 前端:
- JSONP 的原理很简单,就是利用 <script> 标签没有跨域限制的漏洞。通过 <script> 标签指向一个需要访问的地址并提供一个回调函数来接收数据当需要通讯时。
<script src="http://domain/api?param1=a¶m2=b&callback=jsonp"></script>
<script>
function jsonp(data) {
console.log(data)
}
</script>
局限性:兼容性不好,只是限制于get请求
- 设置代理
vue 中可以单独配置代理 - CORS (后端)
服务端设置 Access-Control-Allow-Origin 就可以开启CORS
个人觉得最理想状态是在nginx配置,不要嵌套在后台代码里
server {
listen 80;
server_name xxxx;
root /www/xxxx;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With,Content-Type;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
}
cookie 跨域:现在大型项目都是分模块部署的不同的web容器的,但是当用户登录之后,cookie要公用的,
解决策略:
location /web1 {
proxy_pass http://web1;
proxy_set_header Host 127.0.0.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie $http_cookie;
log_subrequest on;
}
location /web2 {
proxy_pass http://web2;
proxy_set_header Host 127.0.0.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie $http_cookie;
log_subrequest on;
}
这种策略就是把不同域的cookie放在相同的nginx中
- postMessage
postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。
// 发送消息端
window.parent.postMessage('message', 'http://test.com')
// 接收消息端
var mc = new MessageChannel()
mc.addEventListener('message', event => {
var origin = event.origin || event.originalEvent.origin
if (origin === 'http://test.com') {
console.log('验证通过')
}
})
存储
h5有哪些存储特性
特性 | cookie | localStorage | sessionStorage | indexDB |
---|---|---|---|---|
生命周期 | 可设置过期时间 | 除非清理,一直存在 | 页面关闭就清理 | 除非清理,一直存在 |
大小 | 4k | 5M | 5M | 无限 |
与服务端通信 | 每次都会携带在请求头中 | 不参与 | 不参与 | 不参与 |
浏览器的渲染原理
都知道,执行js有js引擎,渲染页面有渲染引擎,那他如何工作的
- 浏览器从服务端去拿html,而浏览器并不清楚css,hlml,元素,所有他是有一个转换的过程的
首先拿到的元素字节然后转为字符串,接着渲染成node节点,最后形成dom树, - 同理css也是一样的过程接
- 最后css树和DOM数结合形成DOM树结合形成网页
为什么操作js dom慢,插入几万个DOM,怎么不卡
因为js是数据js引擎的,而dom是属于渲染引擎的,所以实际上是两个线程在工作,操作多了,自然就卡了
解决几万个DOM操作不卡的办法:
- 将多条数据进行分组,
然后开启异步线程,每组进行渲染
每组的数据可以用 requestAnimationFrame 进行渲染
requestAnimationFrame 会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧。 - 滚动渲染,
重绘 , 回流
- reflow(回流): 当DOM树中的一部分或者全部因为大小边距等问题发生改变而需要重建的过程叫做回流
- repaint(重绘): 当元素的一部分属性发生变化,如外观背景色不会引起布局变化而需要重新渲染的过程叫做重绘
** 减少重绘,回流操作 **
- 使用visibility 替换 dipslay: none
- 不要使用table布局,可能很小的改动就回造成table的重新布局
- 避免css的层级过多
渲染请求的过程及优化 https://juejin.im/post/5d0f3a726fb9a07ea4208766
window的onload事件和domcontentloaded谁先谁后
1、当 onload事件触发时,页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了。
2、当 DOMContentLoaded 事件触发时,仅当DOM加载完成,不包括样式表,图片,flash