目录
document load和ready的区别
-
load是页面的资源全部加载完才执行
-
ready是DOM渲染完就执行,此时图片、视频还可能没有加载完
window.addEventListener('load', function () {
// 页面的全部资源加载完才执行,包括图片、视频等
})
document.addEventListener('DOMContentLoaded', function () {
// DOM 渲染完即可执行,此时图片、视频还可能没有加载完
})
访问 DOM 元素的常用方法
<body>
<div id="app">
<p class="txt">1111111111111111</p>
<p class="txt">2222222222222222</p>
<p>3333333333333333</p>
</div>
</body>
<script>
const a = document.getElementById('app') //通过 ID 得到 元素 兼容 IE6
const b = document.getElementsByTagName('p') //通过 标签名 得到 元素数组 兼容 IE6
const c = document.getElementsByClassName('txt') //通过 类名 得到 元素数组 兼容 IE9
const d = document.querySelector('#app') //通过 选择器 得到 元素 兼容 IE9
const e = document.querySelector('#app .txt') //通过 选择器 得到 元素(如果存在多个,只能得到第一个) 兼容 IE9
const f = document.querySelectorAll('#app .txt') //通过 选择器 得到 元素数组(能得到所有) 兼容 IE9
</script>
DMO 节点的 attribute
<body>
<div id="app">
<p class="txt">1111111111111111</p>
<p class="txt">2222222222222222</p>
<p>3333333333333333</p>
</div>
</body>
<script>
const a = document.getElementById('app')
//设置 attribute
a.setAttribute('data-n','节点')
//获得 attribute
const Attr = a.getAttribute('data-n')
console.log(Attr) // 节点
</script>
DOM 结构的操作(创建、移动、删除)
<body>
<div id="app">
<p class="oldP">我是本来就有的文字</p>
</div>
<div id="app1"></div>
</body>
<script>
const a = document.getElementById('app')
const a1 = document.getElementById('app1')
//创建一个新标签
const b = document.createElement('p')
b.innerHTML = '我是新创建的标签'
a.appendChild(b)
//获得 oldP
const oldP = document.getElementsByClassName('oldP')
a1.appendChild(oldP[0])
//删除节点
a.removeChild(oldP)
</script>
获取子元素列表 & 获取父元素
<body>
<div id="app">
<p>我是本来就有的文字</p>
<p>我是本来就有的文字</p>
<p>我是本来就有的文字</p>
</div>
</body>
<script>
const a = document.getElementById('app')
//获得 a 节点的所有子元素(包含空格、回车)
const list = a.childNodes
//获得 a 节点的所有父元素
const father = a.parentNode
console.log(father)
console.log(list) //得到的 list 有 7 个元素,因为包含 4 个 文字节点(回车)
//类数组对象 --> 数组的 两种方式
// const listArr = [...list]
const listArr = Array.prototype.slice.call(list)
const newArr = listArr.filter( item => {
return item.nodeType === 1
})
console.log(newArr) //得到 3 个元素 ,排除了 4 个文字节点
</script>
NodeType
如何优化 DOM 操作的性能
- 对 DOM 查询做缓存
- 将频繁的操作改为一次性的操作
DOM 查询做缓存
![](https://i-blog.csdnimg.cn/blog_migrate/8408b874be2c9371cd4d23012de7f116.png)
将频繁的操作改为一次性的操作
- 优化性能的示例
-
优化示例 - 反面示例(消耗性能的频繁插入操作)
-
反面示例(消耗性能的频繁插入操作)
判断当前浏览器所处的环境(navigator)
navigator.userAgent : 浏览器用于 HTTP 请求的用户代理头的值,通过UserAgent可以取得浏览器类别、版本,客户端操作系统等信息。
在PC端打开 ,navigator.userAgent 显示如下:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36
在手机web端打开 ,navigator.userAgent 显示如下
Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1
场景1:判断页面是在手机端,平板端还是PC端打开
var os = function (){
var ua = navigator.userAgent,
isWindowsPhone = /(?:Windows Phone)/.test(ua),
isSymbian = /(?:SymbianOS)/.test(ua) || isWindowsPhone,
isAndroid = /(?:Android)/.test(ua),
isFireFox = /(?:Firefox)/.test(ua),
isChrome = /(?:Chrome|CriOS)/.test(ua),
isTablet = /(?:iPad|PlayBook)/.test(ua) || (isAndroid && !/(?:Mobile)/.test(ua)) || (isFireFox && /(?:Tablet)/.test(ua)),
isPhone = /(?:iPhone)/.test(ua) && !isTablet,
isPc = !isPhone && !isAndroid && !isSymbian;
return {
isTablet: isTablet,
isPhone: isPhone,
isAndroid: isAndroid,
isPc: isPc
};
}();
if (os.isAndroid || os.isPhone) {
console.log('手机')
} else if (os.isTablet) {
console.log('平板')
} else if (os.isPc) {
console.log('电脑')
}
场景2:判断当前环境是否是微信环境
function is_weixin(){
var ua = navigator.userAgent.toLowerCase();
if(ua.match(/MicroMessenger/i)=="micromessenger") {
return true;
} else {
return false;
}
}
location
- location.href: 获得当前网页的网址
- location.protocol: 获得当前网页的协议( http / https )
- location.host: 获得当前网页的域名( www.baidu.com )
- location.search: 获得当前网页的参数( www.baidu.com?a=200&b=250 )
- location.hash: 获得当前网页的哈希值( www.baidu.com#apple )
- location.pathname: 获得当前网页的路径( www.baidu.com/page )
history
- history.back() //后退
- history.forword() //前进
事件冒泡
事件代理
事件代理是什么:在父元素上定义一个事件,监听子元素触发时的冒泡。 如果子元素想要阻止冒泡,则使用:e.stopPropagation()
- 代码简洁
- 减少浏览器内存使用
- 但是不可滥用(比如只有一个节点)
<body>
<div id='div' style="height: 500px;">
<p>a1</p>
<p>a2</p>
<p>a3</p>
<p>a4</p>
</div>
</body>
<script>
const fun = (el, type, fn) => {
el.addEventListener(type, fn)
}
const div = document.getElementById('div')
fun(div, 'click', e => {
const txt = e.target.innerHTML
console.log(txt)
})
</script>
通用的事件监听函数
<body>
<div id='div' style="height: 500px;">
<p>a1</p>
<p>a2</p>
<p>a3</p>
<p>a4</p>
<button>hha</button>
</div>
</body>
<script>
//selector 为你规定的事件代理绑定节点
const fun = (el, type, fn , selector=undefined) => {
el.addEventListener(type, event => {
const target = event.target
if(selector){
//事件代理绑定
if(target.matches(selector)){ //判断所点击的节点是否是规定的节点(selector)
fn.call(target, event)
}
}else{
//普通事件绑定
fn.call(target,event)
}
})
}
const div = document.getElementById('div')
fun(div, 'click', function(e){
e.preventDefault()
console.log(this.innerHTML)
},'p')
</script>
XMLHttpRequest
ajax请求的get和post的区别
- get一般用于查询操作,post一般用于用户提交操作
- get参数拼接在url上,post放在请求体内(数据体积可更大)
- 安全性:post易于防止CSRF
readystatechange
监听 readyState 的状态变化:readyState 共有 0-4 一共五个状态
- 0:未初始化,未调用 open() 函数;
- 1:启动,已经调用open() 函数,尚未调用 send()函数;
- 2:发送,已经调用send()函数,尚未接到响应;
- 3:接受,已经接受到部分相应数据;
- 4:已经接受到完整的响应数据,可以在浏览器中使用了;
为了 兼容性 ,该部分提升至 open()函数前使用;
GET 请求
const url = './new.json'
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = function() {
if (xhr.readyState !== 4) return
if (xhr.status === 200) {
console.log(JSON.parse(xhr.responseText))
} else {
console.log('其他情况')
}
}
//第三个参数:true 代表 ‘异步’
xhr.open('get', url, true)
//使用 GET 方法请求是,传入 参数 null(为了浏览器的兼容性)
xhr.send(null)
POST 请求
const url = '/Login'
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = function() {
if (xhr.readyState !== 4) return
if (xhr.status >= 200 && xhr.status <= 300 || xhr.status === 304) {
console.log(xhr.responseText)
}
}
const postData = {
name: '张三',
age: 40
}
xhr.open('POST', url, true)
//提交时要转换成 JSON 字符串的形式才能提交
xhr.send(JSON.stringify(postData))
Promise 封装 Ajax
function ajax(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = function() {
if (xhr.readyState !== 4) return
if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
resolve(JSON.parse(xhr.responseText))
} else {
reject(new Error('出错了'))
}
}
xhr.open('GET', url, true)
xhr.send(null)
})
}
const url = './new.json'
ajax(url).then(res => {
console.log(res)
})
跨域解决方案
同源策略:协议、域名、端口,三者必须一致
CSS、JS、图片加载 可无视同源策略
- JSONP
- CORS