iScroll框架解析——Android 設備頁面內 div(容器,非頁面)overflow:scroll; 失效解決(轉)

移動平臺的活,兼容問題超多,今兒又遇到一個。客戶要求在彈出層容器內顯示內容,但內容條數過多,容器顯示滾動條。按說是So easy,容器設死寬、高,CSS加屬性javascript

overflow:scroll;
-webkit-overflow-scrolling:touch;

完事!可拿設備去測的時候有趣了,Pc all browser正常,ios正常 ,android失效。泥馬在android下效果與 overflow:hidden;同樣,溢出部分隱藏了!php

水平有限,用盡吃奶力各類解決未果,網上一頓亂搜,Google搜索有人說是android系統BUG,最後查到比較靠譜的解決是國外某高手開發了個JS庫,名曰iScroll 4 。 親測,好用,惟獨效率不敢恭維(拿別人的東西用,少TM廢話)。下載地址:http://cubiq.org/iscroll-4css

使用方法:
1. 引入 iscroll.js
html

<script type="application/javascript" src="http://istyles.blog.163.com/blog/js/iscroll.js"></script>
<script type="text/javascript">
var myScroll;
function loaded() {
    myScroll = new iScroll('wrapper');
}
document.addEventListener('DOMContentLoaded', loaded, false);
window.onload = function() { 
    setTimeout(function(){ new iScroll(document.getElementById('scroller')) }, 100) 
};
</script>

註明:iScroll必須在調用以前實例化java

 2. 添加必要的樣式jquery

<style type="text/css">
#wrapper {
position:relative;
z-index:1;
height:200px;        /* Desired element height */
height:200px; /* Desired element height */
overflow:/* hidden|auto|scroll */;
}
</style>

3. 容器加 id="wrapper" , 內容加 id="scroller" android

<div id="wrapper">
   <ul id="scroller">
         <li></li>
         ...
         <li></li>
   </ul>
</div>

iscroll 須要兩個參數,第一個很簡單就是外容器的id,第二個參數是一個參數對象。經過這個對象能夠傳入iscroll的各項參數來配置iscroll。
參數基本分爲四個部分
ios

    • 基礎
    • 滾動條
    • 放大縮小
    • 事件回調

-------------------------------------------俺混亂的分界線-----------------------------web

iScroll框架解析(翻譯)ajax

iScroll 4 這個版本徹底重寫了iScroll這個框架的原始代碼。這個項目的產生徹底是由於移動版webkit瀏覽器(諸如iPhone,iPad,Android這些系統上普遍使用)提供了一種本地化的方式來對一個限定了高度和寬度的元素的內容進行滑動。很不幸的是,這種狀況下全部的web應用的頁面就不可以包含具備position:absolute的頭、頁尾或者是一個內容可滾動的中間區域。

然而,Android系統最新修訂版已經能夠支持這種功能了(儘管支持的力度還不是特別好),Apple公司彷佛不太情願將one-finger滑動事件運用到div元素上。

除了之前版本的iScroll的特性之外,iScroll 4還包括以下的特性:

  1. 縮放(Pinch/Zoom)
  2. 拉動刷新(Pull up/down to refresh)
  3. 速度和性能提高
  4. 精確捕捉元素
  5. 自定義滾動條

      友情提示:iScroll 4並非iScroll 3的簡易替代版本,API文檔已經不同了。同時考慮到此版本正處於測試期,一些API 可能會有細微的變化。

使用指南

插件的調用須要在頁面徹底加載以後。你能夠經過如下3種方法來實現。

iScroll對所要進行滾動的元素進行初始化,而且不限定一個頁面中使用iScroll的元素的個數(這裏不考慮您的硬件配置)。滾動元素中內容的類型和長度在必定程度上將會影響iScroll腳本庫裏能夠同時使用的元素的個數。使用iScroll這個腳本庫時,DOM樹的結構要足夠簡單,移除沒必要要的標籤,儘可能避免過多的標籤嵌套使用。最優的使用iScroll的結構以下所示:

<div id="wrapper">
        <ul>
          <li></li>
          .....
        </ul>
</div>

