冒泡捕获以及ajax补充

110 阅读2分钟
  • 1.什么是冒泡 指的是从点击的这个元素开始,往父级去触发事件

  • 2.什么是捕获 从父级元素开始,逐步触发事件至当前点击的这个元素上,这叫捕获。 他和冒泡刚好是相反的

  • tips:

    1. target 和 currentTarget 的区别 答: target 是实际点击的元素,currentTarget 是触发的元素
    1. 如果冒泡和捕获是同时存在,他们的顺序是什么 优先出现 捕获 然后是冒泡 在同一个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)