事件池 dom0 dom2

  • 設計模式

    • 發(fā)布訂閱-觀察者
      • 事件池 存放->按順序執(zhí)行
    • 模塊模式
      • 閉包
    • 工廠模式
      • 無法區(qū)分關系
    • 構造函數(shù)模式
    • 混合模式(工廠 模塊)
      • 定制化
    • 單例模式
      • 有且只有一個
  • JQ的發(fā)布訂閱

    • .Callbacks()-回調函數(shù)集合(無去重處理) //JQ的事件池 letpond1=.Callbacks() //創(chuàng)建事件池('.submit').click(function(){
      spond1.fire(100); //執(zhí)行事件池中的方法 傳參 })pond1.add(func) //添加到事件池中的方法
      $pond1.remove(func) //移除事件池中的方法
  • DOM0和DOM2

    • 語法上的區(qū)別
      • dom0 box.onclick=function(){}
      • dom2 box.addEventListener('click',function(a,b,c){}) //a:事件名 click b:方法名 c:true-捕獲階段調用 false-冒泡階段調用
    • 底層運行機制
      • dom0 元素某個屬性綁定方法值 有效綁定的方法只有一個(后面替換之前的)
      • dom2 基于事件池機制完成,每增加一個綁定的方法,都會往事件池中存放一個 當事件觸發(fā)會依次執(zhí)行事件池中的事件(類似發(fā)布訂閱模式 模擬事件池機制),可以給同一個元素的某個事件綁定多個不同的方法
    • dom2中可以給一些特殊的事件類型綁定方法,這些類型dom0不支持綁定,DOMContentLoaded(dom結構加載完成 觸發(fā)執(zhí)行事件)、transitioned(css3 過渡動畫執(zhí)行完成觸發(fā))
      • (document).ready() =>(function(){}) dom2 可以綁定多個
        • dom結構加載完成就執(zhí)行
      • window.onload dom0 只能綁定一個 => dom2 window.addEventListener('onload',function(){})
        • dom樹+所有相關資源均加載完畢才執(zhí)行
    • dom2的事件池機制
      1. 基于addEventListener/attachEvent(IE6-8)向事件池追加方法、新版本瀏覽器會根據(jù)元素和事件類型對新增方法做重復校驗,但是IE6-8不可以
      2. removeEventListener/dttachEvent刪除事件 不能移除匿名函數(shù)
      3. 當事件行為觸發(fā),會把事件池中的方法按照增加的順序執(zhí)行,但IE6-8中執(zhí)行的順序是不固定的(亂序執(zhí)行) 捕獲 目標 冒泡
  • 事件池--數(shù)組塌陷

        let _subscribe=(function(){
            //發(fā)布訂閱類subscribe
            class Sub(){
                constructor(){
                    //創(chuàng)建事件池 存儲后期需要執(zhí)行的方法
                    this.$pond = [];
                    
                    //向事件池中追加方法   func(需要追加的方法 判斷是否是方法 去重)
                    add(func){ 
                        /*some
                            arr.some(item=>{
                                return item>1
                            })
                            找true
                            是否存在滿足條件的 true   循環(huán)結束沒有 false 不檢測空數(shù)組,不改變原始數(shù)組) 
                        
                        every
                            找false
                            找到后終止并返回false 每個對象是否滿足條件
                        
                        find
                            arr.find(item=>{
                                return item.flag
                            })   
                            返回找到的滿足條件的第一項,停止循環(huán) 不改變原始數(shù)組 循環(huán)完畢沒找到返回undefined,不檢測空數(shù)組)
                        
                        
                        includes(arr.includes(1)  true/false) filter(篩選 返回新數(shù)組,不改變舊的) 
                        
                        map(映射 返回新數(shù)組,不改變舊的) 
                        */
                        let flag = this.$pond.some(item=>{
                            return item===func
                        })
                        if(!flag){
                            this.$pond.push(func)
                        }
                        // !flag ? this.$pond.push(func) : null;
                    }

                    //移除事件池中的方法
                    remove(func){
                        //splice filter  淺拷貝 堆內存 引用類型
                        let $pond=this.$pond;
                        for(let i=0;i<$pond.length;i++){
                            let item=$pond[i];
                            if(item===func){
                                //移除 不改變方法順序(改變順序 刪除當前項 將最后一項添加到當前位置,然后刪除最后一位--性能優(yōu)化) splice(i,n)
                                $pond.splice(i,1);  //導致數(shù)組塌陷-->假移除 賦值為null
                                $pond[i]=null//解決數(shù)組塌陷 偽刪除 保證索引
                                break;  
                                //終止循環(huán) 區(qū)別return(終止當次循環(huán))  
                            }
                        }
                    }

                    //通知事件池中的方法依次執(zhí)行
                    fire(...args){   //...擴展運算符   args  傳進來所有參數(shù)的數(shù)組(不確定參數(shù)有幾個)
                        let $pond=this.$pond
                        for(let i=0;i<$pond.length;i++){
                            let item=$pond[i]
                            if(typeOf item!=='function'){
                                $pond.splice(i,1);  //再進行刪除
                                i--;
                                continue;//跳過循環(huán)體中剩下的語句                                 
                            }
                            item.call(this,...args)  //this指向當前實例   單獨傳參 在三個或以上參數(shù)時 call的性能略優(yōu)與apply  --apply  數(shù)組傳參
                        }
                    }
                }
            }
            return function subscribe(){  //暴露外界使用 做普通函數(shù)
                return new Sub()
            } 
        })();//閉包 防止污染 沖突

        let s1 = _subscribe(); //創(chuàng)建實例 事件池
        document.querySelector('.submit').onclick=function(event){
            let evt=event?event:window.event;    //cancelBubble  取消事件冒泡        stopPropagation  取消事件冒泡和下沉
            s1.fire(evt) //執(zhí)行事件池中的方法執(zhí)行
        }
        s1.add(func)
        s1.remove(func)
  • B站學習偶然看到的 up主-光影嗶哩 珠峰培訓課程
  • 之前的知識忘卻大部分了 有錯誤的地方歡迎大佬聯(lián)系我改正
  • 好久不學習了~ 咸魚太久了啊
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • dom事件 1.什么是事件?事件就是一件事情或者行為(對于元素來說他的很多事件都是天生自帶)只要我們去操作這個元素...
    田成力閱讀 740評論 0 0
  • 22、JQ的基礎語法、核心原理和項目實戰(zhàn) jQ的版本和下載 jQuery版本 1.x:兼容IE6-8,是目前PC端...
    萌妹撒閱讀 1,867評論 0 0
  • 事件流分為兩種,捕獲事件流和冒泡時間流 捕獲事件流:從根節(jié)點出發(fā)開始執(zhí)行,一直往子節(jié)點查找執(zhí)行,直到查到到根節(jié)點。...
    路上靈魂的自由者閱讀 451評論 0 0
  • 什么是事件 事件分為兩部分:1)行為本身:瀏覽器賦予的行為(本來就存在的):onclick、onmouseover...
    沒了提心吊膽的稗子閱讀 257評論 0 0
  • 聲明:本文來源于http://www.webzsky.com/?p=731我只是在這里作為自己的學習筆記整理一下(...
    angryyan閱讀 7,239評論 1 6

友情鏈接更多精彩內容