requirejs clear cache

當每次需要把code佈署至production,又希望user不要因為瀏覽器的機制讀取到舊的code,那麼最簡單方式,就是改變靜態檔案的連結,只要連結不同,瀏覽器就會視為不同檔案。

第一種方法就是讓每次佈署到production時,先替換靜態檔案的連結,如果使用ruby on rails,它能直接將靜態檔案去做merge,和將連結轉成亂碼,可以參考icook頁面上的source code。

另一種方式就是直接將js、css這些靜態檔案,直接經由頁面上吐出來,這種方式request的數量會大幅減低,讀取速度也會更快,例如yahoogoogle

那如果是使用requirejs,又不想使用以上方法或者自行在每個script加參數,那麼可以使用以下方式:

var require = {
    urlArgs: "bust=v1"
};

官方有建議使用var的方式宣告require,而不要使用window.require方式,因為在老舊的IE瀏覽器,會有可能會出問題。

(相信之前有測過IE6和常常使用共用同一個namespace,並且有寫得很嚴謹的人,應該都有碰過這奇怪bug。)

Modernizr

modernizr是一個判斷瀏覽器支援性的JavaScript library ,比起以往使用userAgent判斷不同瀏覽器的支援性,使用modernizr相對更直覺方便。

支援性的example:

//是否支援css3動畫的效果
if( Modernizr.csstransitions ){

}

//是否支援touch event
if( Modernizr.touch ){

}

在css3如transform屬性,在不同瀏覽器上,都會有不同屬性名稱,可以用prefixed來判斷:

//如果是chrome則會顯示WebkitTransform
console.log( Modernizr.prefixed('transform') );

如果要判斷css的media query,目前是否符合那段判斷,可以使用Modernizr.mq

Modernizr.mq('(min-width: 0px)');

判斷event可以採用hasEvent:

//是否有縮放event(iphone、ipad)
Modernizr.hasEvent('gesturestart', elem) ;

如果要自己撰寫測試的判斷,可以使用addTest

//官方已實作
Modernizr.addTest('canvas', function() {
  var elem = document.createElement('canvas');
  return !!(elem.getContext && elem.getContext('2d'));
});

判斷有沒有此css屬性:

Modernizr.testProp('pointerEvents')

其他method的使用方式和詳細文件,可以參考官方的doc

Backbone history

backbone的router,主要用途是可以依照不同url,做不同的動作,很適合拿來做動態頁面切換,像是拿來製作mobile web,就滿適合的,使用到的技術有兩種,一個是利用錨點(#)的特性,另一個則是使用html5的pushState,達到不換頁的效果。

以下是官方的範例:

var Workspace = Backbone.Router.extend({

  routes: {
    "help":                 "help",    // #help
    "search/:query":        "search",  // #search/kiwis
    "search/:query/p:page": "search"   // #search/kiwis/p7
  },

  help: function() {
    doSomething("help");
  },

  search: function(query, page) {
    doSomething( query, page );
  }

});

定義好router要做的事情後,接著把router實體化:

new Workspace()

最後執行start,router就能開始運作了:

/**
* 開始使用router
* @param {String} root 指的是起始url
* @param {object} opts.pustState 就是html的pushState,如果為true就不會採用錨點方式,而是直接更動url,讓web看到在不同頁面的url
*/
Backbone.history.start({root:"/"});

/**
* 更動web上的location url
* @param {String} url
* @param {Object} opts.trigger 為true,則會觸發router event,如果為false,只會更動location url
* @param {Object} opts.replace 為true,會取代目前這筆的history,pushState則是新增一筆
*/
Backbone.history.navigate("/search",{trigger:true});

用錨點的優勢,支援舊有的瀏覽器(backbone都處理好了,即時不支援pushState,也會採用錨點方式),也可以直接利用a這個element,直接觸發event,而不需在另外寫script去bind event。如下:

<a href="#search">search</a>

利用pushState想達到跟錨點一樣的效果,可以如下:

$(document.body).on( "click", "a.history-go" ,function( event ){
    Backbone.history.navigate( $(this).attr("href").replace("#","") ,{trigger:true} );
    event.preventDefault();
}).on( "click", "a.history-back" );

接著只要在a這個Element,加入class,即可達到一樣效果:

<a class="history-go" href="#search">search</a><br>
<a class="history-back">back</a>