一.前言
前陣子做公司的項(xiàng)目攒至,是用混合開(kāi)發(fā)cordova
來(lái)開(kāi)發(fā)APP峻黍,開(kāi)發(fā)過(guò)程中,需要用到從底部向上的彈窗晃琳。之前用到的彈窗是使用jqm
的讯检,但是在開(kāi)發(fā)過(guò)程中發(fā)現(xiàn),如果jqm
的popup
外部的window
也是可以滾動(dòng)的話卫旱,popup
會(huì)跟隨著背后的window
滾動(dòng)人灼,這個(gè)當(dāng)然是不可取的,所以想自定義一個(gè)彈窗來(lái)滿足需求顾翼。
二.制作思路
在自定這個(gè)彈窗的時(shí)候投放,有大概構(gòu)思過(guò)步驟,就是要有一個(gè)遮罩層适贸,一個(gè)顯示內(nèi)容灸芳。其中遮罩層需要覆蓋這個(gè)mobile
界面,當(dāng)用戶點(diǎn)擊遮罩層的時(shí)候拜姿,可以關(guān)閉這個(gè)彈窗或者不關(guān)閉彈窗耗绿,可以自行設(shè)置;顯示內(nèi)容當(dāng)然是可以滾動(dòng)的砾隅,可以給顯示內(nèi)容設(shè)置一個(gè)max-height
误阻,這樣,當(dāng)內(nèi)容少的時(shí)候就顯示內(nèi)容高度,當(dāng)內(nèi)容過(guò)多時(shí)候究反,高度就為max-height
寻定。彈窗是從下面向上升起,那么顯示內(nèi)容的position
就可以設(shè)置為absolute
精耐,bottom
為0狼速,只是在打開(kāi)或者關(guān)閉的時(shí)候,改變遮罩層和顯示內(nèi)容的高度和顯示的問(wèn)題卦停。
三.遇到的bug
在具體的開(kāi)發(fā)中也是按照這樣的步驟去做向胡,但是其中遇到了一個(gè)比較大的坑,就是自定義的彈窗有滾動(dòng)條惊完,并且彈窗背后的整個(gè)頁(yè)面也是可以滾定的話僵芹,當(dāng)滾動(dòng)彈窗里面的內(nèi)容,背后的window
也會(huì)跟著滾動(dòng)小槐。這樣肯定是不可取的拇派,在網(wǎng)上也找了很多解決方法,很多說(shuō)在打開(kāi)彈窗的時(shí)候凿跳,設(shè)置window
的overflow
為hidden
就行件豌,但是這樣設(shè)置后,解決不了控嗜。后面在網(wǎng)上看到了張?chǎng)涡竦囊灿龅竭^(guò)類(lèi)似的問(wèn)題茧彤,所以就用了他的解決方法smartscroll
。
看了其中的源碼疆栏,解決的核心問(wèn)題就是彈窗滾動(dòng)到上下邊緣的滾定問(wèn)題棘街。
// 上下邊緣檢測(cè)
if (distanceY > 0 && scrollTop == 0) {
// 往上滑,并且到頭
// 禁止?jié)L動(dòng)的默認(rèn)行為
event.preventDefault();
return;
}
// 下邊緣檢測(cè)
if (distanceY < 0 && (scrollTop + 1 >= data.maxscroll)) {
// 往下滑承边,并且到頭
// 禁止?jié)L動(dòng)的默認(rèn)行為
event.preventDefault();
return;
}
運(yùn)用到自己的項(xiàng)目里面遭殉,測(cè)試一遍后發(fā)現(xiàn),iPhone
運(yùn)行沒(méi)有問(wèn)題博助,但是在Android
上發(fā)現(xiàn)险污,當(dāng)彈窗的內(nèi)容接近上下邊緣的時(shí)候,此時(shí)快速滾動(dòng)彈窗富岳,背后的window
還是會(huì)跟著滾動(dòng)蛔糯,所以自己在其中改動(dòng)了些代碼,具體的方案是窖式,當(dāng)open
彈窗的時(shí)候蚁飒,記錄下window
當(dāng)前的x
和y
,然后綁定window
的onscroll
方法萝喘,在這個(gè)方法中call window
的scrollTo
方法淮逻,滾動(dòng)的x
和y
就是上面記錄的x
和y
值琼懊,需要注意的是,在close
這個(gè)彈窗的時(shí)候爬早,需要window
的onscroll
方法哼丈,方法里面do nothing
,這樣關(guān)閉彈窗后筛严,才不會(huì)影響到window
的滑動(dòng)醉旦。
1) open彈窗時(shí)需要調(diào)用
//fiexd position for android
var x=window.scrollX;
var y=window.scrollY;
window.onscroll=function(){
window.scrollTo(x, y);
};
2)close彈窗時(shí)需要調(diào)用
window.onscroll=function(){};
當(dāng)然,在Android
中不能做到跟iOS
一樣桨啃,彈窗的滑動(dòng)完全不會(huì)影響到window
车胡,在Android
中快速滑動(dòng)彈窗,window
會(huì)有稍微的移動(dòng)嗎照瘾,但是會(huì)馬上回彈到window
原先的位置匈棘。
因?yàn)閟martscroll中,傳入了當(dāng)前頁(yè)面作為container网杆,綁定了touchmove羹饰,所以close彈窗的時(shí)候伊滋,需要給這個(gè)頁(yè)面解除綁定碳却。
張?chǎng)涡窀訚L動(dòng)解決方法
四.總結(jié)
使用jqm
中的popup
效果不佳,popup
跟著window
滑動(dòng)的問(wèn)題之前就存在了笑旺,所以自定義的彈窗也要盡量避免出現(xiàn)這個(gè)問(wèn)題昼浦。在解決這個(gè)問(wèn)題花費(fèi)了很多時(shí)間,其中最最重要的就是解決有滾動(dòng)條的彈窗的下上邊緣的問(wèn)題筒主,在臨界點(diǎn)進(jìn)行處理关噪。
五.Github地址
GitHub上,導(dǎo)入了jqm的相關(guān)代碼乌妙,因?yàn)閏ustom_alert.js文件中用到了jqm來(lái)獲取當(dāng)前頁(yè)面使兔,如果UI框架不使用jqm,可以用你項(xiàng)目的UI框架來(lái)獲取當(dāng)前頁(yè)面藤韵,然后代替里面的代碼即可虐沥,承載的彈窗的div放在page的footer中(即使顯示彈窗的頁(yè)面不需要用到footer,承載的彈窗的div放在page的footer中也不會(huì)影響)泽艘。
有實(shí)例展示欲险,直接下載源碼,就可以測(cè)試匹涮。其中做得不好的請(qǐng)指正天试,相互交流??。
源碼下載
六.運(yùn)行后樣式
制作后簡(jiǎn)單展示(如果需要美化彈窗然低,可以自行在我這個(gè)小組件上進(jìn)行修改):