事件
知识点
1.通用事件绑定
// 第一种
var btn = document.getElementById('btn1')
btn.addEventListener('click',function(event) {
console.log('clicked')
})
// 第二种
function bindEvent(elem,type, fn) {
elem,addEventListener(type,fn)
}
var a = document.getElementById('link1')
bindEvent(a,'click', function(e) {
e.preventDefault() //阻止默认行为
alert('clicked')
})
2.事件冒泡
<body>
<div id="div1">
<p id='p1'>激活</p>
<p id='p1'>取消</p>
<p id='p1'>取消</p>
<p id='p1'>取消</p>
</div>
<div id='div2'>
<p id='p5'>取消</p>
<p id='p6'>取消</p>
</div>
</body>
var p1 = document.getElementById('p1')
var body = document.body
bindEvent(p1, 'click',function (e) {
e.stopPropagation()
alert('激活')
})
bindEvent(body,'click',function (e) {
alert('取消')
})
3、代理
<div id='div1'>
<a href='#'>a1</a>
<a href='#'>a2</a>
<a href='#'>a3</a>
<a href='#'>a4</a>
<!-- 会随时新增更多 a 标签 -->
</div>
var div1 = document.getElementById('div1')
div.addEventListener('click',function (e) {
var target = e.target //获取冒泡的最初触发的标签
if (target.nodeName === 'A') {
alert(target.innerHTML)
}
})
题目
1.编写一个通用的事件监听函数
function bindEvent(elem,type, selector, fn) {
if(fn == null) {
fn = selector
selector = null
}
elem.addEventListener(type,function (e) {
var target
if (selector) {
target = e.target
if (target.matches(selector)) {
fn.call(target,e)
}
} else {
fn(e)
}
})
}
// 使用代理
var div1 = document.getElementById('div1')
bindEvent(div1,'click','a',function (e) {
console.log(this.innerHTML)
})
// 不适用代理
var a = document.getElementById('a1')
bindEvent(a,'click',function (e) {
console.log(a.innerHTML)
}
描述事件冒泡流程
- DOM树形结构
- 事件冒泡
- 阻止冒泡(stopPropagation)
- 冒泡的应用
对于一个无限下拉加载图片的页面,如何给每个图片绑定事件
- 使用代理
- 知道代理的优点
1.代码简洁
2.浏览器效率高
Ajax
知识点
XMLHttpRequest
var xhr = new XMLHttpRequest()
//true 是异步,false是同步, api是请求URL,GET是请求方式
xhr.open('GET','/api',true)
xhr.onreadystatechange = function () {
// 这里的函数异步执行,可参考之前 JS 中的异步
if(xhr.readyState == 4) { // 4 完成
if( xhr.status ==200) { // 状态码 200 成功
alert(xhr.responseText)
}
}
}
xhr.send(null) //send 发送
readyState
- 0 -(未初始化) 还没有调用send()方法
- 1 -(载入) 已调用send() 方法,正在发送请求
- 2 -(载入完成) send()方法执行完成,已经接收到全部相应内容
- 3 -(交互) 正在解析响应内容
- 4 -(完成) 响应内容解析完成,可以在客户端调用了
状态码说明
- 2xx - 表示成功除理请求 如200
- 3xx - 需要充定向,浏览器直接跳转
- 4xx - 客户端请求错误, 如404
- 5xx - 服务器端错误
跨域
- 什么是跨域
- 浏览器有同源策略,不允许ajax 访问其他域接口
- 跨域条件:协议、域名、端口、有一个不同就算跨域
- 可以跨域的三个标签
<img src=xxx><link href=xxxx><script src=xxxx>
- 三个表情的使用场景
<img>用于打点统计,统计网站可能是其他域,如百度站长<link><script>可以使用CDN,CDN的也是其他域<script>可以用于JSONP
- 跨域注意事项
- 所有跨域请求都必需经过信息提供方允许
- 如果未经允许即可获取,那是浏览器同源策略出现漏洞
- JSONP
- 加载URL请求时
- 不一定服务器真正有一个相应的文件
- 服务器可以根据请求,动态生成一个文件,返回
<script>
window.callback = function (data) {
// 这是我们跨域得到的信息
console.log(data)
}
</script>
<script src="https://xxx.com/api.js">
<!--以上将返回 callback({x:100,y:200})-->
- 服务器端设置 http header
- 另外一个解决跨域的简洁方法,需要服务器端来做
- 但是作为交互方,前端必须知道这个方法
- 是讲来解决跨域问题的一个趋势
// 注意不同后端语言写法不一样
// 第二个参数填写允许跨域的域名称,不建议直接写 '*'
response.setHeader("Access-Control-Allow-Orgin", "http://a.com,http://b.com")
response.setHeader("Access-Control-Allow-Header", "X-Requested-With");
response.setHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
// 接收跨域的cookie
response.setHeader('Access-Control-Allow-Credentials','true');
题目
- 手动编写一个 ajax, 不依赖第三方库
var xhr = new XMLHttpRequest()
//true 是异步,false是同步, api是请求URL,GET是请求方式
xhr.open('GET','/api',true)
xhr.onreadystatechange = function () {
// 这里的函数异步执行,可参考之前 JS 中的异步
if(xhr.readyState == 4) { // 状态码 4 完成
if( xhr.status ==200) { // 状态码 200 成功
alert(xhr.responseText)
}
}
}
xhr.send(null) //send 发送
- 跨域的几种实现方式
- JSONP
- 服务器端设置 http header