在這個小例子中,ul標籤將會被滾動。iScroll必定要與滾動內容外面的wrapper進行聯繫纔會產生效果。

【注意事項】:只有wrapper裏的第一個子元素才能夠滾動,若是你想要更多的元素能夠滾動,那麼你能夠試試下面的這種寫法:

<div id="wrapper">
        <div id="scroller">
               <ul>
                    <li></li>
                     ...
                </ul>
                <ul>
                     <li></li>
                       ...
                </ul>
       </div>
</div>

在這個例子中,scroller這個元素能夠滾動,即使它包含兩個ul元素

 

從上圖中能夠看出,wrapper之於scroller,就像viewport之於document.

iScroll必須在調用以前實例化,你能夠在下面幾種狀況下對iScroll進行實例化(插件的調用須要在頁面徹底加載以後):

  1. 設置onDOMContentLoaded事件
  2. 設置onLoad事件
  3. 把調用代碼放到頁面的最後,之內聯inline方式

下面咱們逐個來說講這三種用法的優缺點

1. ONDOMContentLoaded

 適用:滾動區域的長寬是固定的,滾動內容只包含文字、圖片,而且全部的圖片都有固定的尺寸

 使用方法:(在head標籤中添加以下代碼)

<script src="iscroll.js"></script>
<script>
       var myscroll;
       function loaded(){
            myscroll=new iScroll("wrapper");
         }
        window.addEventListener("DOMContentLoaded",loaded,false);
</script>

         注意:myscroll這個變量是全局的,能夠在任什麼時候候調用插件,在任何地方調用它的函數

2. 設置onLoad事件

 由於DOMContentLoaded事件是載入DOM結構後就會被調用,因此在圖片等元素未載入前可能沒法肯定滾動區域的長寬,此時可使用onLoad事件來實現。

有些時候在DOMContentLoaded的狀態下就初始化iScroll實際上是有點草率的,所以此時頁面的資源可能尚未所有加載完畢。若是你遇到了一些很怪異的行爲能夠試試下面的寫法:       

<script src="iscroll.js"><script>
<script>
    var myscroll;
    function loaded(){
         setTimeout(function(){
                myscroll=new iScroll("wrapper");
          },100 );
    }
   window.addEventListener("load",loaded,false);
</script>

 如上代碼,在頁面加載完100毫秒後調用插件。若是這個時間後還有元素未徹底載入致使沒法計算滾動區域長寬,可能會致使錯誤。但這是目前最好的方法了。

這種狀況下iScroll會在頁面資源(包括圖片)加載完畢100ms以後獲得初始化,這應該是一種比較安全的調用iScroll的方式。

3. inline初始化

 這種狀況會在頁面加載到js的時候就進行調用,此方法不推薦使用,可是不少javascript的大牛都在用這種方式,我又有什麼理由不同意呢?

<script src="iscroll.js"></script>
<div id="wrapper">
      <ul>
         <li></li>
         ...
       </ul>
 </div>
<script type="text/javascript">
   var myscroll=new iScroll("wrapper");
 </script>       

 不過建議你使用一些框架的ready方法來安全調用iScroll(好比jquery裏的ready())。

-------------------------------------------俺混亂的分界線-----------------------------

iScroll參數設置

        iScroll裏的第二個參數容許你自定義一些內容,好比下面的這段代碼:

<script>
     var myscroll=new iScroll("wrapper",{hScrollbar:false, vScrollbar:false});
 </script>      

       第二個參數一般都是一個對象,像上面的這個例子裏就設定了不顯示滾動條。經常使用的參數以下:

  • hScroll            false 禁止橫向滾動 true橫向滾動 默認爲true
  • vScroll            false 精緻垂直滾動 true垂直滾動 默認爲true
  • hScrollbar       false隱藏水平方向上的滾動條
  • vScrollbar       false 隱藏垂直方向上的滾動條
  • fixedScrollbar  在iOS系統上,當元素拖動超出了scroller的邊界時,滾動條會收縮,設置爲true能夠禁止滾動條超出scroller的可見區域。默認在Android上爲true,                               iOS上爲false
  • fadeScrollbar  false 指定在無漸隱效果時隱藏滾動條
  • hideScrollbar  在沒有用戶交互時隱藏滾動條 默認爲true
  • bounce            啓用或禁用邊界的反彈,默認爲true
  • momentum     啓用或禁用慣性,默認爲true,此參數在你想要保存資源的時候很是有用
  • lockDirection    false取消拖動方向的鎖定, true拖動只能在一個方向上(up/down 或者left/right)爲了保持資源的完整性,建議去除滾動條

