H5填坑筆記--持續更新


  最近一直在做移動端的頁面,發現很多的坑,這里做一下總結,填填坑……

css常見的問題(一)

一、iOS鍵盤首字母自動大寫

  IOS的機子,默認英文輸入法狀態下,首字母是自動大寫的,有時候挺煩人的。

  在iOS中,默認情況下鍵盤是開啟首字母大寫的功能的,如果業務不想出現首字母大寫,可以這樣:

<input type="text" autocapitalize="off" />

二、iOS輸入框默認內陰影和樣式問題

  在iOS上,輸入框默認有內部陰影,但無法使用 box-shadow 來清除,如果不需要陰影,可以這樣關閉,不過加了上面的屬性后,iOS下默認還是帶有圓角的,不過可以使用 border-radius屬性修改:

input,
textarea {
    border: 0; 
    -webkit-appearance: none; 
}

三、andriod輸入框type = "number"存在樣式問題

去除input[type=number]的默認樣式

input[type=number] {
    -moz-appearance:textfield;
}
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

四、輸入框光標不居中問題

  通常,移動端如果我們不設置line-height值時,大部分機器輸入框的光標是可以居中的,但是如果我們用line-height:$height值,卻導致光標不居中問題

  遇到這個問題,我們只能用line-height:$height\9來處理居中問題,這里就不能用line-height:$height,示例代碼:

height:40px;
line-height:40px\9;
font-size:16px;

五、輸入框前置用text-indent縮進問題

  css中text-indent縮進,但是在部分andriod機中,光標是輸入框先獲得光標依然在最左邊,然后輸入文字才到縮進的值,這樣很不好,建議通過padding-left設置縮進,完美解決。

六、a標簽默認激活高亮框問題

  在做移動端頁面時,會發現所有a標簽在觸發點擊時或者所有設置了偽類 :active 的元素,默認都會在激活狀態時,顯示高亮框,如果不想要這個高亮,那么你可以通過css以下方法來禁止:

.xxx {
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

  這個設置,在大部分機子上都是起效果的。但是,移動端三星自帶瀏覽器,點擊頁面任意a標簽時,設置-webkit-tap-highlight-color:rgba(0,0,0,0)還是會有陰影底色,這應該是瀏覽器強制加上去的,通過代碼設置也無法覆蓋。

  有一種妥協的方法是把頁面非真實跳轉鏈接的a標簽換成其它標簽,可以解決這個問題。

七、Android 2.3 自帶瀏覽器不支持border-radius 中 %

  建議大家寫在使用border-radius寫圓角時,還是不要border-radius:50%實現圓,建議用具體的數值。

八、border邊框1像素問題

  移動端 當設置 通用viewport 后。代碼中的 1px 單位的邊框實際在高清屏( @2x )pixel-ratio:2上顯示的是2像素,pc ( 非高清屏幕 ) 上顯示的正常的1px。

border:1px solid #000

  可能看到這里,大家又有疑問了,干嘛我們不把border-width:0.5px呢,可是早的瀏覽器不支持,到了ios8.0才支持這個

  現在通常來說有兩種解決方案:1.通過border-image實現(但缺點是不能實現四邊邊框,而且加載浪費資源) 2.通過scale進行縮放

  1.border-image 實現演示(掃碼地址):

  

  2.通過scale進行縮放

    ①單邊1像素邊框處理方法通過偽類畫出邊框,然后通過scale將其縮放,最后處理@1.5x(安卓機器) @2.0x(ios機器) @3.0x(注意是 1080p)的縮放比例

%border-btm-1pt{
  content: '';
  height: 0px;
  display: block;
  border-bottom:1px solid #ddd;
  position: absolute;
  left:0;
  right:0;
  bottom:0;
}
.some_div{
    position:relative; // 因為偽類用的absolute 所以需要添加 relative 
    &:after{
        @extend %border-btm-1pt
        border-color:#f09;  // 在這里自定義邊框顏色。
    }
 
}

//適配早期的andriod機器    1/1.5 = 0.666
@media only screen and (-webkit-min-device-pixel-ratio: 1.5) {
    .some_div{
        -webkit-transform: scaleY(0.666)
    }
}
//高清屏( @2x ) iphone這種  1/2 = 0.5
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
    .some_div{
        -webkit-transform: scaleY(0.5)
    }
}
//1080機子@3x 
@media only screen and (-webkit-min-device-pixel-ratio: 3) {
    .some_div{
        -webkit-transform: scaleY(0.333)
    }
}        

 案例:

