DOM事件、事件流

制作“點(diǎn)擊別處關(guān)閉浮層”效果

  • debugger
  • event.stopPropagation()這個(gè)方法用于阻止事件的傳播
  • 用css制作一個(gè)小三角
#triangle{
    border:10px solid transparent;
    border-right:5px solid red;
}
  • 在某元素上添加了 preventDefault() 會(huì)導(dǎo)致它本身和它的子元素里的checkbox(<input type='checkbox'>)無(wú)法被點(diǎn)擊(因?yàn)槟J(rèn)動(dòng)作都被阻止了)

    此時(shí)無(wú)法點(diǎn)擊checkbox

  • 如何節(jié)省監(jiān)聽(tīng)器內(nèi)存?
    在實(shí)際網(wǎng)頁(yè)中我們只需要在浮層彈出時(shí)設(shè)定一個(gè)一次性事件監(jiān)聽(tīng)器

$('button').on('click',function(x){
    $(popover).show()
    $(document).one('click',function(x){
        $(popover).hide()
    })
})

這樣在浮層沒(méi)有被彈出時(shí),不對(duì)document進(jìn)行監(jiān)聽(tīng),就很好的減少了內(nèi)存的使用

  • 如何解決下圖一個(gè)小bug?(兩種方法)
    如果代碼照下面寫,會(huì)導(dǎo)致點(diǎn)擊按鈕后浮層不彈出的問(wèn)題
$('button').on('click', function (x) {
    $(popover).show()
    console.log('展示浮層')
    $(document).one('click', function (x) {
        $(popover).hide()
        console.log('隱藏浮層')
    })
}) 
控制臺(tái)結(jié)果

可以看到同時(shí)執(zhí)行了兩個(gè)函數(shù),這是因?yàn)樵凇甤lick’事件的target階段就已經(jīng)將document的監(jiān)聽(tīng)器設(shè)定好了,等到‘click’事件冒泡到document時(shí)一次性監(jiān)聽(tīng)器中的函數(shù)就會(huì)被執(zhí)行
方法1:給button的父級(jí)元素添加 event.stopPropagation()方法

//此時(shí)button的父級(jí)元素是wrapper
wrapper.addEventListener('click',function(x){
    x.stopPropagation()
})

方法2:用setTimeout()

$('button').on('click', function (x) {
    $(popover).show()
    console.log('展示浮層')
    setTimeout(function () {
        $(document).one('click', function (x) {
            $(popover).hide()
            console.log('隱藏浮層')
        })
    }, 0)
})
  • setTimeout(()=>{},0) 是如何實(shí)現(xiàn)異步操作的
  • 最終代碼
    $('#btn').on('click',function () {
      $('#popover').toggleClass('show')
      .one('click',()=>{
        setTimeout(function () {
        $(document).on('click',function () {
          $('#popover').removeClass('show');
        })
      },0)
      })
    })
    $('#wrap').on('click',function (e) {
      e.stopPropagation();
    })

DOM事件的進(jìn)一步了解

http://js.jirengu.com/jamirapaqi/1/edit

無(wú)縫輪播

  • 無(wú)縫輪播一個(gè)bug:從其他頁(yè)面切換回?zé)o縫輪播頁(yè)面的時(shí)候,會(huì)出現(xiàn)輪播亂了的情況(自己做做看),原因在于瀏覽器在頁(yè)面切出去后不會(huì)執(zhí)行setInterval()的內(nèi)容,在等用戶切回頁(yè)面之后,再同時(shí)執(zhí)行setInterval()的內(nèi)容,這導(dǎo)致了輪播可能出現(xiàn)混亂
  • 解決方法1:通過(guò)監(jiān)聽(tīng)visibilitychange事件,在用戶沒(méi)有看該頁(yè)面時(shí)把setInterval()停掉,代碼如下:
 document.addEventListener('visibilitychange', function (x) {
    if (document.hidden) { ///如果當(dāng)前頁(yè)面沒(méi)有被瀏覽就不要再執(zhí)行輪播
        window.clearInterval(timer)
    } else {///如果切換回輪播頁(yè)面,重新啟動(dòng)輪播效果
        timer = setInterval(() => {
            slide(n)
            n++
        }, 1500)
    }
})

