制作“點(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('隱藏浮層')
})
})

可以看到同時(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í)行順序只由代碼的順序決定。