@media only screen and (-webkit-min-device-pixel-ratio: 1.5),(min-resolution: 120dpi),(-ms-high-contrast: active),(-ms-high-contrast: none) {
    .jd_space:after{
        -webkit-transform:scaleY(0.5);
        -webkit-transform-origin: 50% 100%
    }

    .jd_space:before{
        -webkit-transform: scaleY(0.5);
        -webkit-transform-origin: 50% 0%
    }

    .jd_brand{
        -webkit-transform: scaleX(0.5);
        -webkit-transform-origin: 0% 0%
    }

    .jd_brand{
        -webkit-transform: scaleX(0.5);
        -webkit-transform-origin: 0% 0%
    }

    .jd_madden{
        -webkit-transform: scale(0.5);
        -webkit-transform-origin: 0% 0%;
        bottom: -100%;
        right: -100%
    }
}

@media only screen and (-webkit-min-device-pixel-ratio: 3) {
    .jd_space:before{
        -webkit-transform: scaleY(0.333)
    }

    .jd_madden{
        -webkit-transform: scale(0.333);
        -webkit-transform-origin: 0% 0%;
        bottom: -200%;
        right: -200%
    }
}

@media only screen and (-webkit-device-pixel-ratio: 1.5) {
    .jd_space:before{
        -webkit-transform: scaleY(0.666)
    }

    .jd_madden .jd_item:before{
        -webkit-transform: scale(0.666);
        bottom: -50%;
        right: -50%
    }
}

  

   ②處理四邊邊框1px問題,兩種思路:1.子邊框兩邊通過偽類,父邊框兩邊通過偽類 2.一個偽類,畫出四邊邊框,然后通過width:200%;height:200%(這里主要說的是@2.0x機器,由於@1.5 @3比例無法算整會導致不夠精確,不予討論);即把內容縮放兩倍,進行縮放scale ,處理。

    這里舉例第二種情況(但是這里要注意的是,如果容器里面有a鏈接,就會導致設置的偽類遮住元素,無法點擊,所以容器里面的內容也要設置絕對定位):

  

    <style type="text/css">

        h3{text-align:center}
        div.border_scale{
            margin:100px auto;
            width:600px;
            height:150px;
            position:relative;
        }
        div.border_scale:before{
            display:block;
            position:absolute;
            content:"\20";
            width:200%;
            height:200%;
            border:1px solid #000;
            -webkit-transform-origin:0 0;
            transform-origin:0 0;
            -webkit-transform:scale(0.5);
            transform:scale(0.5);
            top:-1px;
            left:-1px;
        }
        div.border_scale a{
            display:block;
            width:100%;
            height:100%;
            text-align:center;
        }
    </style>
    <h3>border的1像素框 scale</h3>
    <div class="border_scale">
        <a href="http://www.baidu.com">百度</a>
    </div>

  sass庫 1像素邊框:

%border-1pt{
  content: '\20';
  display: block;
  position: absolute;
  top:0;
  bottom:0;
  left:0;
  right:0;
  pointer-events:none;
}

@media only screen and (-webkit-min-device-pixel-ratio:1.5),(min-resolution:120dpi),(-ms-high-contrast:active),(-ms-high-contrast:none){
  %border-1pt{
    -webkit-transform:scale(0.5);
    -webkit-transform-origin:0% 0%;
    bottom:-100%;
    right:-100%;
  }
}
    
@media only screen and (-webkit-min-device-pixel-ratio:3){
  %border-1pt{
    -webkit-transform:scale(0.333);
    -webkit-transform-origin:0% 0%;
    bottom:-200%;
    right:-200%;
  }
}

@media only screen and (-webkit-device-pixel-ratio : 1.5){
  %border-1pt{
    -webkit-transform:scale(0.666);
    bottom:-50%;
    right:-50%;
  }
}

div.border_test{
  margin:20px;
  height:200px;
  position: relative;
  background: orange
}
div.border_test:before{
 @extend %border-1pt;
  border:1px solid #fff;
}

九、通過transform進行skew變形,rotate旋轉會造成出現鋸齒現象

  在制作H5頁面我們難免會對一些元素進行旋轉、變形,可是這樣卻惡來許多麻煩,出現鋸齒他媽的咋辦,還不如直接圖片,對吧。

  我們可以通過這樣直接解決煩惱:我發現呢微信更新到6.2.4之后對旋轉鋸齒有些修復

    -webkit-transform: rotate(-4deg) skew(10deg) translateZ(0);
    transform: rotate(-4deg) skew(10deg) translateZ(0);
    outline: 1px solid rgba(255,255,255,0)

