內部Hybrid App經驗解讀

jopen 8年前發布 | 14K 次閱讀 Zepto.js HTML Android開發 移動開發

鄭昀編纂 關鍵詞:Hybrid,Zepto,Fastclick,Backbone,sui,SPA,pushState,跨域,CORS

  1. click 事件還是 tap 事件?
  2. Zepto 的 show/hide 有時不靠譜
  3. Android 下的跨域問題
  4. pushState 調用失敗也屬于跨域問題
  5. </ol>

    內部做 Hybrid App 開發歷程也不短了,楊海波、潘軍和劉勤紅與前端組、App 組一起總結了不少寶貴的經驗教訓,逐步形成我們自己的標準打法。下面選了幾個經驗點(坑)做進一步解讀。

    </div>

    0x00,click 事件還是 tap 事件?

    300  毫秒點擊延遲的來龍去脈 一文所言『盡管蘋果公司創造的雙擊縮放行為,是一種在移動設備上訪問桌面端站點的不錯的解決方案,但隨之引入的 300 毫秒點擊延遲也成為了移動端網站讓用戶感覺卡頓的罪魁禍首之一』,此文把原因和對策講得清楚透徹,此處鄭昀不再贅述,感興趣的同學自習一下。

    那么,我們看到,時至今日,有三種應對措施:

    1. 對于無需縮放的頁面,禁用雙擊縮放功能,
    2. 引入 Zepto 框架的 tap 事件
      • Zepto 趁著 JQuery 在移動互聯網市場歷史包袱重的機會,搞了一套輕量級類 JQuery 框架的代碼,核心代碼千行,從而迅速成為移動端 DOM 操作庫的首選。
      • Zepto 提供了一個 touch 庫,在載入 Zepto 后為 document 綁定 touchstart、touchmove、touchend 事件,根據手指 x、y 值的位置,判斷方向從而觸發 tap、doubleTap、swipeLeft 等事件。
      • 原本沒有 tap 事件,Zepto tap 是用 touchstart 和 touchend 模擬出來的。
      • </ul>

      • 引入 Fastclick 的 click 事件
        • FastClick  是  FT Labs  專門為解決移動端瀏覽器 300 毫秒點擊延遲問題所開發的一個輕量級的庫。簡而言之,FastClick 在檢測到  touchend  事件的時候,會通過  DOM 自定義事件 立即觸發一個模擬 click  事件,并把瀏覽器在 300 毫秒之后真正觸發的  click  事件阻止掉。
        • </ul> </ol>

          但我們在實踐過程中,也領教了著名的  Zepto tap 『點透』坑

          對此,yexiaochai 分析道:

          1,一旦引入 touch 庫便會在全局綁定事件,每次點擊皆會觸發無意義的 tap 事件 ;

          2,zepto 為了實現 doubleTap 等功能,2B 地在 touchend 上設置了一個 setTimeout,然后整個世界都充滿了翔了。

          由于 setTimeout 的拋出主干流程,導致其 event 參數失效,這個時候就算在 tap 事件函數中執行 e.preventDefault() 或者什么都是無效的,這是導致 zepto tap“點透”的罪魁禍首。

          點透的效果可以看  http://www.cnblogs.com/lilyimage/p/3740668.html 所述。總之,有人 建議 , 如果你還打算繼續用 Zepto,那么它的 tap 事件已經沒用了,那你可以自己 build 一個無 touch 模塊的 Zepto ,以便減小文件大小并提高運行效率。

          </div>

          Fastclick 是怎么做的呢?

          Fastclick 將事件綁定到你傳入的元素 上,在 touchstart 和 touchend 后(會手動獲取當前點擊 el),如果是類 click 事件便手動觸發 dom 元素的 click 事件。所以 click 事件在 touchend 便被觸發,于是整個響應速度就起來了。這里雖然使用了 touch 事件,但 touch 事件是綁定到了具體 dom 而不是 document 上 ,所以 e.preventDefault 是有效的,我們可以阻止冒泡,也可以阻止瀏覽器默認事件。

           

          最終我們采用 Fastclick 的 click 事件來規避點擊延遲響應。

           

          0x01,Zepto 的 show/hide 有時不靠譜

          在 Hybrid App 開發初期,我們引入了 Zepto 的 fx_methods 模塊,來控制元素的顯示與隱藏:

          </tr> </tbody> </table>

          但總是出現一些莫名奇妙的問題,如元素不能正常顯示,元素的定位發生變化等,非常不好定位,最終前端同學發現是 Zepto 的 show/hide 造成的。

          對此,我們可以找到 2012 年的一個 issue 佐證:

          fx_methods Animated show ,  hide ,  toggle , and  fade*() methods.

          fx_methods show() and hide() add unnecessary CSS properties on non-animated DOM nodes

          </td> </tr>

          When you add fx_methods to your Zepto, the show() and hide() methods are overriden with methods that also call animate. 

          Even in the case of undefined speed (normal show), animate still adds many CSS properties to the shown/hidden nodes.

          These unexpected CSS rules can interfere with the page CSS (in my case, it has changed the positioning of my child fixed DIVs).

          </td> </tr> </tbody> </table>

          即,她認為,即使是簡單的顯示,fx_methods.js 的 show/hide 也會加入一些額外的 CSS,以至于影響整個頁面樣式,而且還會亂彈琴地改變透明度,重置為 1.0。samwu 在 2013 年也講過類似問題。

          所以,我們有兩種選擇:

          1. 繼續引入 Zepto 的 fx_methods,但按 madrobby 所說,沒有定義 speed 時,僅調用原生的 show;
            • 從 Zepto 官方的  內部Hybrid App經驗解讀  改為  內部Hybrid App經驗解讀
            • </ul>

            • 如 0x00 和本小節所描述的問題, 不要引入 Zepto 的 touch 和 fx_methods 模塊
              • 只引入 zepto+event+ajax+form+ie 基本模塊
              • </ul> </ol>

                0x02,Android 下的跨域問題

                在 Hyrbid App 里,鄭昀要求采用 Template+Data=HTML 模式在手機客戶端本地渲染出所需的頁面。

                Template(HTML5 模板文件+JS+CSS+Images)既可以提前打包到 App 安裝包里,也可以從 CDN(如無,則溯源到靜態文件服務器)拉到客戶端里并存儲在本地。

                Data 則是通過模板文件里的 JavaScript 腳本,從遠端拉取 JSON 格式的數據包。

                那么,這里存在一個跨域問題:

        • sesese色