-------------------------------------------俺混亂的分界線-----------------------------

各類效果的實現

一、拉動刷新(pull to refresh)

        自從Twitter和一些Apple的本地化應用出現了這個效果以後,這個效果就變得很是流行。你能夠看看這兒先一睹爲快。我最近把"pull to refresh"這個部分單分出來做爲iScroll的一個額外插件。你能夠點擊這兒看看pull to refresh是如何工做  滴。你只須要作的就是自定義pullDownAction()這個方法。你可能須要一個ajax來加載新的內容,不過一旦DOM樹發生了變化要記得調用refresh這個方法來。須要記住的是在例子中咱們加了1秒的延遲來模擬網絡的延遲效果。固然,若是你不想使用這個延遲,那就把setTimeout方法去掉就好了。

2. 縮放(pinch / zoom)

        咱們不得不面對一個事實,那就是光有滾動其實沒什麼新意的。這就是爲何在iScroll 4這個版本里咱們容許你能夠放大和縮小。想要這個功能,只須要設置放大的參數zoom 爲true便可實現利用手勢來放大和縮小。你能夠看看這兒。雙擊放大和縮小的功能在iScroll 4裏也是獲得支持的。要使用縮放功能,你至少須要以下配置:

                var myScroll =new iScroll("wrapper",{zoom:true});

       若是你想對縮放功能進行深度的自定義的話可使用下面的一些選項:

               zoomMax   指定容許放大的最大倍數,默認爲4

      【注意事項】:若是想要圖片縮放的效果很好的話要把他們放到硬件的合成層中。通俗點說,就是在全部須要縮放的img元素上使用-webkit-transform:translate3d(0,0,0)來實現,並且尤其重要的是,硬件的加速會佔用大量資源,要謹慎使用,不然你的應用可能就此崩潰。

3. 捕捉元素(snap and snap to element)

SNAP功能是判斷元素是否滑動到指定位置。經過這個效果能夠製做花哨的跑馬燈效果。插件會自動分析滾動區域內相同標籤或相同大小的元素作爲捕捉對象,也能夠經過參數指定捕捉的對象

捕捉的功能會促使scroller去從新定義位置,這樣能夠製做更加花哨的傳送帶效果。點擊這裏有個小例子。默認狀況下,iScroll將scroller分紅四分體,或者是相同大小的wrapper。iScroll 4加入了這個屬性容許捕捉scroller裏的 任何元素,不考慮外部wrapper的大小。若是你想要實現這樣的傳送帶效果,我建議你使用「quadrant」分割。最佳的設置以下:

 var myscroll=new iScroll("wrapper",{
                       snap:true,
                       momentum:false,
                       hScrollbar:false,
                       vScrollbar: false
});              

能夠經過設置snap參數爲指定標籤來設定捕捉對象。好比捕捉li標籤

         var myscroll=new iScroll("wrapper",{
                      snap:"li",
                      momentum:false,
                      hScrollbar:false,
                      vScrollbar:false
        });      

           在這個例子中scroller能夠捕捉到滾動區域中最左上角的li元素

在snap屬性的值爲指定標籤的時候,插件會經過 scroller.querySelectorAll(snap_string)的方法來獲取對象。因此要注意不要寫成"$scroller li",這是錯誤的。只要寫'li'。