十、h5頁面中內容滾動滾動條問題

  在我們做h5頁面時,經常遇到要在容器內容里面做滾動調的問題,但是,當我們用那些滾動條時,發現,在andriod里面實在是太丑陋了,通常還會出問題,產品MM也接受不了,所以這里給大家提供一個解決方案:

.scroll::-webkit-scrollbar{width:5px; height:5px;}
.scroll::-webkit-scrollbar-button{width:0;height:0;}
.scroll::-webkit-scrollbar-corner{display:block; }
.scroll::-webkit-scrollbar-thumb{background-clip:padding-box;background-color:rgba(0,0,0,.2);border-radius:8px;}//還可以設置滾動條的顏色
.scroll::-webkit-scrollbar-thumb:hover{background-clip:padding-box;background-color:rgba(0,0,0,.5);border-radius:8px;}

  讓我們的滾動條變成這樣,從此媽媽再也不用擔心滾動條問題了,上圖:

十一、CSS3 timing-function: steps()理解運動函數的問題

   steps() 第一個參數 number 為指定的間隔數,即把動畫分為 n 步階段性展示,第二個參數默認為 end,設置最后一步的狀態,start 為結束時的狀態,end 為開始時的狀態。 

 steps 有兩個參數
  第一個肯定是分幾步執行完
  第二個有兩個值
    start 第一幀是第一步動畫結束    //第一個階段結束之后的值
    end 第一幀是第一步動畫開始   //第一個階段開始的值

理解 start 第一幀是第一步動畫結束    end 第一幀是第一步動畫開始,number為階段數

demo:http://pingfan1990.sinaapp.com/honor7/anim.html

我們看最后一個tab,可以反襯出以下

十二、inline-display 在andriod2.3下通過:before偽類導致擠下去的問題

  這里建議用:after將容器撐起。

steps() 第一個參數將動畫分割成三段。當指定躍點為 start 時,動畫在每個計時周期的起點發生階躍(即圖中空心圓 → 實心圓)由於第一次階躍發生在第一個計時周期的起點處(0s),所以我們看到的第一步動畫(初態)就為 1/3 的狀態,因此在視覺上動畫的過程為 1/3 → 2/3 → 1 

 

當指定躍點為 end,動畫則在每個計時周期的終點發生階躍(即圖中空心圓 → 實心圓)。由於第一次階躍發生在第一個計時周期結束時(1s),所以我們看到的初態為 0% 的狀態;而在整個動畫周期完成處(3s),雖然發生階躍跳到了 100% 的狀態,但同時動畫結束,所以 100% 的狀態不可視。因此在視覺上動畫的過程為 0 → 1/3 → 2/3(回憶一下數電里的異步清零,當所有輸出端都為高電平的時候觸發清零,所以全為高電平是暫態)。  

 

  但是當我們看到這樣的圖片的時候,知道這個有12幀,我么就會理解為steps(12),其實這里是11個階段完成的,應該是steps(11);

  demo:http://pingfan1990.sinaapp.com/honor7/anim1.html

  steps(11)幀等價於,總長1680,默認是steps(11,end):

        @-webkit-keyframes run1{
              0%{ background-position: 0 0; }
              9.09%{ background-position: -140px 0; }
              18.18%{ background-position: -280px 0; }
              27.27%{ background-position: -420px 0; }
              36.36%{ background-position: -560px 0; }
              45.45%{ background-position: -700px 0; }
              54.54%{ background-position: -840px 0; }
              58.33% { background-position: -980px 0; }
              63.63% { background-position: -1120px 0; }
              72.72% { background-position: -1260px 0; }
              81.81% { background-position: -1400px 0; }
              /*中間缺10張圖,11個階段*/
              100% {
                background-position: -1540px 0; // 12幀
              }    
        }    

  而steps(12)幀等價於,總長1680,默認是steps(12,end):

//這里background-position-x按幀均分,我就不算了
@keyframes run {
  0% { background-position: 0 0; }
  8.33% { background-position: -140px 0; }
  16.67% { background-position: -280px 0; }
  25% { background-position: -420px 0; }
  33.33% { background-position: -560px 0; }
  41.67% { background-position: -700px 0; }
  50% { background-position: -840px 0; }
  58.33% { background-position: -980px 0; }
  66.67% { background-position: -1120px 0; }
  75% { background-position: -1260px 0; }
  83.33% { background-position: -1400px 0; }
  91.67% { background-position: -1540px 0; }
  100% { background-position: -1540px 0; }
}

  做動畫時請不要在:before和:after這些偽類身上做動畫,移動端不支持。做animation動畫時,我們可以結合,webkitAnimationEnd 這個事件來監聽,改變動畫,做出更炫的效果。

 

