手機端的側滑導航、側滑菜單效果極其地常見,這篇文章就是分享側滑導航的制作過程。首先這是一個基于 jQuery 庫的插件,其實不用 jQuery 庫也是可以的,并且代碼改起來也不能,這里就不作過多的講解。
首先做這個效果的時候我們得分析下,要實現這個功能,我們需要什么技術。
所需技術:
1.滑動,你可以JavaScript 實現 也可以用 CSS3 實現。這里我用CSS3 實現。
2.JavaScript 事件綁定解綁、事件禁用。
從上面所需的技術可以得知要想做這個效果其實不難。好了下面我們開始吧。
這里有一個初步實現的 Demo 1:http://yunkus.com/demo/mobile-slide-side-nav-bar/index.html ,這其實是一個半成品。
當你在不滾動頁面內容的情況下,點擊導航后效果是沒問題的,但是當你滾動內容后再點擊導航按鈕,那么你會發現當菜單從左側滑出時,右側內容頂部本來應該是固定的頂部的導航不見了。這是什么回事?原來 fixed 屬性會受到transform: translate3d()屬性的影響。如果給元素設置了transform: translate3d()那么 fixed 就會失效。那這個問題要怎么解決呢?
方法一:可以通過JavaScript 來刪除transform: translate3d()那,當導航關閉時,把style=”transform: translate3d(0px, 0px, 0px);”這個行內樣式刪掉,即JavaScript 代碼里的:me.contentCtrl.removeAttr(“style”);但這種方法還是有一些瑕疵的。就是當你滑出導航菜單時,右側內容的這個頂部導航會暫時消失了,當你關閉滑動導航時,它又會回來了,并且會很明顯地出場。具體效果可以看Demo1 。
方法二:我們不妨換一種思路來實現這個 fixed 效果。用position:absolute;配合overflow:auto來替代position:fixed。我們只需要對上面的代碼稍作修改就可以了。修改后的Demo 2 :http://yunkus.com/demo/mobile-slide-side-nav-bar/index-2.html 。下面是一張橫屏的效果圖:
滑出效果
在做這個效果的時候,會遇到幾個坑:
坑
1.fixed 固定問題。
2.滑動出現卡頓。
3.事件禁用問題。
第一個問題我們已經解決了,現在來說說第二個問題,為什么會出現卡頓,一開始我做的時候,我用給transform: translate3d()傳的是百分比值,當我把這個百分比值改成具體的像素值時這個卡頓問題就解決了。就像本例子中的側邊的導航寬度設置為70%,一開始我就設置了右邊內容transform: translate3d(70%,0,0),雖然效果是實現了,但來回切換幾次后就會出現明顯的卡頓現象。解決方法就是把這個70% 通過 JavaScript 來計算出來,并動態賦值給translate3d,這個應該不難。關于最后一個問題:事件禁用。為什么要禁用一些默認的行為?因為當你點擊按鈕滑出導航后,你會發現右邊的內容還是可以通過鼠標滾輪滾動內容,或者在手機里滑動。這時我們就需要禁止瀏覽器的一些默認行為,比如鼠標滾輪,手機滑屏。在想實現這個也非常簡單。在導航滑出后,觸發下相應的preventDefault()方法就可以了。而收起導航后,取消這兩個事件監聽就可以,如果不取消,那么就會導致正常情況下瀏覽器無法滾動。
完整的 JavaScript 代碼如下:
menuSide={
run:function(){
var me=$(this)[0];
me.getElement();
me.bindElement();
},
getElement:function(){
var me=$(this)[0];
me.sideTrigger=$("#side-trigger");
me.sideCtrl=$("#side-ctrl");
me.contentCtrl=$("#content-ctrl");
me.maskTrigger=$("#mask-trigger");
me.navCloseCtrl=$("#nav-close-ctrl");
me.flag=true;// 默認關閉
},
bindElement:function(){
var me=$(this)[0];
me.sideTrigger.bind("click",function(event){
me.dealFn(event);
});
me.maskTrigger.bind("click",function(event){
me.dealFn(event);
});
me.navCloseCtrl.bind("click",function(event){
me.dealFn(event);
});
},
dealFn:function(event){
var me=$(this)[0];
var sideCtrlWidth=Math.floor(me.sideCtrl.width());
me.contentCtrl.toggleClass("side-trigger-active");
var preventDefaultEvent=function(){
me.maskTrigger.bind("wheel",function(event){
preventEvent(event);
});
me.maskTrigger.bind("touchmove",function(event){
preventEvent(event);
});
};
var preventEvent=function(event){
event.preventDefault();
event.stopPropagation();// 不管是例子一還是例子二,這行代碼可以注釋掉
};
var slideMove=function(distance){
distance=distance ||0;
me.contentCtrl.css({
"transform":'translate3d('+distance+'px,0,0)'
});
}
if(me.flag){
slideMove(sideCtrlWidth);
preventDefaultEvent();
}else{
me.maskTrigger.unbind("wheel");
me.maskTrigger.unbind("touchmove");
slideMove();
me.contentCtrl.removeAttr("style");// 如果是例子二,那么這行代碼就可以注釋掉
}
me.flag=!me.flag;
}
}
在這一段 JavaScript 中有幾個地方可能需要說明下:
授課時間:
1.$(this)[0],這個就是獲取當前對象。跟原生的this等價,注意: 在例子中的$(this)[0]是通過jQuery方法來獲取的,如果你直接$(this)是不正確的,這個是一個 jQuery 對象,而真正的 “this” 則是在這個對象里頭。
2.me 就是 menuSide 對象每個方法一開始都先把這個對象($(this)[0])傳進來,然后就可以使用這個對象下的所有方法及屬性了。
3.flag 就是用于標記側邊導航當前的狀態(滑出 | 隱藏)
做完了兩個demo 后,我有了一個小發現,demo 2 竟然可以在不禁用瀏覽器默認的滾動行為下,也實現了滑出導航后右側內容不可被動的效果(至少在 Android 機上,蘋果機未測)。
更新于:22:54 2017/3/27
Demo 1 還有一個問題就是在 Iphone 的 Safari 瀏覽器瀏覽時滾動會出現不流暢的情況。并且當你滾動內容后,點擊按鈕滑出導航,再收起側邊導航時你會發現頂部的菜單竟然不重新固定在瀏覽器窗口面部了。所以Demo 1 的坑是非常多的,如果想不管在 Android 機上還是 Iphone 上都能有最好的用戶體驗,那么請選擇 Demo 2 的方法。
查看例子演示可以用手機訪問 上面的 DEMO 地址。在發這篇文章的時候突然發現了一個問題,但現在估計來不急修正這個 BUG 了,今晚修改正,我會在網頁中記錄這個BUG,并給出解決方案 ,如果你覺得這個效果以后可能會用到自己的項目中,你可以先收藏,甚至方便的話這兩天可以訪問我的博客查看修正的 BUG。
【車型】A6LC7
【行駛里程】56483KM
【故障頻次】偶發
【故障現象】防側滑燈報警【故障分析】
1、電腦檢測網關19內有傳感器電子設備控制單元無通訊故障碼,并且3B傳感器電子設備單元自診斷也是無法達到狀態。
2、根據電路圖檢查供電保險正常。
3、當檢查完保險和供電后此車恢復正常,自診斷從無法達到轉為可以通訊。當時分析與斷電有關。但車輛行駛50km后再次出現故障,用戶觀察使用反映故障時有時無。
4、倒換傳感器電子單元后故障徹底清除不下去,再次檢查供電發現沒有電壓,檢查線路不通。
5、檢查控制單元插件時發現供電T50/1供電線針腳折斷,導致之前虛接故障時有時無,更換控制單元時徹底斷開,修復插腳后故障排除。
?