Appearance
一、DOM
1 DOM是什么
从HTML解析出来的一颗树,DOM树。
2. DOM结构操作
- property:对DOM元素的js变量进行修改。js的属性,去修改页面样式,或者结构的一种形式。不会对页面标签产生影响,不会体现到html结构中。 例如:document.getElementById()
- attribute:DOM元素节点属性,作用到节点,直接修改页面标签。修改html属性,会改变html结构。 例如:p.setAttribute('style','font-size:50px'),p.getAttribute('style')
- 两者都会引起DOM重新渲染。尽量使用property使用
3. 如何优化DOM性能
DOM查询时,做缓存。
js
//不缓存DOM查询结果
for(let i = 0;i<document.getElementsByTagName('p').length;i++) {
//每次循环,都会重新计算长度,频繁的查询DOM
}
//缓存DOM查询
const pList = document.getElementsByTagName('p')
const length = pList.length
for(let i = 0; i < length;i++) {
//缓存length,只进行了一次dom查询
}二、BOM
- userAgent
获取浏览器内容,比如浏览器类型:
const ua = navigator.userAgent
const isChrome = ua.indexOf('Chrome')
- screen
屏幕的数据,比如屏幕宽度
console.log(screen.width)
- location
网址信息:
console.log(location.href)//获取这个网址
console.log(location.protocol)//获取协议,http,https
console.log(location.host)//获取域名
console.log(location.pathname)//获取路径
console.log(location.search)//获取地址查询参数
console.log(location.hash)//获取地址#号后面内容
- history
history.back()//后退
history.forward()//前进
三、事件
1. 事件绑定
js
<button id='btn1'>按钮</button>js
//事件绑定
const btn = document.getElementById('btn1')
btn.addEventListener('click', event => {
console.log('clicked')
})
//通过事件绑定函数
function bindEvent(elem, type, fn) {
elem.addEventListener(type, fn)
}
const btn1 = document.getElementById('bnt1')
bindEvent(btn1, 'click', event => {
console.log(event.target)//获取点击元素
event.preventDefault()//阻止默认行为,例如,超链接,阻止跳转
alert('clicked')
})2. 事件冒泡
基于DOM树形结构,事件会顺着触发元素往上冒泡。应用场景:代理
js
<div id="div1">
<p id="p1">激活</p>
<p id="p2">取消</p>
<p id="p3">取消</p>
<p id="p4">取消</p>
</div>
<div id="div2">
<p id="p5">取消</p>
<p id="p6">取消</p>
</div>js
function bindEvent(elem, type, fn) {
elem.addEventListener(type, fn)
}
const p1 = document.getElementById('p1')
const body = document.body
bindEvent(p1,'click',e => {
e.stopPropagation()//阻止事件冒泡
console.log('激活')
})
bindEvent(body,'click',e => {
console.log('body click')
console.log(event.target)
})
const div2 = document.getElementById('div2')
bindEvent(div2,'click',e => {
console.log('div2 click')
})3. 事件代理
有事件冒泡,才能在事件冒泡的基础上实现事件代理。
事件代理应用场景:瀑布流
例如:不知道div中有多少a标签,没办法给a标签绑定click事件。把事件绑定到div上,每当点击a标签时,都会通过事件冒泡,冒泡到div上,然后拿到a标签的点击。这就是一个事件代理的应用。
js
<div id="div3">
<a href="#">a1</a>
<a href="#">a2</a>
<a href="#">a3</a>
<a href="#">a4</a>
<button id="btn1">点击加载更多</button>
</div>
<script>
// 通过事件绑定函数
// function bindEvent(elem, type, fn) {
// elem.addEventListener(type, fn)
// }
// 另一种写法,支持事件代理,事件监听函数
function bindEvent(elem, type, selector, fn) {
//传了三个参数
if(fn == null) {
fn = selector;
selector = null;
}
elem.addEventListener(type, event => {
const target = event.target
if(selector) {
//搭理绑定
//判断当前元素符合不符合
if(target.matches(selector)) {
console.log(12321)
fn.call(target, event)
}
}else {
//普通绑定
fn.call(target, event)
}
})
}
// 普通绑定
const btn1 = document.getElementById('btn1')
bindEvent(btn1,'click', function(event) {
event.preventDefault()
alert(this.innerHTML)
})
//代理绑定
const div3 = document.getElementById('div3')
bindEvent(div3,'click','a',function(event) {
event.preventDefault()
alert(this.innerHTML)
})
</script>四、Ajax
1. ajax核心API-XMLHttpRequest
get请求:
js
const xhr = new XMLHttpRequest()
xhr.open('GET','api',true/*异步请求*/)
//xhr实例状态,触发函数
xhr.onreadystatechange = function () {
if(xhr.readyState === 4) {
if(xhr.status === 200) {
console.log(JSON.parse(xhr.responseText))
}
}
}
xhr.send(null)post请求:
js
const xhr = new XMLHttpRequest()
xhr.open('POST','api',true)
xhr.onreadystatechange = function () {
if(xhr.readyState === 4) {
if(xhr.status === 200) {
console.log(JSON.parse(xhr.responseText))
}
}
}
const postData = {
userName:'zhangsan',
password:'xxx'
}
xhr.send(JSON.stringify(postData))2. 浏览器同源策略
ajax请求时,浏览器要求当前网页和server必须同源(浏览器安全策略)
同源:协议,域名,端口,三者必须一致。
加载图片,css,js可无视同源策略
3. 解决ajax跨域
- JSONPJavaScript
因为页面引入不同域名的js脚本是可以,因此在js文件载入完毕之后,触发回调,可以将需要的data作为参数传入。
js
<script type="text/javascript">
function dosomething(data){
//处理获得的数据
}
</script>
<script src="api?callback=dosomething"></script>JSONP优缺点: 优点:兼容性好 缺点:只支持GET请求
- CORS
服务端设置http header
Access-Control-Allow-Origin: * 表明该资源可以被任意外域访问。
js
response.setHeader("Access-Control-Allow-Origin","http:localhost:8011");//跨域请求的域名
response.setHeader("Access-Control-Allow-Headers","X-Requested-With");//可接受跨域请求自定义头
response.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");//接收跨域的方法
//接收跨域的cookie
response.setHeader("Access-Control-Allow-Credentials","true");