觸屏版開發總結

概述

前段時間剛剛完成公司觸屏版項目,我以爲頗有必要寫一篇文章總結下本身的心得和踩過的坑。每次回頭看看本身寫的代碼,都有不同的體會,不過大體感受都是驚人的類似:這TM寫的是啥?這TM寫的又是啥?css

架構

Java+Node。嘗試了先後端分離,Java端負責業務邏輯處理,提供接口。Node端負責頁面渲染、SEO等balabala一堆非業務邏輯,二者經過HTTP接口交互。先後端分離確實帶來了好處:html

  1. 分工明確,不會出現佔着茅坑不拉粑粑的狀況,一人一個坑蹲着
  2. 職能清晰,設計寫SASS,前端寫JavaScript,後端寫Java
  3. 提升了代碼的複用性,Java端的接口可供多個應用調用

先後端分離只有好處? No! 多了Node,實際上多了層請求,這個過程是須要花費時間的,不過這點性能的損耗同提升維護性來比是微不足道的,咋不糾結這個!真正來講,先後端的過分分離讓每一個人只關注本身的任務,等到聯調的時候會發現出現不少問題,舉個幾個簡單的例子:前端

撕逼1

通常都是設計跟據視覺稿先編碼,作好HTML頁面,而後丟給咱們前端開發。我套頁面的時候,發現有個幻燈片效果,而後去找了個插件xxx.js,大部分的幻燈片插件對HTML結構都是有要求的(你懂的),因此我只好找到設計,讓他從新寫下這部分結構,設計欣然接收,改了!作着作着又發現某個div的須要fixed佈局,又得找設計改SASS,某個div須要添加 overflow:hidden,仍是得找設計改,如此反覆,設計內心確定會默唸:我去年買了個表!說到這裏我不得不說一點了,做爲一個合格的設計,在編寫HTML時,要根據交互效果編寫CSS代碼,站在套頁面人的角度去編碼。也須要將CSS模塊化,便於維護啊!固然了,做爲一個合格的JSer,也要善於同設計交流,提早溝通,避免出現上述的狀況。不溝通的結果就是這樣的:jquery

<div style="overflow: hidden;margin-top: 200px;">
    <div style="width: 500px;margin-left: 20px;"></div>
</div>

$('#btn').click(function(){
    $('.someDiv').css({overfolw : 'hidden'}).show();
});

來來來,放學別走!git

撕逼2

交互說,點擊這裏,我須要duang的效果,點擊那裏我須要duang duang的效果,點那那裏,我須要duang duang duang的效果。我一看,但願用盡可能少的代碼實現,同交互交流但願統一UI,保留一種效果就能夠了,交互堅持!交互堅持,交涉無果,不得很少寫額外的代碼,然並卵!下次需求,又換交互效果!github

撕逼3

不一樣的列表頁,有着相同的HTML結構,本次相同代碼不寫兩遍的原則,抽出告終構:數據庫

<div>
     {{comName}}
    //...
</div>

可是後端返回的數據結構一處叫comName,一處叫companyName。問後端,他說數據庫就是這樣設計的。express

小結

我的以爲整個開發流程就是一體的,沒有絕對的先後端分離。產品、交互、設計、JSer、後端、庫表設計都會對咱們的代碼產生影響。及時溝通是一方面。處了本身的本職外,也須要了解他人的工做,當你對整個流程都特別熟悉,那就是所謂的架構師了。還在前端摸爬滾打的我,還差得遠啊。後端

Zepto

Zepto是一個輕量級的針對現代高級瀏覽器的JavaScript庫, 它與jquery有着相似的api。選擇Zepto是由於它輕量高效,而且封裝好了移動端的touch事件。細數下開發過程當中遇到的坑。api

下載

直接從官網上下載了Zepto,立刻編碼

$('#btn').on('tap',function(){
    //todo
});

發現壓根不起做用,再到官網上看下,我就呵呵了
圖片描述
看黃色部分,默認只添加了Effects、iOS3和Detect這三個模塊,最最重要的Touch模塊竟然沒有!因此你們要下載Zepto還得本身定製模塊
Zepto Builder
附上模塊說明:
圖片描述

延時

總所周知,默認click事件,會有300ms的延時問題,Zepto的tap事件很好的解決了這個問題。可是也挖了一個大坑。

點透

Zepto的點透應該也是你們比較熟悉的了。當兩個層疊加的時候,上層綁定的tap事件觸發後會穿透到底層,剛好底層有個a標籤,頁面就跳轉了。爲了解決這個問題,我不得不把tap事件換成click事件,因爲click事件有延時,還得引入了第三方的類庫FastClick

計算寬高

一個很簡單的Tip提示,例如‘操做成功’、‘登陸失敗’等等簡單的提示,Tip在show以前,我會計算讓Tip居中顯示:

var left = ($(window).width() - $pop.width()) / 2 + $(window).scrollLeft();

然而$pop.width()始終爲0,對於不可見元素,獲取的寬高度始終爲0,可是jQuery就能正常獲取到,我又不得不採起以下的處理方式:

var cssShow = {visibility: 'hidden', display: 'block'};
var cssHide = {visibility: 'visible', display: 'none'};

$pop.css(cssShow);
var left = ($(window).width() - $pop.width()) / 2 + $(window).scrollLeft();
$pop.css(cssHide);

 $pop.css({
     left: left > 0 ? left : 0
 });

小結

Zepto相對於JQuery來講確實比較輕量,可是成熟度還差得遠,當出現點透和計算寬高失效的時候,我對Zepto有點灰心,但願Zepto後續可以及時升級解決這些問題,否則就使用jQuery了,特別是jQuery升級到版本2,也是至關不錯的選擇。

瀏覽器的坑

禁用滾動

當頁面彈出一個選擇框。滑動屏幕,背後的頁面跟着滾動,特別是在safari下,那效果太噁心,因此我選擇禁用body的滾動。最暴力的解決方式是:

$(document).on('touchmove',function(e){
    e.preventDefault();
});

這樣會同時禁用掉彈出層的滾動效果,明顯不可取,因此我才用下面的方式:

.alpha {
    height: 100%;
    overflow: hidden;
    position: relative;
}

.alpha body {
    height: 100%;
    overflow: hidden;
}

當遮蓋彈出的時候或者隱藏的時候讓html切換class alpha
$('html').toggleClass('alpha');

回到頂部

對於PC端,直接這樣寫,就會有一個向上平滑滾動的效果,然而對於移動端來講,並無什麼卵用:

$('body,html').animate({scrollTop: 0});

仍是使用了第三方的插件模式出這個效果的scrollToTop

SEO

URL Rewiter

先後端分離後,Node端要乾的事情太多了,URL重寫這個模塊是我一個前輩寫的,配置放在JSON文件裏,就像這樣:

{
    "product.detail": {
        "in": {
            "from": "^/chanpin/(.+)\\.html$",
            "to": "/product/$1",
            "last": true
        },
        "out": {
            "from": "^/product/(.+)$",
            "to": "/chanpin/$1.html",
            "last": true
        }
    },    
    "special": {
        "in": {
            "from": "^/special/(.+)\\.html$",
            "to": "/special/$1",
            "last": true
        },
        "out": {
            "from": "^/special/(.+)$",
            "to": "/special/$1.html",
            "last": true
        }
    }
}

推廣代碼

就是這貨:

<title>淘寶網 - 淘!我喜歡</title>    
<meta name="description" content="" />
<meta name="keyword" content="" />

我一樣採用JSON文件管理全部頁面的推廣代碼,就像這樣:

{  
  "catalog": {
    "title": "產品目錄–$1",
    "keywords": "產品目錄,$1",
    "description": "$1,產品目錄。"
  }, 
  "search.product": {
    "title": "產品搜索–$1",
    "keywords": "產品搜索,$1",
    "description": "$1,產品搜索。"
  }  
}

路由管理

本身編寫了個模塊,能夠指定某個文件下的js文件做爲路由,路由代碼寫起來就像這樣的:

module.exports = {
    mapping: '/vo',
    get: {       
        /**
         * 登陸
         */
        '/login': function (req, res) {
            res.render('vo/login');
        },
        /**
         * 註冊
         */
        '/register': function (req, res) {
            res.render('vo/register');
        }            
    },
    post: {
        /**
         * 登陸
         */
        '/login': function (req, res) {
            //todo
        },
        /**
         * 註冊
         */
        '/register': function (req, res) {
           //todo
        }        
    }
};

詳細使用請看這裏Express-Mapping

吐槽下Handlebars

模板引擎使用的Handlebars。Handlebars的if判斷不支持type==='2'這種邏輯判斷的,然而咱們的數據庫裏有不少字段是使用數字1,2,3,4來標識不一樣狀態的,碰到這種狀況就得在Node端預先處理,這個是很坑爹的!碰到列表展現的嵌套循環更是坑爹了。有時候還得寫這種代碼:

{{#if a}}
    {{#if b}}
        {{#if c}}
            //todo
        {{/if}}
    {{/if}}
{{/if}}

真實的業務場景更是複雜,額外的處理代碼老是會帶來維護的負擔。最近在看nunjucks模板,貌似很吊的樣子!

總結

學習就是不斷踩坑的過程啊!

相關文章
相關標籤/搜索