Skip to content

一、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");

Released under the MIT License.