一.通用事件绑定
<button id="btn">点我</button>
<a href="https://www.baidu.com" id="links">这是一个链接</a>
<script type="text/javascript">
var btn = document.getElementById("btn");
btn.addEventListener('click',function(event){
console.log('clicked');
})
//自己封装一个通用的事件绑定函数
function bindEvent(elem,type,fn) {
elem.addEventListener(type,fn);
}
var a = document.getElementById("links");
bindEvent(a, 'click', function(e) {
e.preventDefault(); //阻止默认事件,这里是为了阻止a标签点击产生的链接跳转事件,这样他就不会跳转到百度页面
alert('clicked');
})
</script>
关于IE低版本的兼容性
- IE低版本使用attachEvent绑定事件,和W3C标准不一样。
- IE低版本使用量已经非常少,很多网站早已不支持。
- 建议对IE低版本的兼容性:了解即可,无需深究。
- 如果遇到对IE低版本要求苛刻的面试,果断放弃。
二.事件冒泡
<body>
<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>
<script type="text/javascript">
function addEvent (el,type,fn) {
el.addEventListener(type,fn);
}
var p1 = document.getElementById("p1");
var body = document.body;
addEvent(p1,"click",function(e){
//阻止冒泡
e.stopPropagation(); //e指的是时间处理函数的第一个参数,又可以用event表示
alert("激活");
})
addEvent(body,"click",function(e){
alert("取消");
})
</script>
</body>
上面代码的效果是点击激活,弹出激活两字,并且阻止事件冒泡。点击body区域,弹出取消两字。
举一个事件冒泡的具体应用——代理。我们点击a元素,打该元素的文本内容。
<body>
<div id="div1">
<a href="#">a1</a>
<a href="#">a2</a>
<a href="#">a3</a>
<a href="#">a4</a>
<!-- 将来可能会有更多的a元素添加进来 -->
</div>
<script type="text/javascript">
var div1 = document.getElementById("div1");
div1.addEventListener("click",function(e){
var target = e.target; //获取目标的a元素
if (target.nodeName === "A") {
console.log(target.innerText);
}
})
</script>
</body>
完善通用事件绑定函数,使其能够兼容使用代理的场景
<body>
<div id="div1">
<a href="#" id="a1">a1</a>
<a href="#" id="a2">a2</a>
<a href="#" id="a3">a3</a>
<a href="#" id="a4">a4</a>
<!-- 将来可能会有更多的a元素添加进来 -->
</div>
<script type="text/javascript">
function addEvent(el,type,selector,fn) {
if (fn == null) {
fn = selector;
selector = null;
}
el.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");
addEvent(div1,"click","a",function(e){
console.log(this.innerText);
})
//不使用代理
var a = document.getElementById("a1");
addEvent(a,"click",function(e){
console.log(a.innerText);
})
</script>
</body>
代理的好处:
- 代码简洁;
- 减少浏览器内存占用。
问题1: 编写一个通用的事件绑定函数
function addEvent(el,type,selector,fn) {
if (fn == null) {
fn = selector;
selector = null;
}
el.addEventListener(type,function(e){
var target;
if (selector) {
target = e.target;
if (target.matches(selector)) {
fn.call(target,e);
}
} else {
fn(e);
}
})
}
问题2:简述事件冒泡的流程
- DOM树形结构;(即body > div > a这样的结构)
- 事件冒泡;
- 阻止冒泡;
- 冒泡的应用;(即代理)
问题3:无限下拉加载图片的页面,绑定事件
- 使用代理;
- 知道代理的两个优点。
三.Ajax
1.XMLHttpRequest
<script type="text/javascript">
var xhr = new XMLHttpRequest();
xhr.open("GET","/api",true); //true代表异步,默认是true
xhr.onreadystatechange = function(){
if (xhr.readyState == 4) { //readyState 属性存有 XMLHttpRequest 的状态信息。4: 请求已完成,且响应已就绪
if (xhr.status == 200) { //200表示服务器响应正常
console.log(xhr.responseText);
}
}
}
xhr.send(null);
</script>
IE低版本兼容性问题,使用
var xmlhttp;
if (window.XMLHttpRequest)
{
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
xmlhttp=new XMLHttpRequest();
}
else
{
// IE6, IE5 浏览器执行代码
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
状态码:
跨域
1.什么是跨域
- 浏览器有同源策略,不允许ajax访问其他域接口;
- 跨域条件:协议、域名、端口,有一个不同就算跨域。
2.但是有三个标签允许跨域加载资源
- <img src=xxx>
- <link href=xxx>
- <script src=xxx></script>
跨域注意事项
- 所有的跨域请求都必须经过信息提供方允许;
- 如果未经允许即可获取,那是浏览器同源策略出现漏洞。
3.jsonp实现原理
下面例子首先声明一个函数,然后通过script的src调用外部的接口,外部接口执行此前声明的js函数,然后把参数传进来,这就是jsonp的实现原理。
解决跨域除了服务器端使用jsonp以外,还用一种方法
问题1:手动编写一个ajax
<script type="text/javascript">
var xhr = new XMLHttpRequest();
xhr.open("GET","/api",true); //true代表异步,默认是true
xhr.onreadystatechange = function(){
if (xhr.readyState == 4) { //readyState 属性存有 XMLHttpRequest 的状态信息。4: 请求已完成,且响应已就绪
if (xhr.status == 200) { //200表示服务器响应正常
console.log(xhr.responseText);
}
}
}
xhr.send(null);
</script>
问题2:跨域的几种实现方式
- JSONP
- 服务器端设置http header
存储
1.cookie
2.localStorage和sessionStorage
这两个每次http请求都不用带,是专门为存储而设计的。
注意:ios safari隐藏模式下localStorage.getItem会报错,所以建议统一用try-catch封装。
问题1:cookie sessionStorage localStorage三者的区别
- 容量
- 是否会携带到ajax中(cookie每次都会)
- API易用性