web移動端Fixed在Input獲取焦點時ios下產生的BUG及處理

1.現象

能夠看到下面兩張圖,圖1搜索框爲fixed固定在頂部,滾動沒有任何問題。javascript

圖2當光標進入搜索框時,ios自做聰明的把光標定位到中間,而且fixed屬性被自動修改爲了absolute。此時注意滾動頁面的話,會發現本來fixed的搜索框跟着文檔一塊兒滾動了。css

再仔細觀察ios下的一些特色,ios爲了讓input垂直居中,甚至還滾動了滾動條,本來看不到的上半段產品的內容也漏出來了。html

 

2. 參考別人的解決方法

在網上搜索事後,大部分都是轉載的這一篇文章,甚至配圖都是拿別人原來的:java

http://efe.baidu.com/blog/mobile-fixed-layout/jquery

這個解決方案,主要用到了一個div包裹了整個能夠滾動的部分,而後不能滾動的部分就固定在底部,不失爲一種不錯的解決方案,惋惜個人搜索框不是一直固定在頂部,頁面滾動到下面的時候纔出現搜索框置頂,頁面回到最頂部時搜索框要消失,而且我須要監控window.onscroll,作自動翻頁的ajax請求等等,最後這個方案就無法使用了。即便要使用的話修改量應該也很大。android

 

在參考了下面這篇文章後,想到了新的思路:ios

http://www.cnblogs.com/yexiaochai/p/3561939.htmlweb

 

3. 新的思路

文章中提到,ajax

咱們想到這麼一個場景,若是咱們能監控到鍵盤的行爲,若是能的話,咱們即可以app

① 鍵盤彈出時候將fixed元素設置爲static(最後我設置成absolute)

② 鍵盤消失時候將fixed元素設置爲fixed

3.1 錯誤的嘗試

基於這個想法,進行一系列的測試,首先static的意思是迴歸文檔,致使整個搜索框都找不到了,由於可能回到文檔最底部去了。因此static不可用,那麼absolute呢,只要設置成absolute而後設置合適的top就能夠了。思路是,根據滾動條獲取top,而後經過$(window).height()獲取屏幕可見區域的高度,估計虛擬鍵盤大概是一半,那麼就除以2,而後減去搜索框的高度,就得到了偏移量。

最後top=top-偏移量,便可

想法是不錯的,實現起來效果如何呢。觀察以前的圖2,咱們能夠猜想ios移動了滾動條,始終爲了保證input處於垂直居中的位置,因此哪怕咱們給他設置了top-偏移量,最後ios仍是又往上滾動了一下。真是又愛又恨啊,你這麼聰明你爲何搞這麼個BUG出來呢。

 

 

3.2 最後的解決方案

仍是回到圖2去進行測試,當ios經過滾動條將input居中後,ios就不會再繼續監控那個input了,此時咱們隨便拖拉頁面,input都不會再回到中間,基於這個想法,那麼咱們經過js延遲一會來從新設置scroll可不能夠呢? 

 

帶着這樣的想法進行了一些測試,最後解決方案以下

1. 監控input的focus和blur事件,進入時設置搜索框爲absolute;

2. 獲取當前scroll的高度,設置給搜索框的top;

3. 設置延遲函數,從新滾動滾動條到當前的top;

4. 離開input時恢復原來的fixed佈局。

 

測試iphone6s ios 9.x 沒問題

android 隨便找了一臺同事的vivo測試 沒問題

暫時就測了2臺手機

 

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head >
    <title></title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="Pragma" content="no-cache">
    <meta http-equiv="Cache-Control" content="no-cache">
    <meta http-equiv="Expires" content="0">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0" />
    <meta name="viewport" content="initial-scale=1, width=device-width, maximum-scale=1, user-scalable=no" />
    <meta name="viewport" content="initial-scale=1.0,user-scalable=no,maximum-scale=1"
        media="(device-height: 568px)" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-touch-fullscreen" content="yes" />
    <meta name="full-screen" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
    <meta name="format-detection" content="telephone=no" />
    <meta name="format-detection" content="address=no" />
   
  
<style>
#float-search{
	height:40px;
	background:red;
	position:fixed;
	top:0;
	width:100%;
	
}
#float-search input{
	height:36px;
	border:1px solid #ccc;
	width:100px

}
</style>   
</head>

<body>
    <div class="warp">
     <p>1</p>
	 <p>2</p>
	 <p>3</p>
	 <p>4</p>
	 <p>5</p>
	 <p>6</p>
	 <p>7</p>
	 <p>8</p>
	 <p>9</p>
	 <p>10</p>
	 <p>1</p>
	 <p>2</p>
	 <p>3</p>
	 <p>4</p>
	 <p>5</p>
	 <p>6</p>
	 <p>7</p>
	 <p>8</p>
	 <p>9</p>
	 <p>10</p>
	 <p>1</p>
	 <p>2</p>
	 <p>3</p>
	 <p>4</p>
	 <p>5</p>
	 <p>6</p>
	 <p>7</p>
	 <p>8</p>
	 <p>9</p>
	 <p>10</p>
	 <p>1</p>
	 <p>2</p>
	 <p>3</p>
	 <p>4</p>
	 <p>5</p>
	 <p>6</p>
	 <p>7</p>
	 <p>8</p>
	 <p>9</p>
	 <p>10</p>
	 <p>1</p>
	 <p>2</p>
	 <p>3</p>
	 <p>4</p>
	 <p>5</p>
	 <p>6</p>
	 <p>7</p>
	 <p>8</p>
	 <p>9</p>
	 <p>10</p>
	 <p>1</p>
	 <p>2</p>
	 <p>3</p>
	 <p>4</p>
	 <p>5</p>
	 <p>6</p>
	 <p>7</p>
	 <p>8</p>
	 <p>9</p>
	 <p>10</p>
	 <p>1</p>
	 <p>2</p>
	 <p>3</p>
	 <p>4</p>
	 <p>5</p>
	 <p>6</p>
	 <p>7</p>
	 <p>8</p>
	 <p>9</p>
	 <p>10</p><p>1</p>
	 <p>2</p>
	 <p>3</p>
	 <p>4</p>
	 <p>5</p>
	 <p>6</p>
	 <p>7</p>
	 <p>8</p>
	 <p>9</p>
	 <p>10</p>
	 <p>1</p>
	 <p>2</p>
	 <p>3</p>
	 <p>4</p>
	 <p>5</p>
	 <p>6</p>
	 <p>7</p>
	 <p>8</p>
	 <p>9</p>
	 <p>10</p>
	 <p>1</p>
	 <p>2</p>
	 <p>3</p>
	 <p>4</p>
	 <p>5</p>
	 <p>6</p>
	 <p>7</p>
	 <p>8</p>
	 <p>9</p>
	 <p>10</p>
	 <p>1</p>
	 <p>2</p>
	 <p>3</p>
	 <p>4</p>
	 <p>5</p>
	 <p>6</p>
	 <p>7</p>
	 <p>8</p>
	 <p>9</p>
	 <p>10</p>
	 <p>1</p>
	 <p>2</p>
	 <p>3</p>
	 <p>4</p>
	 <p>5</p>
	 <p>6</p>
	 <p>7</p>
	 <p>8</p>
	 <p>9</p>
	 <p>10</p>
	 
    </div>
    <div id="float-search">
       <input type="text" id="Text1" name="q" x-webkit-speech="" placeholder="搜索商品" autocomplete="off"
                    value="">
    </div>
    <div id="debugmsg" style="position: fixed; top: 20%; right:100px;width: 100px; height: 100px;
        border: 1px solid red;">
    </div>
</body>
  <script src="http://cdn.bootcss.com/jquery/3.1.0/jquery.js"></script>
<script>

function printStyles(elem) {
    var dtop = $(document).scrollTop();
    var position = $("#"+elem).css("position");
    var top = $("#"+elem).css('top');
    var height = $(window).height();//整個窗口高
     height = height / 4;
    var html = 'top:' + dtop + "<br/>"
        + "bodyTop:" + document.body.scrollTop + "<br/>"
        + "position:" + position + "<br/>" + "top:" + top + "<br/>"
        + "height:" + height;
    return html;
}


    $().ready(function () {
        window.onscroll = function() {

        //測試代碼
        $("#debugmsg").html(printStyles('float-search'));
        //end 測試代碼

        $("#float-search input").focus(function() {
            var top = $(document).scrollTop();
            var height = $(window).height();//整個窗口高
            height = height / 4;

            $("#float-search").css("position", "absolute");
            $("#float-search").css("top",top);
            setTimeout(function() {
                $("html,body").animate({scrollTop:top},5);//1000是ms,也能夠用slow代替 
            },5);
            //測試代碼
        $("#debugmsg").html(printStyles('float-search'));
        //end 測試代碼

        }).blur(function() {
            $("#float-search").css("position", "fixed");
            $("#float-search").css("top","0");


            //測試代碼
         $("#debugmsg").html(printStyles('float-search'));
        //end 測試代碼
        });

		}
    });


 


</script>
</html>
相關文章
相關標籤/搜索