十二、animation不簡寫,可能造成的問題

  今天做動畫時遇到animation不簡寫導致的問題,為了讓動畫達到步奏迭代,我們通常會用animation-delay來設置延遲時間,但是我發現單獨分開寫時,會導致在紅米手機上面出現,動畫元素失真的問題。

十三、animation屬性值js控制

  常見的文字左右滾動通常實現形式就用animation實現設置好duration時間,但是有些時候,我們希望動態改變animation-duration的執行時間,但是發現ios生效,android不生效這種情況,是由於animation初始渲染之后,android改動是不允許生效的,這時我們只能在頁面初始加載的時候,在頭部加入js,document.write()寫入樣式進行控制了。 

十四、transform中scale放大圖形導致失真的問題

  昨天遇到一個問題,就是一個白色小圓通過scale放大,導致在移動端出現不同程度的失真,ios邊緣很刺,andriod就顯示成邊緣半透明的方向了。

  最終發現我們通過transform的scale進行縮放,其實是對位圖放大(不管圖片還是圖形),會導致失真,解決辦法,先用大的圖形,進行縮小操作。

十五、translate3d引起的問題

  1.translate3d會引起兄弟元素的z-index層級無效;原因是t3d實際是有z軸層的變換,解決辦法自己處理的是在兄弟元素上也加上t3d。
  2.translate3d內部的fixed元素效果失效;從css角度無解,只能js控制或者把它抽離成t3d的兄弟元素。

 

十四、position定位引起的ios樣式問題

  兩種情況:

<i class="fix_jd">獎勵20豆</i>


樣式
i.fix_jd{
	position:fixed;
	bottom:60px;
	display: block;
	padding:0 10px;
	background: #e4393c ;
	height:16px;
	line-height: 16px;
	font-size: 12px;
	@include boradius(8px);
	color:#fff;
	left:48.4%;	
	z-index: 1;
	&:before{
		display: block;
		position: absolute;
		content:"\20";
		@include base64Img("border_san.png");
		 bottom:-4px;
		 left:10px;	
	}
}

  

  1.父級 position:fixed, 子級position:absolute,可能導致色塊隨滾動條的變化,變藍色。

  

  左邊是需要的正常效果,右邊是由於滾動條滾動出錯的效果。

  我最終的解決辦法就是調整結構,用兩個position:fixed,或者,整個層,只用一個position:fixed.

  2.父級 position:relative,子級position:absoltue,從子級position:absolute,導致,從子級的圓角無法溢出隱藏。

  這個問題主要出現在一些ios版本比較舊的機型上面,也是一樣,調整結構,盡可能的少用position。

 

十五、position:fixed吸頂菜單,js監聽阻塞,吸頂延遲問題

  解決ios8.4版以上移動端,吸頂延遲問題

  1. sticky 元素只能在父容器內活動
  2. sticky 元素父容器不能含有overflow:hidden 和 overflow:auto 屬性

  示例代碼:

<div class="wx618_tabs">
        <ul>
            <li class="cur">手機</li>
            <li>IT數碼</li>
            <li>家電<span class="sign_c_tip">小氣泡</span></li>
            <li>時尚服飾</li>
        </ul>
    </div>

  css樣式:

.wx618_tabs {
  position: relative;
  .wx618_tabs.fixed ul {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%; 
    }
}

@supports (position: -webkit-sticky) {
  .wx618_tabs {
        position: -webkit-sticky;
        top: 80px; 
    }
    .wx618_tabs.fixed ul {
          position: relative; 
      } 
  }

 

 

js常見的問題(二)

一、移動端點擊300ms延遲的問題 

  click300ms延遲是由於iphone采用的是雙擊默認是放大頁面,實現click是判斷第二次點擊間隔時間300ms認定為click,許多廠家沿用而導致的,click 事件因為要等待雙擊確認,會有 300ms 的延遲,體驗並不是很好。

  開發者大多數會使用封裝的 tap 事件來代替click 事件,所謂的 tap 事件由 touchstart 事件 + touchmove 判斷 + touchend 事件封裝組成。

  FastClick.jstap.js可以有效的解決300ms延遲的問題。

  參考資料 單擊300ms延遲

二、移動端點透問題

  簡單的說,由於在移動端我們經常會使用tap(touchstart)事件來替換掉click事件,那么就會有一種場景是:

<div id="mengceng"></div>
 
<a href="www.jd.com">www.jd.com</a>

  div是絕對定位的蒙層z-index高於a,而a標簽是頁面中的一個鏈接,我們給div綁定tap事件:

$('#mengceng').on('tap',function(){
$('#mengceng').hide();
});

  我們點擊蒙層時 div正常消失,但是當我們在a標簽上點擊蒙層時,發現a鏈接被觸發,這就是所謂的點透事件。

  分析原因:

  touchstart 早於 touchend 早於 click。亦即click的觸發是有延遲的,這個時間大概在300ms左右,也就是說我們tap觸發之后蒙層隱藏,此時click還沒有觸發,300ms之后由於蒙層隱藏,我們的click觸發到了下面的a鏈接上。
  解決辦法:
  1 盡量都使用touch事件來替換click事件。
  2 阻止a鏈接的click的preventDefault

  點透資料:http://segmentfault.com/q/1010000000691822

三、移動端touch事件問題,在andriod4.0

  移動端touch事件:
    touchstart //當手指接觸屏幕時觸發
    touchmove //當已經接觸屏幕的手指開始移動后觸發
    touchend //當手指離開屏幕時觸發
    touchcancel//當某種touch事件非正常結束時觸發
  這4個事件的觸發順序為:
    touchstart -> touchmove -> touchend ->touchcancel

  對於某些android系統touch的bug:

  比如手指在屏幕由上向下拖動頁面時,理論上是會觸發 一個 touchstart ,很多次 touchmove ,和最終的 touchend ,可是在android 4.0上,touchmove只被觸發一次,觸發時間和touchstart 差不多,而touchend直接沒有被觸發。這是一個非常嚴重的bug,在google Issue已有不少人提出 ,這個很蛋疼的bug是在模擬下拉刷新是遇到的尤其當touchmove的dom節點數量變多時比出現,當時解決辦法就是用settimeout來稀釋touchmove。 

  或者通過在touchmove阻止默認行為preventDefault,這里就會導致要通過js來實現頁面的滾動

//發現在android4.0以上的webkit瀏覽器touchmove事件只觸發一次,加event . preventDefault()就可以,但是這里就導致只能通過js來實現頁面的滾動
addEventListener("touchmove",function(e){
    e.stopDefault(e);    
},false)

四、 html5重力感應事件

   這個不是什么問題,我只是覺得好,所以說一下,當回搬運工,簡單的搖一搖案例。

if (window.DeviceMotionEvent) { 
                 window.addEventListener('devicemotion',deviceMotionHandler, false);  
        } 
        var speed = 30;//speed
        var x = y = z = lastX = lastY = lastZ = 0;
        function deviceMotionHandler(eventData) {  
          var acceleration =event.accelerationIncludingGravity;
                x = acceleration.x;
                y = acceleration.y;
                z = acceleration.z;
                if(Math.abs(x-lastX) > speed || Math.abs(y-lastY) > speed || Math.abs(z-lastZ) > speed) {
                    //簡單的搖一搖觸發代碼
                    alert(1);
                }
                lastX = x;
                lastY = y;
                lastZ = z;
        }

  關於deviceMotionEvent是HTML5新增的事件,用來檢測手機重力感應效果具體可參考:

  http://w3c.github.io/deviceorientation/spec-source-orientation.html

四、 多音頻的問題

  我們知道,ios設備可以多音頻支持,但是andriod不支持多音頻,很多時候做法往往是我們先靜止背景音樂,然后去播放另一音樂,感覺上實現多音頻。

  這里大家也可以嘗試第三方插件:

  *優先使用 Web Audio API
  *SoundJS 等音頻處理庫

五、 橫屏監測

  樣式判斷

//橫屏
@media only screen and (orientation: landscape) {
    .warn_wp {
        display: block
    }
}

//豎屏
@media only screen and (orientation: portrait) {
    .warn_wp {
        display: none
    }
}

  腳本判斷:

//橫屏監聽
var updateOrientation = function(){
	var $landscapeWrap = $('.landscape_wrap');
	if(window.orientation === -90 || window.orientation === 90){
			$landscapeWrap.show();
		}else{
			$landscapeWrap.hide();
		}
	}
}
window.orientationchange = updateOrientation;

  

經典材料:

  meta標簽大全 http://segmentfault.com/blog/ciaocc/1190000002407912

  使用border-image實現類似iOS7的1px底邊:https://github.com/AlloyTeam/Mars/blob/master/solutions/border-1px.md

  devicePixelRatio:http://imququ.com/post/devicepixelratio-and-border-width.html

  移動問題小結:http://www.alloyteam.com/2015/06/yi-dong-web-wen-ti-xiao-jie/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM