iScroll這個移動端的滾動神器你們都很是熟悉了,直到如今還是實現移動端Web滾動的首選方案之一。。。html
當我接觸移動端Web時iScroll已經有兩個版本了,iScroll 4和iScroll 5,當時看到不少文章都是關於iScroll 4的,看來這個版本已經獲得的很是普遍的應用,而iScroll 5的文章相對很是之少,好吧,項目進度耽誤不起,咱們就選當前最流行的這個版本吧(iScroll 4.2.5),想必也是最成熟穩定的。。。 前端
iScroll 4的官網地址:node
這個插件的功能全面,使用也簡單,應對錶面統一的移動瀏覽器平臺(咱們只關注webkit核心~~ ^_^)感受遊刃有餘,對於性能問題,使用初期也察覺到有什麼異樣(看來常年停留在安卓2.3系統的我根本不知道順滑與卡頓的區別~~),內心還在莫莫崇拜國外牛人多啊~~ 瀏覽器
直到項目進入後期完善階段了,就會處處點一點,按一按,檢查下前端工做是否有重大Bug,忽然間意識到有些頁面表現怪怪的,一些Button點擊時少了一點什麼效果,原來是在點擊按鈕時沒有表現出交互效果!app
查看下CSS代碼,明明我在.btn類上加了:active效果了的,並且在應用iScroll滾動的區域外的button是有效果的(我是用桌面Chrome模擬器的),那問題必定是出在iScroll身上了。。。其實這個問題也能夠理解,在不少相似的模擬插件中若是不由用掉系統默認事件或者效果的話,達不到完美的用戶體驗效果,印象中桌面端的那個mousewheel插件就是如此。。。
性能
那我就看API,找度娘~~原來很早有不少人已經遇到這樣的問題了,好比園裏的Tony同窗(http://www.cnblogs.com/lostyu/p/3907256.html)哈哈,有人進過坑,就意識着有人成功跳出過坑~~直接把解決方法拿來用是咱們前端城獅的必要技術之一,因而我也複製之~~ ^o^ 學習
iScroll做者當時一刀砍啊,全部默認行爲所有幹掉了:spa
onBeforeScrollStart: function (e) { e.preventDefault(); }
你們的解決方法:插件
onBeforeScrollStart: function (e) { var nodeType = e.explicitOriginalTarget ? e.explicitOriginalTarget.nodeName.toLowerCase() : ( e.target ? e.target.nodeName.toLowerCase() : '' ); if( nodeType != 'select'&& nodeType != 'option' && nodeType != 'input' && nodeType != 'textarea' ) e.preventDefault(); }
這個方法很直接,頗有效,將最爲經常使用的系統組件select、option、input、textarea等等在iScroll中點擊無效的問題解決了;
可是若是咱們想讓Button也能點擊且有點擊效果的話,就要手動再加 && nodeType != 'button' 到代碼裏去,也行吧~~~
可是若是咱們想讓<a class="btn">也有點擊效果~~~,就要進一步改造啦。
對了,不是有iScroll 5了嗎,它會不會有這個問題呢?看一下API, 新版本已經有相關的控制參數了: options.preventDefaultException
iScroll 5官網API:
http://iscrolljs.com/#advanced-options
要不直接換iScroll 5? 瞭解過iScroll 5的同窗要先呵呵一下,由於iScroll 5已經不是4+1=5那麼簡單了。
iScroll 5已經徹底重寫了,很多接口都作了改變,就連實例化的方式都不一樣了,這麼說吧,iScroll 4與5徹底是兩個東西,你甚至能夠在同一個頁面中同時使用它們倆:
iScroll 4使用:
new iScroll('scroll-wrapper-1');
iScroll 5使用:
new IScroll('#scroll-wrapper-2');
iScroll 5提供的那個配置接口參數能夠解決咱們以前遇到的問題:
new IScroll('#pro-detail',{ preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT)$/, className: /(^|\s)btn(\s|$)/ } });
看到 className: /(^|\s)btn(\s|$)/ 了嗎? 這樣就可使.btn的元素不被preventDefault()方法干擾。
因爲換用iScroll5的勞動成本略大於對iScroll4的改進(實際上是不改內心有點難受,我不是處女座),咱們開始改動工~
咱們學習iScroll 5的樣子,爲iScroll 4也添加配置參數(大概在107行):
// Default options
that.options = { hScroll: true, vScroll: true, x: 0, y: 0, bounce: true, bounceLock: false, momentum: true, lockDirection: true, useTransform: true, useTransition: false, topOffset: 0, checkDOMChanges: false, // Experimental
handleClick: true, preventDefaultException: "", // ex: "A|BUTTON|.btn-class|#btn-id"
。。。
而後將那個onBeforeScrollStart方法在同窗們改造過的基礎之上變得更豐滿,以下:
onBeforeScrollStart: function (e) { var nodeType = e.explicitOriginalTarget ? e.explicitOriginalTarget.nodeName.toLowerCase() : (e.target ? e.target.nodeName.toLowerCase() : ''); var excpt = that.options.preventDefaultException.replace(/\s/g, ""), excptArr = null, targetNode = null; if (nodeType != 'select' && nodeType != 'option' && nodeType != 'input' && nodeType != 'textarea' && !isExcptNode(e.target, excpt)) { e.preventDefault(); } function isExcptNode(_node, _excptStr) { var result = false; if (_excptStr) { targetNode = _node; excpt += _excptStr.match("|") ? "" : "|"; excptArr = excpt.split("|"); for (i in excptArr) { if (targetNode.nodeName.toString().toLowerCase() == excptArr[i].toLowerCase()) { result = true; break; } else if (excptArr[i].match("#")) { if (targetNode.id.match(excptArr[i].replace("#", ""))) { result = true; break; } } else if (excptArr[i].match(".")) { if (targetNode.className.match(excptArr[i].replace(".", ""))) { result = true; break; } } } } return result; } }
因而,咱們也能夠在使用iScroll4時這樣啦:
new iScroll('wrapper', { useTransition: false, vScrollbar: false, preventDefaultException:".btn|.btn-b|#btn-submit" });