document.hidden返回布爾值,用于查看當(dāng)前頁(yè)面是否被瀏覽
這可以防止輪播混亂

  • 要實(shí)現(xiàn)又能點(diǎn)擊切換圖片又能無(wú)縫輪播
    用到element屬性:outerHTML
    用到以下jQueryAPI
    clone()
    append()末尾插入元素,可以接受DOM元素、jQ對(duì)象、字符串
    prepend()最前面插入元素,可以接受DOM元素、jQ對(duì)象、字符串
  • 在一句代碼中出現(xiàn)hide()show(),瀏覽器可能會(huì)同時(shí)處理,沒(méi)辦法達(dá)到想要的效果。此時(shí)在中間加入offset(),會(huì)使瀏覽器不同時(shí)進(jìn)行offset()show(),達(dá)到想要的效果
    .offset()返回一個(gè)對(duì)象,該對(duì)象包含jQ對(duì)象相對(duì)于document的位置
$(btn).eq(0).on('click',()=>{
  if(current === 2){
    $slide.css({'transform':'translateX(-1200px)'})
    .one('transitionend',()=>{           
           $slide.hide().offset()
           $slide.css({'transform':'translateX(-400px)'})//.offset()返回的不是jQ對(duì)象所以不能直接鏈?zhǔn)讲僮?           
      })    
  }
})

猜想用setTimeout(fn,0)也能實(shí)現(xiàn)相同效果,但發(fā)現(xiàn)在切換的動(dòng)畫過(guò)程中會(huì)有閃爍

$btn.eq(0).on('click',()=>{
    if(current === 2){
        $slide.css({'transform':'translateX(-1200px)'})  
        .one('transitionend',()=>{
            $slide.hide()
            setTimeout(() => {
                $slide.css({'transform':'translateX(-300px)'}).show()
            }, 0);
            
        })

事件流

事件流描述的是事件在頁(yè)面中傳播的順序,它包括三個(gè)階段:捕獲階段、目標(biāo)階段、冒泡階段。
在DOM2級(jí)事件中,用addEventListener()來(lái)處理事件。該函數(shù)接受三個(gè)參數(shù),由第三個(gè)參數(shù)決定事件被觸發(fā)后回調(diào)函數(shù)在哪個(gè)階段被執(zhí)行,該參數(shù)默認(rèn)為false,即冒泡階段被執(zhí)行。
需要注意的是,觸發(fā)事件時(shí)嵌套最深,最底層的那個(gè)元素,它沒(méi)有冒泡和捕獲階段,僅有目標(biāo)階段。而在目標(biāo)階段,回調(diào)函數(shù)的執(zhí)行順序只由代碼的順序決定。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,071評(píng)論 4 61
  • ??JavaScript 與 HTML 之間的交互是通過(guò)事件實(shí)現(xiàn)的。 ??事件,就是文檔或?yàn)g覽器窗口中發(fā)生的一些特...
    霜天曉閱讀 3,680評(píng)論 1 11
  • 以下文章為轉(zhuǎn)載,對(duì)理解JavaScript中的事件處理機(jī)制很有幫助,淺顯易懂,特分享于此。 什么是事件? 事件(E...
    jxyjxy閱讀 3,162評(píng)論 1 10
  • 今天上午我去小區(qū)前面的蔬菜店買兩番茄,老板給我稱了一下,一共1.5元,我去柜臺(tái)準(zhǔn)備付錢,當(dāng)時(shí)看到一個(gè)2歲的孩子在一...
    清水曼殊閱讀 221評(píng)論 0 0
  • 把握人生方向,永遠(yuǎn)找得到北! 此次內(nèi)蒙古呼倫貝爾大草原、黑龍江大興安嶺森林尋北之旅,歷時(shí)八天八夜,每日200-30...
    龍馬行天下閱讀 1,054評(píng)論 1 3

友情鏈接更多精彩內(nèi)容