3. 自定義滾動條(custom scrollbars)

          在iScroll 4這個版本中,能夠利用一系列的css來自定義滾動條的呈現。能夠給滾動條添加一個class參數,以下:

                  var myscroll=new iScroll("wrapper",{scrollbarClass: "myScrollbar"});

          你能夠點擊這裏看一個小例子,在這個小例子裏,myScrollbarH這個類被添加到了水平滾動條上,myScrollbarV這個類則被添加給了垂直方向上的滾動條上了。須要提醒的是,滾動條是由兩個元素組合而成的:容器和顯示器。容器同wrapper的高度相同,而顯示器則表明的是滾動條自己。

           滾動條的HTML結構以下:

<div class="myScrollbarV">
           <div></div>
 </div>

.myscrollbarV{
        position:absolute;z-index:100;width:8px;bottom:7px;top:2px;right:1px;
}

 .myScrollbarV > div {
                           position:absolute;
                           z-index:100;
                           width:100%;
                             /* The following is probably what you want to customize */
                           background:-webkit-gradient(linear, 0 0, 100% 0, from(#f00), to(#900));
                           border:1px solid #800;
                          -webkit-background-clip:padding-box;
                          -webkit-box-sizing:border-box;
                          -webkit-border-radius:4px;
                          -webkit-box-shadow:inset 1px 1px 0 rgba(255,255,255,0.5);
                 }                 

內部方法:

iScroll還提供了一些公共方法。好比說refresh。在改變滾動區域裏內容的時候都必須調用refresh方法。由於iScroll是經過實例化一個全局變量來實現的,因此使用者可在任何狀況下調用這些方法。

調用方法: myScroll.name_of_the_function(參數)

  1. refresh                     在DOM樹發生變化時,應該調用此方法
  2. scrollTo()                 滾動到某個位置         eg: myscroll.scrollTo(0,10,200,true);
  3. scrollToElement()      滾動到某個元素         eg: myscroll.scrollToElement("li:nth-child(10)",100);
  4. detroy()                   徹底消除myscroll及其佔用的內存空間          eg: myscroll.destroy()

 一、refresh方法 

iScroll須要知道滾動區域的大小和滾動條才能正常工做。在實例化的時候iScroll會自動計算一次。但若是滾動區域裏的內容發生變化後,須要告訴iScroll內容發生了變化。

 每次改變元素的高度/寬度或以任何方式修改(如: appendChild或innerHTML的)HTML結構時,瀏覽器會從新渲染頁面。javascript就須要從新分析新的DOM結構和新的屬性,有時候,這個不是即時的。 

爲了確保javascript分析新的頁面,能夠實例化一個新的iScroll。

ajax('page.php', onCompletion);
function onCompletion () {
    setTimeout(function () {
        myScroll.refresh();
    }, 0);
};

二、JAVASCRIPT SCROLLING

iScroll還提供了scrollTo, scrollToElement和scrollToPage三個方法讓你可以經過javascript來控制滾動效果。

scrollTo(x, y, time, relative):在指定的time時間內讓內容滾動條x/y的位置。如myScroll.scrollTo(0, -100, 200) 在200毫秒內Y軸向下滾動100像素。 myScroll.scrollTo(0, 10, 200, true)能夠實現相對當前位置在200毫秒內Y軸向上滾動10像素的效果。

scrollToElement(element, time):在指定的時間內滾動到指定的元素。如myScroll.scrollToElement('li:nth-child(10)', 100) 在100毫秒內滾動到第10個li元素的位置。第1個參數能夠用CSS3中的選擇器來篩選元素。

snapToPage(pageX, pageY, time):在200毫秒內從第1頁滾動到第2頁(0表明第1頁,1表明第2頁)。這個使用SNAP功能的時候能夠調用這個函數。

三、註銷iScroll

經過調用destroy()函數下注銷iScroll來釋放內存。

myScroll.destroy(); myScroll = null;

四、LITE版iScroll

若是你只但願在移動設備中使用iScroll,請使用iscroll-lite.js

LITE版是一個精簡版,它支持移動設備(沒有桌面兼容性)滾動。所佔的資源更少。

iScroll的發展方向

  • 表單域的支持
  • 縮放的優化
  • 更好的桌面瀏覽器的兼容性
  • onScrol事件的優化
  • 加個哈希值的變化
  • DOM改變後自動刷新

轉載:

相關文章
相關標籤/搜索