-
1.什么是冒泡 指的是从点击的这个元素开始,往父级去触发事件
-
2.什么是捕获 从父级元素开始,逐步触发事件至当前点击的这个元素上,这叫捕获。 他和冒泡刚好是相反的
-
tips:
- target 和 currentTarget 的区别 答: target 是实际点击的元素,currentTarget 是触发的元素
-
- 如果冒泡和捕获是同时存在,他们的顺序是什么 优先出现 捕获 然后是冒泡 在同一个dom上,是先执行冒泡还是捕获 答:他是同时执行的,一定是先执行捕获的。 但是在老版本的浏览器上是看书写顺序,决定优先执行顺序的
-
3.阻止冒泡
w3c的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true window.event? window.event.cancelBubble = true : e.stopPropagation(); 4.阻止默认事件 w3c的方法是e.preventDefault(),IE则是使用e.returnValue = false;
当需要停止冒泡行为时,可以使用: function stopBubble(e) { //如果提供了事件对象,则这是一个非IE浏览器 if ( e && e.stopPropagation ) //因此它支持W3C的stopPropagation()方法 e.stopPropagation(); else //否则,我们需要使用IE的方式来取消事件冒泡 window.event.cancelBubble = true; } //阻止浏览器的默认行为 function stopDefault( e ) { //阻止默认浏览器动作(W3C) if ( e && e.preventDefault ) e.preventDefault(); //IE中阻止函数器默认动作的方式 else window.event.returnValue = false; return false; }
阻止冒泡当然还有通过if 判断 if(target == currgetTarget){ console.log('伪阻止冒泡') }
ajax
创建一个ajax的步骤
function ajax(url,onSuccess,onFailed){
// 1. 创建xhr
const xhr = window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject('Microsoft.XMLHttpRequest')
// 2. 连接服务器
xhr.open('GET', url,true);
// 3. 发送
xhr.send()
// 4. 默认带上cookie
// xhr.withCredentials = true
// 5. 接收
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 ){
if(xhr.state === 200){
onSuccess && onSuccess(xhr.responseText);
} else {
onFailed && onFailed();
}
}
}
}
// ajax('http://127.0.0.1:8080/demo.json', e => {
// console.log(e)
// }); // 此时访问会跨域
//fetch('http://127.0.0.1:8080/demo.json', e => {
// console.log(e)
//}); // 此时访问会跨域
// 写一个复杂一丢丢的
let cc = null
const mitt = {
// 写一个发布订阅
canche: {},
on(name,func){
this.canche[name] = func;
},
emit(name, data) {
const fn = this.canche[name]
fn && fn(data)
}
}
function adaptor(config){
return new Promise((resolve, reject) => {
let request = new XMLHttpRequest();
request.open(
config.methods.toUpperCase(),
config.url,
true
)
request.send();
request.timeout = config.timeout;
request.onabort = function() {
reject('[abort] request is abort')
request = null
}
if(config.cancel){
config.cancel(
mitt.emit('abort', function() {
request.abort();
request = nullreject('[abort] current requset is abort.')
})
);
}
request.onreadystatechange = function() {
if(request.readyState === 4){
if(request.status == 200){
setTimeout(() => resolve(request && request.responseText),10000 )
} else {
reject('request error')
}
}
}
})
}
function dispatchRequset(config) {
return adaptor(config).then(function(response) {
return response
},function(rescon) {
return Promise.reject(rescon)
})
}
function req(config = {}){
/**
如何实现一个拦截
*/
const chain = [ dispatchRequset, undefined ]
if(config.interceptor) {
chain.unshift(
config.interceptor.fullfilled,
config.interceptor.rejected
)
}
if(config.cancel){
mitt.on('abort', function(cancel) {
// cc = cancel;
config.cancel(cancel)
})
}
// [拦截器成功, 拦截器失败,请求成功,请求失败,响应成功,响应失败]
if(config.adaptor) {
chain.push(
config.adaptor.fullfilled,
config.adaptor.rejected
)
}
// promise 链
let promise = Promise.resolve(config);
while(chain.length){
promise = promise.then(chain.shift(), chain.shift())
}
return promise;
}
req({
url: 'http://127.0.0.1:8080/demo.json',
methods: 'get',
interceptor: {
fullfilled: e => {
console.log('请求拦截成功')
return e;
}
},
adaptor: {
fullfilled: e => {
console.log('响应拦截成功', e)
return e;
}
},
cancel(Oncancel) {
cc = Oncancel
}
})
setTimeout(() => cc&& cc() , 10000)