15個值得開發人員關注的jQuery開發技巧和心得

15個值得開發人員關注的jQuery開發技巧和心得

作者: gbin1 來源: 博客園 發布時間: 2011-11-18 06:49 閱讀: 9092 次 推薦: 11 原文鏈接 [收藏]

英文原文:15 Powerful jQuery Tips and Tricks for Developers

在這篇文章中,我們將介紹15個讓你的jQuery更加有效的技巧,大部分關于性能提升的,希望大家能夠喜歡!

1. 盡量使用最新版本的jQuery類庫

jQuery項目中使用了大量的創新。最好的方法來提高性能就是使用最新版本的jQuery。每一個新的版本都包含了優化的bug修復。對我們來說唯一要干的就是修改tag,何樂而不為呢?

我們也可以使用免費的CDN服務,例如, Google來存放jQuery類庫。

<!-- Include a specific version of jQuery -->
http://a%20href=
<!-- Include the latest version in the 1.6 branch -->
http://a%20href=

2. 使用簡單的選擇器

直到最近,返回DOM元素的方式都是解析選擇器字符串,javascript循環和內建的javascript API,例如, getElementbyId(),getElementsByTagName(),getElementsByClassName()三種方式的整合使用。但是現代瀏覽器都開始支持querySelectorAll(),這個方法能夠理解CSS查詢器,而且能帶來顯著的性能提升

然而,我們應該避免使用復雜的選擇器返回元素。更不用說很多用戶使用老版本的瀏覽器,強迫jQuery去處理DOM樹。這個方式非常慢。

$('li[data-selected="true"] a') // Fancy, but slow
$('li.selected a') // Better
$('#elem') // Best

選擇id是最快速的方式。如果你需要使用class名稱, 那么你最好帶上tag名稱,這樣會更快些。特別是在老瀏覽器和移動設備上。

訪問DOM是javascript應用最慢的方式 ,因此盡量少使用。使用變量去保存選擇器,這樣會使用cache來保存。性能更好。

var buttons = $('#navigation a.button'); // Some prefer prefixing their jQuery variables with $:
var $buttons = $('#navigation a.button');

另外一個值得做的是jQuery給了你很多的額外便利選擇器 ,例如,:visible,:hidden,:animated還有其它,這些不是合法的CSS3選擇器。結果是你使用這些類庫就不能有效地利用 querySelectorAll() 方法。為了彌補這個問題,你需要先選擇元素,再過濾,如下:

$('a.button:animated'); // Does not use querySelectorAll()
$('a.button').filter(':animated'); // Uses it

3. 數組方式使用jQuery對象

運行選擇器的結果是一個jQuery對象。然而,jQuery類庫讓你感覺你正在使用一個定義了index和長度的數組。

// Selecting all the navigation buttons:
var buttons = $('#navigation a.button');

// We can loop though the collection:
for(var i=0;i<buttons.length;i++){
console.log(buttons[i]); // A DOM element, not a jQuery object
}

// We can even slice it:
var firstFour = buttons.slice(0,4);

如果性能是你關注的,那么使用簡單for或者while循環來處理,而不是$.each(),這樣能使你的代碼更快

檢查長度也是一個檢查你的collection是否含有元素的方式。

if(buttons){ // This is always true
// Do something
}

if(buttons.length){ // True only if buttons contains elements
// Do something
}

4. 選擇器屬性

jQuery提供了一個屬性,這個屬性顯示了用來做鏈式的選擇器。

$('#container li:first-child').selector // #container li:first-child
$('#container li').filter(':first-child').selector // #container li.filter(:first-child)

雖然上面的例子針對同樣的元素,選擇器則完全不一樣。第二個實際上是非法的,你不可以使用它來創建一個對象。只能用來顯示filter方法是用來縮小collection。

5. 創建一個空的jQuery對象

創建一個新的jQuery空間能極大的減小開銷。有時候,你可能需要創建一個空的對象,然后使用add()方法添加對象。

var container = $([]);
container.add(another_element);

這也是quickEach方法的基礎,你可以使用這種更快的方式而非each()。

6. 選擇一個隨機元素

上面我提到過,jQuery添加它自己的選擇器過濾。除了類庫,你可以添加自己的過濾器。只需要添加一個新的方法到$.expr[‘:’]對象。一個非常棒的使用方式是Waldek Mastykarz的博客中提到的:創建一個用來返回隨機元素的選擇器。你可以修改下面代碼:

(function($){
var random = 0;

$.expr[':'].random = function(a, i, m, r) {
if (i == 0) {
random = Math.floor(Math.random() * r.length);
}
return i == random;
};

})(jQuery);

// This is how you use it:
$('li:random').addClass('glow');

7. 使用CSS Hooks

CSS hooks API是提供開發人員得到和設置特定的CSS數值的方法。使用它,你可以隱藏瀏覽器特定的執行并且使用一個統一的界面來存取特定的屬性。

$.cssHooks['borderRadius'] = {
get: function(elem, computed, extra){
// Depending on the browser, read the value of
// -moz-border-radius, -webkit-border-radius or border-radius
},
set: function(elem, value){
// Set the appropriate CSS3 property
}
};

// Use it without worrying which property the browser actually understands:
$('#rect').css('borderRadius',5);

更好的在于,人們已經創建了一個支持CSS hooks類庫

8. 使用自定義的刪除方法

你可能聽到過jQuery的刪除插件,它能夠允許你給你的動畫添加特效。唯一的缺點是你的訪問者需要加載另外一個javascript文件。幸運的是,你可以簡單的從插件拷貝效果,并且添加到jQuery.easing對象中,如下:

$.easing.easeInOutQuad = function (x, t, b, c, d) {
if ((t/=d/2) < 1) return c/2*t*t + b;
return -c/2 * ((--t)*(t-2) - 1) + b;
};

// To use it:
$('#elem').animate({width:200},'slow','easeInOutQuad');

9. $.proxy()

使用callback方法的缺點之一是當執行類庫中的方法后,context被設置到另外一個元素,例如:

<div id="panel" style="display:none">
<button>Close</button>
</div>

執行下面代碼:

$('#panel').fadeIn(function(){
// this points to #panel
$('#panel button').click(function(){
// this points to the button
$(this).fadeOut();
});
});

你將遇到問題,button會消失,不是panel。使用$.proxy方法,你可以這樣書寫代碼:

$('#panel').fadeIn(function(){
// Using $.proxy to bind this:

$('#panel button').click($.proxy(function(){
// this points to #panel
$(this).fadeOut();
},this));
});

這樣才正確的執行。$.proxy方法接受兩個參數,你最初的方法,還有context。這里閱讀更多$.proxy in the docs.。

10. 判斷頁面是否太過復雜

一個非常簡單的道理,約復雜的頁面,加載的速度越慢。你可以使用下面代碼檢查一下你的頁面內容:

console.log( $('*').length );

以上代碼返回的數值越小,網頁加載速度越快。你可以考慮通過刪除無用多余的元素來優化你的代碼

11. 將你的代碼轉化成jQuery插件

如果你要花一定得時間去開發一段jQuery代碼,那么你可以考慮將代碼變成插件。這將能夠幫助你重用代碼,并且能夠有效的幫助你組織代碼。創建一個插件代碼如下:

(function($){
$.fn.yourPluginName = function(){
// Your code goes here
return this;
};
})(jQuery);

你可以在這里閱讀更多開發教程

12. 設置全局AJAX為缺省

如果你開發ajax程序的話,你肯定需要有”加載中“之類的顯示告知用戶,ajax正在進行,我們可以使用如下代碼統一管理,如下:

// ajaxSetup is useful for setting general defaults:
$.ajaxSetup({
url : '/ajax/',
dataType : 'json'
});

$.ajaxStart(function(){
showIndicator();
disableButtons();
});

$.ajaxComplete(function(){
hideIndicator();
enableButtons();
});

/*
// Additional methods you can use:
$.ajaxStop();
$.ajaxError();
$.ajaxSuccess();
$.ajaxSend();
*/

詳細你可以查看這篇文章jQuery’s AJAX functionality

13. 在動畫中使用delay()方法

鏈式的動畫效果是jQuery的強大之處。但是有一個忽略了的細節就是你可以在動畫之間加上delays,如下:

// This is wrong:
$('#elem').animate({width:200},function(){
setTimeout(function(){
$('#elem').animate({marginTop:100});
},2000);
});

// Do it like this:
$('#elem').animate({width:200}).delay(2000).animate({marginTop:100});

jQuery動畫幫了我們大忙,否則我們得自己處理一堆的細節,設置timtout,處理屬性值,跟蹤動畫變化等等。

大家可以參考這個文章:jQuery animations

14. 合理利用HTML5的Data屬性

HTML5的data屬性可以幫助我們插入數據。特別合適前后端的數據交換。jQuery近來發布的data()方法,可以有效的利用HTML5的屬性,來自動得到數據。下面是個例子:

<div id="d1" data-role="page" data-last-value="43" data-hidden="true"
data-options='{"name":"John"}'>
</div>

為了存取數據你需要調用如下代碼:

$("#d1").data("role"); // "page"
$("#d1").data("lastValue"); // 43
$("#d1").data("hidden"); // true;
$("#d1").data("options").name; // "John";

如果你想看看實際的例子,請參考這篇教程:使用HTML5和jQuery插件Quicksand實現一個超酷的星際爭霸2兵種分類展示效果

data()的jQuery文檔:data() in the jQuery docs

15. 本地存儲和jQuery

本地存儲是一個超級簡單的API。簡單的添加你的數據到localStorage全局屬性中:

localStorage.someData = "This is going to be saved across page refreshes and browser restarts";

但是對于老的瀏覽器來說,這個不是個好消息。因為他們不支持。但是我們可以使用jQuery的插件來提供支持一旦本地存儲不能用的話。這種方式可以使得本地存儲功能正常工作。

以上是我們介紹的15個jQuery的開發技巧。

英文原文:15 Powerful jQuery Tips and Tricks for Developers

11
0

請先登錄 提交中…

標簽:jQuery

文章列表

Javascript閉包——懂不懂由你,反正我是懂了

Javascript閉包——懂不懂由你,反正我是懂了

作者: FrankFang 來源: 博客園 發布時間: 2011-11-16 22:08 閱讀: 296908 次 推薦: 93 原文鏈接 [收藏]
摘要:“如果你不能向一個六歲的孩子解釋清楚,那么其實你自己根本就沒弄懂。”好吧,我試著向一個27歲的朋友就是JS閉包(JavaScript closure)卻徹底失敗了。

  越來越覺得國內沒有教書育人的氛圍,為了弄懂JS的閉包,我使出了我英語四級吃奶的勁去google上搜尋著有關閉包的解釋,當我看到stackoverflow上這一篇解答,我腦中就出現了一句話:就是這貨沒跑了!

  不才譯文見下,見笑了。

  Peter Mortensen問:

就像老Albert所說的,“如果你不能向一個六歲的孩子解釋清楚,那么其實你自己根本就沒弄懂。”好吧,我試著向一個27歲的朋友就是JS閉包(JavaScript closure)卻徹底失敗了。

你們會怎么把它解釋給一個充滿好奇心的六歲孩子聽呢?

注:我看過StackOverflow上給出的示例,但根本沒用。

  Ali的回答:

  當function里嵌套function時,內部的function可以訪問外部function里的變量。

function foo(x) {
var tmp = 3;
function bar(y) {
alert(x + y + (++tmp));
}
bar(10);
}
foo(2)

  不管執行多少次,都會alert 16,因為bar能訪問foo的參數x,也能訪問foo的變量tmp。

  但,這還不是閉包。當你return的是內部function時,就是一個閉包。內部function會close-over外部function的變量直到內部function結束。

function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + (++tmp));
}
}
var bar = foo(2); // bar 現在是一個閉包
bar(10);

  上面的腳本最終也會alert 16,因為雖然bar不直接處于foo的內部作用域,但bar還是能訪問x和tmp。

  但是,由于tmp仍存在于bar閉包的內部,所以它還是會自加1,而且你每次調用bar時它都會自加1.

  (考慮到六歲這個限制:我們其實可以建立不止一個閉包方法,比如return它們的數組,也可以把它們設置為全局變量。它們全都指向相同的x和相同的tmp,而不是各自有一份副本。)

  注:現在來整點兒七歲的內容。

  上面的x是一個字面值(值傳遞),和JS里其他的字面值一樣,當調用foo時,實參x的值被復制了一份,復制的那一份作為了foo的參數x。

  那么問題來了,JS里處理object時是用到引用傳遞的,那么,你調用foo時傳遞一個object,foo函數return的閉包也會引用最初那個object!

function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + tmp);
x.memb = x.memb ? x.memb + 1 : 1;
alert(x.memb);
}
}
var age = new Number(2);
var bar = foo(age); // bar 現在是一個引用了age的閉包
bar(10);

  不出我們意料,每次運行bar(10),x.memb都會自加1。但需要注意的是x每次都指向同一個object變量——age,運行兩次bar(10)后,age.memb會變成2.

  這和HTML對象的內存泄漏有關,呃,不過貌似超出了答題的范圍。

  JohnMerlino 對Ali說:

  這里有一個不用return關鍵字的閉包例子:

function closureExample(objID, text, timedelay) {
setTimeout(function() {
document.getElementById(objID).innerHTML = text;
}, timedelay);
}
closureExample(‘myDiv’, ‘Closure is created’, 500);

  深夜1:37 John Pick這樣回答:

  JS里的function能訪問它們的:

  1. 參數

  2. 局部變量或函數

  3. 外部變量(環境變量?),包括

3.1 全局變量,包括DOM。

3.2 外部函數的變量或函數。

  如果一個函數訪問了它的外部變量,那么它就是一個閉包。

  注意,外部函數不是必需的。通過訪問外部變量,一個閉包可以維持(keep alive)這些變量。在內部函數和外部函數的例子中,外部函數可以創建局部變量,并且最終退出;但是,如果任何一個或多個內部函數在它退出后卻沒有退出,那么內部函數就維持了外部函數的局部數據。

  一個典型的例子就是全局變量的使用。

  mykhal這樣回答:

  Wikipedia對閉包的定義是這樣的:

In computer science, a closure is a function together with a referencing environment for the nonlocal names (free variables) of that function.

  從技術上來講,在JS中,每個function都是閉包,因為它總是能訪問在它外部定義的數據。

  Since scope-defining construction in Javascript is a function, not a code block like in many other languages, what we usually mean by closure in Javascript is a fuction working with nonlocal variables defined in already executed surrounding function.

  閉包經常用于創建含有隱藏數據的函數(但并不總是這樣)。

var db = (function() {
// 創建一個隱藏的object, 這個object持有一些數據
// 從外部是不能訪問這個object的
var data = {};
// 創建一個函數, 這個函數提供一些訪問data的數據的方法
return function(key, val) {
if (val === undefined) { return data[key] } // get
else { return data[key] = val } // set
}
// 我們可以調用這個匿名方法
// 返回這個內部函數,它是一個閉包
})();

db(‘x’); // 返回 undefined
db(‘x’, 1); // 設置data[‘x’]為1
db(‘x’); // 返回 1
// 我們不可能訪問data這個object本身
// 但是我們可以設置它的成員

  看了這么多外國大牛的解答,不知道你懂還是不懂,反正我是懂了。

  P.S. 發布文章之后看到@xiaotie的一篇文章,覺得有必要推薦一下,因為其剖析得更為深入。有人說應該在文章結尾對閉包進行總結,可惜小弟才疏學淺,不能給出一個精辟的總結。

  @xiaotie對閉包的總結如下:

(1)閉包是一種設計原則,它通過分析上下文,來簡化用戶的調用,讓用戶在不知曉的情況下,達到他的目的;

(2)網上主流的對閉包剖析的文章實際上是和閉包原則反向而馳的,如果需要知道閉包細節才能用好的話,這個閉包是設計失敗的;

(3)盡量少學習。

  大家學習學習。

93
105

請先登錄 提交中…

標簽:Javascript 閉包

文章列表

HTTP Caching 優化網站

HTTP Caching 優化網站

作者: Bory.Chan 發布時間: 2011-12-12 13:05 閱讀: 9084 次 推薦: 0 原文鏈接 [收藏]

  HTTP Caching 用好了,可以極大的減小服務器負載和減少網絡帶寬。十分有必要深入了解下 http 的 caching 協議。

  先來看下請求/響應過程:

http 請求/響應

http 請求/響應

  1、用 Last-Modified 頭

  在第一次請求的響應頭返回 Last-Modified 內容,時間格式如:Wed, 22 Jul 2009 07:08:07 GMT。是零時區的 GMT 時間,servlet 中可以用 response.addDateHeader (“Last-Modified", date.getTime ()); 加入響應頭。如圖:

last-modified 和 If-Modified-Since

last-modified 和 If-Modified-Since

  Last-Modified 與 If-Modified-Since 對應的,前者是響應頭,后者是請求頭。服務器要處理 If-Modified-Since 請求頭與 Last-Modified 對比看是否有更新,如果沒有更新就返回 304 響應,否則按正常請求處理。如果要在動態內容中使用它們,那就要程序來處理了。

  ps:servlet 取 If-Modified-Since 可以用 long last = requst.getDateHeader (“If-Modified-Since");

  2、用 Etag 頭

  很多時間可能不能用時間來確定內容是否有更新。那可以用 Etag 頭,etag 是以內容計算一個標識。計算的方式可以自己決定,比如可以用 crc32、md5等。

Etag 和 If-None-Match

Etag 和 If-None-Match

  Etag 與 If-None-Match 是對應的,前者是響應頭,后者是請求頭。服務器要判斷請求內容計算得到的 etag 是否與請求頭 If-None-Match 是否一致,如果一致就表示沒有更新,返回 304 就可,否則按正常請求處理。可以參考:用 HttpServletResponseWrapper 實現 Etag 過濾器

  3、用 Expires 頭,過期時間

  當請求的內容有 Expires 頭的時候,瀏覽器會在這個時間內不去下載這個請求的內容(這個行為對 F5 或 Ctrl+F2 無效,用 IE7,Firefox 3.5 試了,有效的比如:在地址輸入后回車)。

expires 過期時間

expires 過期時間

  在 servlet 中可以用 response.addDateHeader (“Expires", date.getTime ()); 添加過期內容。

  ps:在 httpwatch 中可以看到 Result 為 (Cached) 狀態的。

  4、用 max-age 的 Cache-Control 頭

  max-age 的值表示,多少秒后失效,在失效之前,瀏覽器不會去下載請求的內容(當然,這個行為對 F5 或 Ctrl+F2 無效)。比如:服務器寫 max-age 響應:response.addHeader (“Cache-Control", “max-age=10″);

  ps:如果你還要加一些 Cache-Control 的內容,比如:private,最好不要寫兩個 addHeader,而是一個 response.addHeader (“Cache-Control", “private, max-age=10″); 否則 ie 可能對 max-age 無效,原因它只讀第一個 Cache-Control 頭。

  小結:

  Last-Modified 與 Etag 頭(即是方式 1 和2)還是要請求服務器的,只是僅返回 304 頭,不返回內容。所以瀏覽怎么 F5 ,304 都是有效的。但用 Ctrl+F5 是全新請求的(這是瀏覽器行為,不發送緩存相關的頭)。

  Expires 頭與 max-age 緩存是不需要請求服務器的,直接從本地緩存中取。但 F5 會忽視緩存(所以使用 httpwatch 之類的 http 協議監察工具時,不要 F5 誤認為 Expires 和 max-age 是無效的)。

  http 協議監察工具:

  Firebox:httpfox、live http header

  IE:httpwatch、iehttpheader

  重要參考文章:How To Optimize Your Site With HTTP Caching

0
0

請先登錄 提交中…

標簽:HTTP Caching 網站優化

文章列表

HTML5標簽使用的常見誤區

HTML5標簽使用的常見誤區

來源: sinaued 發布時間: 2011-12-08 13:54 閱讀: 5787 次 推薦: 0 原文鏈接 [收藏]

  最近組內進行HTML5標簽的學習,方法呢就是大家每人挑選幾個標簽,自己先去學習,然后給大家作講解。這個過程大家還是挺有收獲的。但是現在HTML5還處在草案階段,有些新的標簽元素的解釋也是經常有變化,甚至標簽加入/移出也很頻繁(比如 hgroup),同時現有的大的門戶網站在使用HTML5方面也沒有很好的范例可以參考,讓大家的學習過程更摸索。下面是我在 html5doctor 上面看到的一篇文章,在目前大家懵懂的階段,可能看看大師的講解會更容易理解。由于才疏學淺,很多不明白的地方可能只是做了字面上的翻譯,不對的地方還請大家多多指教。

  下面附上原文地址:Avoiding common HTML5 mistakes,作者 :Richard Clark,有疑問的地方大家可以核對英文。

  在這篇文章中,我將給大家分享HTML5構建頁面的小錯誤和不好的實踐方法,讓我們在以后的工作中避免這些錯誤。

  不要把<Section>當成簡單的容器來定義樣式

  我們經常看到的一個錯誤,就是武斷的將<div>標簽用<section>標簽來替代,特別是將作為包圍容器的<div>用<section>來替換。在XHTML或者HTML4中,我們將會看到類似下面的代碼:

<!– HTML 4-style code –>
<div id="wrapper">
<div id="header">
<h1>My super duper page</h1>
<!– Header content –>
</div>
<div id="main">
<!– Page content –>
</div>
<div id="secondary">
<!– Secondary content –>
</div>
<div id="footer">
<!– Footer content –>
</div>
</div>

  現在我看到了下面的代碼樣子:

<!– Don’t copy this code! It’s wrong! –>
<section id="wrapper">
<header>
<h1>My super duper page</h1>
<!– Header content –>
</header>
<section id="main">
<!– Page content –>
</section>
<section id="secondary">
<!– Secondary content –>
</section>
<footer>
<!– Footer content –>
</footer>
</section>

  直觀的看,上面的例子是錯誤的:<section> 并不是一個容器。<section>元素是有語意的區段,幫助構建文檔大綱。它應該包含標題。如果你要尋找一個可以包含頁面的元素(不論是 HTML 或者 XHTML ),通常的做法是直接對<body>標簽定義樣式就像Kroc Camen描述的那樣子,如果你還需要額外的元素來定義樣式,使用<div>, 就像Dr Mike 闡述的那樣, div并沒有滅亡,如果這里沒有其它更合適的,div可能是你最合適的選擇。
  記住這點,這里我們重新修正了上面的例子,通過使用兩個新角色。(你是否需要額外的<div>取決于你的設計。)

<body>
<header>
<h1>My super duper page</h1>
<!– Header content –>
</header>
<div role="main">
<!– Page content –>
</div>
<aside role="complementary">
<!– Secondary content –>
</aside>
<footer>
<!– Footer content –>
</footer>
</body>

  如果你還是無法確定哪一個元素更適合使用,我建議你去查看HTML5 sectioning content element flowchart來讓你繼續前行。

  只在需要的時候使用<hgroup>和<header>標簽

  使用標記的時候寫入了一些并不需要的現象這是不合理的。不幸的是,經常發現大家在并不需要的地方使用<header>和<hgroup>標簽。你可以跟進我們關于<header>和<hgroup>的最新進展,下面是我的簡單歸納:

  • <header>元素通常是通常作為一組解釋或者導航輔助工具,通常包含section的標題.
  • <hgroup>元素會將當有副標題\子標題,各類標識文字時,對<h1>到<h6>標題進行群組,將其作為section的標題.

  過度使用的<header>

  你肯定知道,在一個文檔中,可以使用多次<header>標簽,下面就是一種很受大家歡迎的模式:

<!– Don’t copy this code! No need for header here –>
<article>
<header>
<h1>My best blog post</h1>
</header>
<!– Article content –>
</article>

  如果你的<header>標簽只包含一個標題元素時,就不要使用<header>標簽了。<article>標簽肯定會讓你的標題在文檔大綱中顯現出來,而且因為<header>并不包含多重內容(就像定義中描述的那樣子),我們為何要增加而外的代碼呢?應該像下面這樣簡單才可以:

<article>
<h1>My best blog post</h1>
<!– Article content –>
</article>

  <hgroup>不合理使用

  在標題的這個主題上,經常看到使用<hgroup>的錯誤案例。在下面這種情況下你不能將<header>標簽和<hgroup>標簽一起使用:

  • 這里只有一個標題,
  • 或者<hgroup>本身就夠了(比如:不需要<hgroup>)

  第一種情形看上去是下面的樣子:

<!– Don’t copy this code! No need for hgroup here –>
<header>
<hgroup>
<h1>My best blog post</h1>
</hgroup>
<p>by Rich Clark</p>
</header>

  這種情況下,將<hgroup>移除,只保留標題就好.

<header>
<h1>My best blog post</h1>
<p>by Rich Clark</p>
</header>

  第二種情況也是包含了他們并不需要的標簽.

<!– Don’t copy this code! No need for header here –>
<header>
<hgroup>
<h1>My company</h1>
<h2>Established 1893</h2>
</hgroup>
</header>

  當<header>標簽的子元素只有<hgroup>的時候,為什么我們還需要一個額外的<header>?如果沒有額外的元素放到<header>中(比如<hgroup>的兄弟元素),我們直接將<header>元素去掉就好。

<hgroup>
<h1>My company</h1>
<h2>Established 1893</h2>
</hgroup>

  不要將所有的鏈接列表都放到<nav>標簽

  在HTML5新增的30個元素中(在我們寫這篇文章的時候),我們在構建更具語義\結構化的標簽的時候,我們的選擇變得太豐富。也就是說我們對現在給我們提供的這些超級有語義的標簽,我們可能會濫用。<nav>就是一個很悲劇的例子。在規范中的描述是這樣的:

The nav element represents a section of a page that links to other pages or to parts within the page: a section with navigation links.

Note: Not all groups of links on a page need to be in a nav element — the element is primarily intended for sections that consist of major navigation blocks. In particular, it is common for footers to have a short list of links to various pages of a site, such as the terms of service, the home page, and a copyright page. The footer element alone is sufficient for such cases; while a nav element can be used in such cases, it is usually unnecessary.
WHATWG HTML spec

  這里面的關鍵詞是”重要”導航。我們可能會對”重要”有不同的定義,但是我的理解是:

  • 主要導航
  • 網站搜索
  • 二級導航(這個能是有爭議的)
  • 頁面內鏈接(比如一篇很長的文章)

  雖然并沒有對錯之分,但根據我的理解和一個民意投票讓我覺得在下面這些情形下,我不會使用<nav>標簽:

  • 翻頁
  • 社交類的鏈接(雖然有些社交類的鏈接也是主要的鏈接,比如關于我About me和品味Flavours
  • 博客文章的標簽
  • 博客文章的分類列表
  • 第三級導航
  • 大頁腳

  如果你不能確定是否使用<nav>,那就先對你問一下下面的幾個問題:“這是否是一個主要鏈接?”,你可以根據下面的幾個因素來回答你剛才的問題:

  • 如果用<section>和標題標簽能夠解決你的問題,那就不要去使用<nav>–Hixie on IRC
  • 你是不是為了增加可訪問性而增加的一個快捷跳轉鏈接呢?

  如果上面的回答都是“不”,那可能就不適合使用<nav>。

  <figure>元素的錯誤

  <figure>和經常與它合伙作案的<figcaption>,是很難掌握的標簽,下面是經常看到的一些小錯誤。

  并不是所有的圖片都是figure(注:比較難理解阿,image=圖片,figure=圖形)

  之前,我曾經說過不要寫那些不需要的標簽。這個錯誤也是相同的。我經常看到一個網站上的每張圖片都有<figure>標簽。這些額外增加的標簽并不會給你帶來任何的益處,并且還增加了你自己的工作強度和讓自己的內容變得更難理解。

  在規范中關于<figure>的解釋如下:“某些流內容,可以有標題,自我包含并且通常作為一個單元獨立于內文檔流之外。”在那里有完美的表述,就是它可以被從主內容中移除——比如放到邊攔,而對文檔流沒有影響。

  如果僅僅是一張表現類的圖片而且和文檔中其他的內容沒有關系的話,那就不需要使用<figure>.”這張圖片需要對上下文的內容作出解釋嗎?”,如果答案是”否”,那就可能不是<figure>(可能是<aside>),“我能把它移到附錄里面嗎?”,如果這兩個問題的答案都是”是”,那就可能是<figure>.

  你的標志不是一個<figure>

  將上面的延伸開來,對你的logo也是這樣。下面是兩組我找到的有規律的代碼片斷:

<!– Don’t copy this code! It’s wrong! –>
<header>
<h1>
<figure>
<img src="/img/mylogo.png" alt="My company" class="hide"/>
</figure>
My company name
</h1>
</header>
<!– Don’t copy this code! It’s wrong! –>
<header>
<figure>
<img src="/img/mylogo.png" alt="My company"/>
</figure>
</header>

  這里就不需要說啥了,這是很明顯的錯誤,可能你認為我們說的是不是將logo放在H1標簽里面,但是我們在這里并不討論這個問題。讓我們迷惑的是<figure>元素。<figure>標簽只用在當有上下文需要說明或者被<section>包圍的時候。我這里要說的是你的logo可能很少會被這種情況下使用。很簡單,那就不要去這樣做,你需要的僅僅是下面的樣子。

<header>
<h1>My company name</h1>
<!– More stuff in here –>
</header>

  figure只能用在標簽上的誤解

  另一個對<figure>的誤解就是我們通常認為它只能用在圖片上面。事實上并不是這樣子的,它可以被用在 <video><audio>, 一個圖標 (比如<SVG>), 一個引用, 一個表格, 一段代碼, 一段散文, 或者任何和這些相關的組合。不要把你的<figure>標簽僅僅局限在圖片上。我們網頁制作師的任務就是用標簽更準確的描述內容。

  這里有一篇更深入講解 <figure>的文章I wrote about <figure>,很值得閱讀的。

  不要去使用那些不必要的type屬性

  這可能是我們最常見的一些問題,它們并不是真正的錯誤,但我覺得我們的最好實踐還是盡量避免這種模式。

  在HTML5中,我們并不需要給<script>和<script>增加 type 屬性,如果這些從CMS默認添加的內容中移出是很痛苦的事情,那當你手工編碼的時候還寫入它們或者你能完全的控制你的模板時候你完全可以刪掉它們。因為所有的瀏覽器都會將<script>解析成Javascript和<css>標簽是CSS,你不再需要那個type屬性了:

<!– Don’t copy this code! It’s attribute overload! –>
<link type="text/css" rel="stylesheet" href="css/styles.css"/>
<script type="text/javascript" src="js/scripts.js"></script>

  現在我們可以寫成下面的樣子:

<link rel="stylesheet" href="css/styles.css"/>
http://js/scripts.js

  你也能夠對編碼的設置作出省略。Mark Pilgrim在Dive into HTML5的語義化一章中作出了解釋。

  不要包含錯誤的表單屬性

  你可能發現<html5>引入了很多新的表單屬性。現在我就給大家講講一些不合適的使用。

  布爾值屬性

  新引入的標簽屬性有幾個是布爾類型的,它們的標簽行為基本接近。這些屬性包括:

  • autofocus
  • autocomplete
  • required

  坦白的說,下面的這種情況對我來說并不常見,但我們從 required 作為例子,如下:

<!– Don’t copy this code! It’s wrong! –>
<input type="email" name="email" required="true"/>
<!– Another bad example –>
<input type="email" name="email" required="1″/>

  基本上看,這段代碼并不會帶來危害。客戶端對 HTML的解析遇到 required 標簽屬性時,他的功能就會生效。但是當我們將代碼修改,錄入 required=”false” 的情況呢?

<!– Don’t copy this code! It’s wrong! –>
<input type="email" name="email" required="false"/>

  解析的時候依然會遇到 required 屬性,雖然你希望加入的行為是“假”,它依然會被解析成“真”。

  這里有三種合理的方法讓布爾值生效。(第二種和第三種方案只有你在寫 XHTML 解析的時候需要)

  我們上面的例子可以寫成下面的樣子:

<input type="email" name="email" required />

  總結
  對我來說,我無法將所有蹩腳的代碼模式都展示在這里,但是上面說的這些都是我們經常遇到的。

0
0

請先登錄 提交中…

標簽:HTML5

文章列表

如何從組件開始構建一座城市?

如何從組件開始構建一座城市?

作者: Aliaksei Papou 來源: InfoQ 發布時間: 2013-06-14 14:30 閱讀: 3032 次 推薦: 6 原文鏈接 [收藏]

  英文原文:How Would You Build Up a City from Components?

  為什么越來越多的企業應用開發正在轉向組件框架和解決方案?組件架構是否有前途?我相信答案是肯定的,而且很快所有開發框架都將會是基于組件的——這是近在眼前的事情。下面讓我來向你揭示這一切的原因。

  你怎么來建設你的房子?一般你會從砌塊開始。我們可以將構建Web應用與構建你的鄉間小屋進行對比。你能夠快速構建一個非常好看的應用,而且它具有所有必需的功能。同樣,在你的房子里面,每一間房間都是針對具體的需求來創建的,例如廚房、起居室、臥室或浴室。房子的布局使你能夠通過走廊和樓梯很方便地在房間之間移動。

  現在你能夠做得更好,而且能夠承擔建設一座更大更好的房子的投入——你也許希望擁有桑拿房、游泳池、影院以及一座滿是爬行動物的巨大的水族館☺。但要想改變房子的設計卻是件非常困難的事情。若要添加額外的設施,房子最終看起來也許就不那么漂亮了。此外,由于你添加的這些設施必須放在不太方便的位置,它們也會影響房子使用的便利性,例如你必須穿過主臥室才能進入臺球室。

  最后,你那漂亮又整潔的房子將擁有一堆不同的功能,但它會變得笨拙又不舒適。同樣的道理也適用于應用開發。

  問題是,有沒有可能設計一款應用,能夠根據你的需求成長和改變?

  組件是應用的積木式構件

   組件是擴展應用功能的首要方法。創建組件的過程,與基于組件創建應用的過程<a name="_GoBack">有一些差異。組件不止應該提供有用的功能,還應該從一開始就設計成可復用的。

  組件復用

  組件應該采用松耦合方式設計以便于復用。為實現這一目標,不同的框架往往基于觀察者模式實現其事件模型。該模式允許多個接收者訂閱同一事件。

  觀察者模式的實現最早出現在Smalltalk中。Smalltalk是一個基于MVC的用戶界面框架,現在它已經成為MVC框架的關鍵部分。我希望你能注意到,自Java 1.0版本起,觀察者模式就已經在Java中存在。下面讓我們深入了解它。

  下面的UML圖展現了觀察者模式:

  以下則是一段基本的Java實現:

public class ObservableX extends Observable { ... public void setAmount(double amount) { this.amount = amount; super.setChanged(); super.notifyObservers(); } } public class ObserverA implements Observer { public void public void update(Observable o) { // gets updated amount } } public class ObserverB implements Observer { public void public void update(Observable o) { // gets updated amount } } //instantiate concrete observableX ObservableX observableX = new ObservableX(); //somewhere in code observableX.addObserver(new ObserverA()); observableX.addObserver(new ObserverB()); //much later observableX.setAmount(amount);

  它是這樣工作的:

  首先我們創建一個ObservableX類的實例,將ObserverA和ObserverB實例添加到observableX對象中,然后在代碼中的某個位置,我們使用setAmount方法設定“一定數量”的值。被觀察者(observable)類的功能將接收到的數量通知所有注冊的觀察者。

  觀察者擔當著中介的角色,維持接收者的列表。當組件里有事件發生時,該事件將被發送到列表上的所有接收者。

  由于這個中介角色的存在,組件并不知道其接收者。而接收者可以訂閱某個特定類型的不同組件中的事件。

  當一個類使用事件將自身的變化通知觀察者時,該類就可以成為一個組件。而這可以通過觀察者模式來實現。

  使用組件比創建組件容易

  通過使用組件,你能夠快速創建各種窗體、面板、窗口以及界面中的其他合成元素。不過,為了能夠復用新的由組件創建的合成部分,應該將它們轉化為組件。

  為了實現這一目標,你需要決定組件所要生成的外部事件,以及消息傳遞機制。例如,你至少需要創建新的事件類并且定義接口或回調方法以接收這些事件。

  這個方式讓實現可復用的應用組件變得更復雜。當系統只是由少量合成元素組成時沒什么問題——這時合成元素最多不超過10個。然而當系統包含數以百計的此類元素時,又當如何?

  與之相反,不遵從這一方式將導致元素間的緊耦合,并且會把復用的機會降低到0。這反過來會導致代碼復制,從而讓未來的代碼維護變得更復雜,并將導致系統中的bug數量上升。

  由于組件使用者往往不了解如何定義和傳遞他們自己的新事件,問題將變得更為嚴重。但他們可以輕松地使用組件框架提供的現成的事件。他們知道如何接收但不知道如何發送事件。

  為了解決這個問題,讓我們考慮如何簡化應用中使用的事件模型。

  太多的事件監聽者

  在Java Swing、GWT、JSF和Vaadin中,觀察者模式被用于實現多用戶能夠訂閱同一事件的模型,并將用于添加事件監聽者的列表作為其實現方式。相關事件一旦發生,將被發送到列表上的全部接收者。

  每個組件為一個或多個事件創建自己的事件監聽者集合。這將導致應用中類的數量不斷增多。反過來,這也會使系統的支持和開發變得更復雜。

  借助注解機制(annotation),Java找到了一條讓單個方法訂閱特定事件的道路。例如,考慮Java EE 6里的CDI(Contexts and Dependency Injection,上下文和依賴注入)中對事件模型的實現。

 public class PaymentHandler { public void creditPayment(@Observes @Credit PaymentEvent event) { ... } } public class PaymentBean { @Inject @Credit Event<<paymentevent> creditEvent; public String pay() { PaymentEvent creditPayload = new PaymentEvent(); // populate payload ... creditEvent.fire(creditPayload); } }

  你可以看到,當PaymentBean對象的pay()方法被調用時,PaymentEvent被觸發。接下來PaymentHandler對象的creditPayment()方法接收了它。

  另一個例子是Guava類庫中事件總線的實現:

// Class is typically registered by the container. class EventBusChangeRecorder { @Subscribe public void recordCustomerChange(ChangeEvent e) { recordChange(e.getChange()); } } // somewhere during initialization eventBus.register(new EventBusChangeRecorder()); // much later public void changeCustomer() { ChangeEvent event = getChangeEvent(); eventBus.post(event); }

  EventBus注冊了EventBusChangeRecorder類的對象。接下來對changeCustomer()方法的調用會使EventBus接收ChangeEvent對象并調用EventBusChangeRecorde對象的recordCustomerChange ()方法。

  現在你不需要為你的組件實現若干事件監聽者,在應用中使用事件也變得更簡單了。

  當所有組件都同時在屏幕上展現時,使用事件總線是很方便的。如下圖所示,它們使用事件總線進行消息交換。

  這里,所有元素——標題、左側的菜單、內容、右側的面板——都是組件。

  訂閱事件——別忘記取消訂閱

  通過將事件監聽者替換為注解,我們在簡化事件模型使用的道路上前進了一大步。但即使如此,系統中的每個組件依舊需要連接到事件總線,然后,必須訂閱上面的事件并在正確的時間取消訂閱。

  當相同的接收者多次訂閱同一個事件時,將會出現許多重復提醒,這種情況很容易出現。而相似的情況還會在多個系統組件訂閱同一事件時發生,這將會觸發一系列級聯事件。

  為了能更好地控制事件模型,將工作與事件一起遷移到配置中,并讓應用容器負責事件管理是很有意義的。由于特定的事件僅在特定條件下有效,將這些事件的狀態管理遷移到配置中也是合理的。

  下面是一段配置的例子:

<?xml version="1.0"?> <application initial="A"> <view id="A"> <on event="next" to="B"/> </view> <view id="B"> <on event="previous" to="A"/> <on event="next" to="C"/> </view> <view id="C"> <on event="previous" to="B"/> <on event="next" to="D"/> </view> <view id="D"> <on event="previous" to="C"/> <on event="finish" to="finish"/> </view> <final id="finish" /> </application>

  視圖A中的“下一個(next)”事件觸發了向視圖B的轉變。在視圖B中,用戶可以通過“前一個(previous)”事件回到A,或是通過“下一個(next)”事件進入C。D視圖中的結束事件將轉入“最終(final)”狀態,將通知應用結束其中的工作流。

  有限狀態機是專為這樣的需求設計的。狀態機是一種數學計算模型。它被設想為一種抽象的機器,可以處于有限數量的狀態中的一個,并且在同一時間里只會處于一個狀態——這被稱為當前狀態。事件或條件將觸發向另一個狀態的轉變。使用這一方式,你能夠輕松地定義活動畫面,并讓某事件來觸發向另一個畫面的轉變。

  使用有限狀態機來配置應用的好處

  大部分情況下,應用配置是靜態定義的。使用依賴注入配置應用,我們在啟動時定義應用結構。但我們忘記了在探索應用的過程中它的狀態可能會改變。在應用的代碼中,狀態改變往往屬于硬編碼,它讓未來的調整和維護變得復雜。

  將狀態間的轉變遷移到配置中可以提高靈活性。而且這正是為什么我們在創建諸如窗體、窗口或面板等復雜應用元素時,無需為了應用應該進入哪個狀態而操心。你可以稍后來處理它們,在配置中設定其行為。

  所有組件都可以使用標準的事件發送機制進行交流——即通過事件總線。同時,狀態機能夠控制組件事件到事件總線的訂閱。這一方式將應用的全部組件(窗體、窗口、面板)變為可復用組件,可以通過外部配置輕松地管理它們。

  如果有興趣,你可以看一下Enterprise Sampler中一些配置的例子。

  你也可以將狀態配置看作城市的公路圖,把事件看作遞送商品的汽車,而將城市里的人看作目的地。

  我確信采用這樣的方式,不僅能夠輕松地設計和構建一間規模雖小卻做好了成長準備的房子,還能夠建設擁有摩天大樓、公路和高速公路的城市。

  關于作者

  Aliaksei PapouLexaden.com的CTO、軟件架構師和聯合創始人,他擁有超過10年的企業級應用開發經驗,他對于技術創新有著強烈愛好。他與Lexaden.com的CEODenis Skarbichev(另一位聯合創始人)一同開發了可以創建大規模敏捷企業級應用的 Lexaden Web Flow語言。

6
0

請先登錄 提交中…

標簽:組件 Java

文章列表

HTML 5 CSS 3的新交互特性

HTML 5 & CSS 3的新交互特性

作者: joey 來源: 百度-UED 發布時間: 2011-11-29 13:45 閱讀: 6043 次 推薦: 4 原文鏈接 [收藏]

  本文標題的這副圖片,是用Phosotshop制作的。但是,在搜索引擎中你卻無法搜索到它,搜索引擎還沒有強大到能夠識別圖片里面的文字。并且由于圖片的體積不算太小,可能網速慢的網友在瀏覽的時候不得不耐心的等待圖片的刷新。那么,有沒有一種新的方法可以避免這些缺點呢?

  有的,HTML5和CSS3就可以滿足你的需求。甚至,它可以做的更多,更好。作為一名設計師,我們應當了解它們是什么東西,有什么特性,從而進一步思考通過HTML5和CSS3我們能做些什么。

  什么是HTML5和CSS3

  HTML和CSS并不難理解。HTML為構成網頁的主要語言。通過這種語言,我們可以向計算機說明網頁格式、內容、顯示效果等等。而CSS則是專門用來控制網頁顯示效果的語言。這時候問題出來了,為什么我們要單獨使用CSS呢,HTML不是一樣可以控制Web頁面的顯示效果么?為了回答這個問題,我舉個簡單的例子:

  有沒有發現如果一旦形容的事情過多,想要把事情描述清楚的時候,我們不得不重復大量的信息?頁面語言也是一樣,在這種情況下顯得雜亂無章,非常難以理出頭緒。通過將控制顯示效果的語言集成到CSS里,我們不但可以保證頁面語言主體部分的簡潔,而且可以非常方便的復用各種語言集合。

  HTML5和CSS3是HTML和CSS的最新版本,它們目前均未確定標準,但是已經公布的新特征已經讓我們心動不已。

  HTML 5的新特新

  1. 新的內容標簽

  HTML4中的內容標簽級別相同,無法區分各部分內容。而HTML5中的內容標簽互相獨立,級別不同,搜索引擎以及統計軟件等均可快速識別各部分內容。

  2. 更好的表格體系

  現在,你可以拋棄JavaScript或者是PHP,只通過HTML5來定義表格。你可以定義每個表格單元的輸入格式,也可以定義這個單元是否是必填的等等。

  3. 音頻、視頻API

  HTML5不但允許你在網頁中直接整合視頻、音頻,同時更提供了一套功能豐富的API用來控制媒體播放,而這些用來控制媒體播放的元素也都是可以被編輯的。因此,HTML5在視頻以及音頻層面上實際已經可以替代常用的flash插件了。

  4. 畫布(Canvas) API

  在網頁中繪制圖形一直是個大難題,我們不得不借助flash、silverlight等插件。然而HTML5允許你直接在網頁上進行繪圖,甚至允許你與網頁生成更多的交互,例如繪制圖形、放大縮小,等等。圖例是一個用HTML5制作的小游戲。

  5. 地理(Geolocation) API

  HTML5提供了地理信息的應用接口Geolocation API。通過這個API,網頁可以通過IP,GPS等方式來獲得用戶的地理信息;同時用戶也可以選擇是否關閉這個功能。

  6. 網頁存儲(Web storage) API

  HTML5提供了網頁存儲的API,方便Web應用的離線使用。除此之外,新的API相對于cookie也有著高安全性,高效率,更大空間等優點。

  7. 拖拽釋放(Drag and drop) API

  我們可以通過HTML5的Drag and drop API來完成網頁中的拖拽釋放效果,避免了以往的網頁在拖拽釋放過程中需要不停修改元素的位置,代碼繁多的弊端。

  CSS3 新特性

  1. RGBa

  CSS3的RGBa新特性允許你對每個元素進行色彩以及透明度的設置。而原來常用的opacity命令只能對元素及其子元素進行設置。

  2. Multi-column layout

  CSS3新提供的多欄布局選擇器無需HTML布局標簽即可生成多欄布局,同時‘欄數’、‘欄寬’以及‘欄間距’都是可以定義的。

  3. Round corners

  圓角功能可能是CSS3提供的最實用的功能了。通過Border-radius,你可以沒有任何難度的給指定的HTML元素添加圓角。并且你還可以定義圓角的大小,以及哪個角是圓角,哪個角不是圓角。

  4. @font-face

  當網頁顯示某種用戶沒有安裝的字體時,CSS3提供的@font-face功能會自動的、默默地幫用戶從網絡上下載相應字體。從而讓設計師更加自由的發揮,而不用考慮用戶的機器是否安裝了相應字體。

  5. 其他特性

  此外,CSS3還給我們帶來了漸變、防止字符串過長溢出、多重背景以及用圖片來作為元素邊框等功能。

  利用好CSS3,你可以更快捷的得到以往用很多插件才能得到的效果。同過使用元素本身來取代大部分圖片,網頁的加載速度會得到提升,這些原本是圖片的內容,也可以被搜索引擎檢索到。

  HTML5和CSS3的兼容性

  HTML5和CSS3的標準并未正式完成,各家瀏覽器對其支持程度也不盡相同。了解HTML5和CSS3的兼容性是十分必要的。下面的連接是一個專門跟蹤HTML5和CSS3兼容性的網站,有興趣的朋友可以點擊查看:

  http://www.findmebyip.com/litmus

  一些你可能感興趣的資源

  http://www.apple.com/HTML5/showcase/
  http://html5watch.tumblr.com/
  http://w3school.com.cn/index.html
  http://www.mhtml5.com/
  http://html5demos.com/
  http://www.sencha.com/
  http://www.findmebyip.com/litmus/
  http://www.thetimes.co.uk/tto/news/
  

4
0

請先登錄 提交中…

標簽:HTML5 CSS3

文章列表

Serif和Sans-serif字體的區別

Serif和Sans-serif字體的區別

作者: 冰火九九 來源: 百度空間 發布時間: 2013-11-01 10:24 閱讀: 105657 次 推薦: 32 原文鏈接 [收藏]

  在西方國家羅馬字母陣營中,字體分為兩大種類:Sans Serif和Serif,打字機體雖然也屬于Sans Serif,但由于是等寬字體,所以另外獨立出Monospace這一種類,例如在Web中,表示代碼時常常要使用等寬字體。

  Serif的意思是,在字的筆劃開始及結束的地方有額外的裝飾,而且筆劃的粗細會因直橫的不同而有不同。相反的,Sans Serif則沒有這些額外的裝飾,筆劃粗細大致差不多。如下圖:

  可以看出,我們平時所用的Georgia、Times New Roman等就屬于Serif字體,而Arial、Tahoma、Verdana等則屬于Sans Serif字體。對中文而言,同樣存在這兩大種類,很明顯,宋體、細明體(繁體中常用)等就屬于Serif,而黑體、幼圓等則屬于Sans Serif。

  Serif和Sans Serif的一般比較:

  ①Serif的字體容易辨認,因此易讀性較高。反之Sans Serif則較醒目,但在行文閱讀的情況下,Sans Serif容易造成字母辨認的困擾,常會有來回重讀及上下行錯亂的情形。

  ②Serif強調了字母筆劃的開始及結束,因此較易前后連續性的辨識。

  ③Serif強調一個word,而非單一的字母,反之Sans Serif則強調個別字母。

  ④在小字體的場合,通常Sans Serif比Serif更清晰。

  因為黑體字屬于“無襯線體”(Sans-serif),而宋體字屬于“有襯線體”(Serif),后者對于人眼的辨識來說會更輕松一些,所以閱讀的時候會比較舒服。日本文字偏歐美的無襯線體(Sans-serif),所以大部分的人都使用歌德體(相當于西洋文字的無襯線體)。

  適用用途:

  通常文章的內文、正文使用的是易讀性較佳的Serif字體,這可增加易讀性,而且長時間閱讀下因為會以word為單位來閱讀,較不容易疲倦。而標題、表格內用字則採用較醒目的Sans Serif字體,它需要顯著、醒目,但不必長時間盯著這些字來閱讀。

  像宣傳品、海報類,為求醒目,它的短篇的段落也會採用Sans Serif字體。但在書籍、報刊雜志,正文有相當篇幅的情形下,則應採用Serif字體來減輕讀者閱讀上的負擔。在Web設計及瀏覽器設置中也應遵循此原則為是。

  實際應用:

  在Firefox 中(目前似乎只有Firefox有此功能),可以分別單獨指定Sans Serif、Serif及Monospace的中西文字體,然而這個選項并未設置在工具菜單中,不過可以在Addressbar中鍵入about: config,然后在Filter中過濾font找到如下Preference Name:

Code: font.name.monospace.x-western font.name.monospace.zh-CN font.name.sans-serif.x-western font.name.sans-serif.zh-CN font.name.serif.x-western font.name.serif.zh-CN

  你可以依照上述Sans Serif、Serif及Monospace的原則來分別指定一種對應字體,按照W3C的CSS規則,在font(或者font-family)的最后都要求指定一個Serif這樣的Generic-family,避免客戶端實在沒有指定字體時使用本機上的Serif默認字體。

  因為襯線字體的可讀性非常好,所以它應用的最多的地方也正是出版物或者印刷品的正文內容等以大段文字作為表現形式的作品上。

  比較常見的襯線字體有:Georgia, Garamond, Times New Roman, 中文的宋體等等。

  無襯線字體比較圓滑,線條一般粗細均勻。比較適合用作藝術字、標題等。因為無襯線字體通常粗細比較均勻,所以在小字體顯示的時候,可讀性會降低,容易引起視覺疲勞。

  常見的無襯線字體有:Trebuchet MS, Tahoma, Verdana, Arial, Helvetica, 中文的幼圓,隸書等等。

  其他的通用字體族

  印刷學中,除了serif和sans-serif之外,通常還有Monospace等寬字體、scripts手寫體(比如花體)、blackletter鉛字體(也叫gothic哥特體。嚴格的說,很多常用的serif字體其實是gothic字體)、ornamental 裝飾體(那些在文字筆劃上或者周圍有裝飾花紋的字體。很多中世紀書籍上很常見。如果腦殘體真的成了字體,那么應該可以算裝飾體吧……)和symbol 符號字體(比如有名的wedding123……)

  Monospace等寬字體:

  所謂的等寬字體,是指每個字符寬度都一致的字體。一個著名的例子就是 Courier New 字體。因為字符寬度一致,所以特別容易對齊,能快速精確的定位到某行某列,因此經常用來顯示代碼。

  Cursive書寫體:相當于印刷學中的手寫體。中文的華文行草就是這樣的一個字體。

  網頁設計中的默認字體:字體大小(12px)、行高(18px)

font: 12px/1.5 Tahoma, Helvetica, Arial, sans-serif;

  ①font-family默認采用Tahoma. Tahoma是英文Windows操作系統的默認字體,這個字體比較均衡,顯示中英文混排很不錯,是經久耐看的一款字體。

  ②Mac OS X系統有一款比Tahoma更典雅的系統默認字體:Helvetica,非Mac系統的Helvetica字體都是Rip版。

  ③Arial是早期Windows英文系統的默認字體,XP和Vista上都是Tahoma。

  ④最后的sans-serif是針對強悍的Linux DIY族。Linux默認只有kernel,字體完全由用戶自定義,針對這部分用戶,sans-serif可能能派上用場。

  ⑤最后,無論在XP還是Vista下,不指定網頁的中文字體時,默認就是宋體。因此font-family里的’宋體’是多余的,可以省去。

32
1

請先登錄 提交中…

標簽:CSS Font

文章列表

什么是云原生

什么是云原生

作者: 葛亮 來源: 簡書 發布時間: 2019-11-17 19:31 閱讀: 1305 次 推薦: 8 原文鏈接 [收藏]

  云原生從字面意思上來看可以分成原生兩個部分。

  云是和本地相對的,傳統的應用必須跑在本地服務器上,現在流行的應用都跑在云端,云包含了IaaS,、PaaS和SaaS。

  原生就是土生土長的意思,我們在開始設計應用的時候就考慮到應用將來是運行云環境里面的,要充分利用云資源的優點,比如️云服務的彈性分布式優勢。

  那具體要怎么利用呢,請參考下圖:

  微服務
  微服務解決的是我們軟件開發中一直追求的低耦合+高內聚,記得有一次我們系統的接口出了問題,結果影響了用戶的前臺操作,于是黎叔拍案而起,靈魂發問:“為啥這兩個會互相影響?!”

  微服務可以解決這個問題,微服務的本質是把一塊大餅分成若干塊低耦合的小餅,比如一塊小餅專門負責接收外部的數據,一塊小餅專門負責響應前臺的操作,小餅可以進一步拆分,比如負責接收外部數據的小餅可以繼續分成多塊負責接收不同類型數據的小餅,這樣每個小餅出問題了,其它小餅還能正常對外提供服務。

  DevOps
  DevOps的意思就是開發和運維不再是分開的兩個團隊,而是你中有我,我中有你的一個團隊。我們現在開發和運維已經是一個團隊了,但是運維方面的知識和經驗還需要持續提高。

  持續交付
  持續交付的意思就是在不影響用戶使用服務的前提下頻繁把新功能發布給用戶使用,要做到這點非常非常難。我們現在兩周一個版本,每次上線之后都會給不同的用戶造成不同程度的影響。

  容器化
  容器化的好處在于運維的時候不需要再關心每個服務所使用的技術棧了,每個服務都被無差別地封裝在容器里,可以被無差別地管理和維護,現在比較流行的工具是docker和k8s。

  所以你也可以簡單地把云原生理解為:云原生 = 微服務 + DevOps + 持續交付 + 容器化 。

8
1

請先登錄 提交中…

標簽:云計算 云原生

文章列表

淺談ASP.NET 4中構造HTML5視頻控件

淺談ASP.NET 4中構造HTML5視頻控件

來源: IT PUB 發布時間: 2011-03-15 08:40 閱讀: 3748 次 推薦: 0 原文鏈接 [收藏]
摘要:今天我們將講講ASP.NET 4打造HTML5視頻控件,這些都是目前比較火熱的知識,希望對大家有所幫助。

  在本文中,將一步步地指導你如何使用Visual Studio 2010和ASP.NET 4的相關知識,打造一個基于HTML5標準規范的視頻播放控件,其中你會學習到一些關于HTML 5的知識,還會學到如何使用ASP.NET 4去打造一個服務端的控件。

  簡介

  ASP.NET 4中有大量由微軟或第三方提供的控件,但要是這些控件不能滿足你的需求,那該怎么辦呢?答案是:自己動手去設計!

  本教程會指導你如何去開發一個ASP.NET 的服務端控件,你會感受到在開發自己的服務端控件的同時,也提升了你開發的Web應用的質量。我們一般在開發自己的服務端控件的時候,會繼承已有的一些服務端控件并添加一些自己的功能。當開發完服務端控件后,我們可以在不同的工程中共享這個控件。一般地,我們會把開發后經過編譯的控件放在Web控件庫,跟我們正常的工程分開。當我們要在某個項目中用到該控件時,只需要簡單的把它拖拉到設計界面中去,就完成了,十分簡單。

  HTML5 Video概述

  目前,HTML5已經慢慢開始流行了,在很多非IE的瀏覽器(IE 9中對 HTML5有相當好的支持)已經支持很多HTML5的特性了。現在,還沒有很統一的播放視頻的方式,大多數是靠FLASH或者其他播放器插件,因此在HTML5規范中,就定義了播放視頻的標準,其中目前支持兩種視頻格式:Ogg文件(Ogg全稱應該是OGGVobis(oggVorbis)是一種新的音頻壓縮格式,類似于MP3等的音樂格式。

  Ogg是完全免費、開放和沒有專利限制的。OggVorbis文件的擴展名是.OGG。Ogg文件格式可以不斷地進行大小和音質的改良,而不影響舊有的編碼器或播放器)和

MPEG4文件格式。在HTML5中,要展示一個視頻,可以用如下方式實現:

 1. <video width="320" height="240" controls="controls">
2. <source src="movie.ogg" type="video/ogg" />
3. <source src="movie.mp4" type="video/mp4" />
4. </video>

  這個控件有象Play,pause和音量等屬性,也有寬度和高度兩個屬性。下面是相關的屬性列表:

  autoplay:該屬性表明視頻加載后是否自動播放還是需要有人工播放

  controls: 指定該控件是否顯示。

  height:播放器的高度。

  loop:指定設置該控件是否循環播放視頻

  preload: 指定控件是否在頁面加載時就開始加載視頻,如果不設置該屬性,則默認是autoplay屬性。

  src: 播放視頻文件的路徑。

  width: 播放器的寬度

  poster: 當沒有視頻時,顯示的圖片。

  下面我們就開始一步步設計該視頻控件了

  步驟1

  首先我們使用的是Visual Studio 2010,當然你也可以使用免費的Visual Web Developer Express。

  我們要設計的HTML5視頻播放器只是一個簡單的例子,在不同的支持HTML5的瀏覽器中可能外觀稍微有點不同,比如在FireFox下,會是如下圖的樣子:

  步驟2 創建自定義組件工程

  首先,我們必須創建一個新的類庫工程去存放我們的自定義控件。當在單獨分離的類庫中創建了自定義控件后,我們可以將其編譯為單獨的DLL,這樣在其他項目中需要的時候就可以用到了。

  用Visual Studio 2010打開你已經建立好的asp.net web項目方案,在方案資源瀏覽器中,鼠標右擊方案名,在彈出的菜單中選擇新增項目。在接下來彈出的菜單中,選擇工程類型為Web,并且選擇ASP.NET Server Control,將工程命名為CustomerControl,點確定完成這個步驟,如下圖:

  步驟3 開始設計自定義的Web控件

  在資源管理器中,右鍵點CustomControls工程,選擇“Add New Item”,再在彈出的菜單中選擇Web的分類目錄,然后在模版中選擇ASP.NET Server Control選項,如下圖:

  將控件命名為:VideoPlayer.cs,點確定,最后Visual Studio為我們生成了初步的代碼如下:

 1. using System;
2. using System.Collections.Generic;
3. using System.ComponentModel;
4. using System.Linq;
5. using System.Text;
6. using System.Web;
7. using System.Web.UI;
8. using System.Web.UI.WebControls;
9. namespace CustomControls
10. {
11. [DefaultProperty("Text")]
12. [ToolboxData("<{0}:VideoPlayer runat=server>")]
13. public class VideoPlayer : WebControl
14. {
15. [Bindable(true)]
16. [category("Appearance")]
17. [DefaultValue("")]
18. [Localizable(true)]
19. public string Text
20. {
21. get
22. {
23. String s = (String)ViewState["Text"];
24. return ((s == null) ? "[" + this.ID + "]" : s);
25. }
26. set
27. {
28. ViewState["Text"] = value;
29. }
30. }
31. protected override void RenderContents(HtmlTextWriter output)
32. {
33. output.Write(Text);
34. }
35. }
36. }

  我們要來修改上面的代碼,修改后的代碼如下:

 1. using System;
2. using System.Collections.Generic;
3. using System.ComponentModel;
4. using System.Linq;
5. using System.Text;
6. using System.Web;
7. using System.Web.UI;
8. using System.Web.UI.WebControls;
9.
10. namespace CustomControls
11. {
12. [ToolboxData("<{0}:VideoPlayer runat=server></{0}:VideoPlayer>")]
13. public class VideoPlayer : WebControl
14. {
15.
16. }
17. }

  注意的是,默認的代碼中,為控件生成了Text屬性,然而這里并不需要,因此我們把

  [DefaultProperty(“Text")]

  這行刪除掉。

  步驟4 繼續為控件增加屬性

  根據之前的介紹,我們開始為控件增加一些屬性,要增加的屬性如下:

  VideoUrl:指定視頻播放的地址。

  PosterUrl: 這個是當沒有視頻時,顯示的替代圖片的地址。

  AutoPlay:指示視頻是否自動裝載播放。

  DisplayControlButtons: 指示是否顯示或者隱藏播放的相關按鈕。

  Loop: 指示視頻是否自動播放。

  增加屬性后的代碼如下:

 1. using System;
2. using System.Collections.Generic;
3. using System.ComponentModel;
4. using System.Linq;
5. using System.Text;
6. using System.Web;
7. using System.Web.UI;
8. using System.Web.UI.WebControls;
9. namespace CustomControls
10. {
11. [ToolboxData("<{0}:VideoPlayer runat=server></{0}:VideoPlayer>")]
12. public class VideoPlayer : WebControl
13. {
14. private string _Mp4Url;
15. public string Mp4Url
16. {
17. get { return _Mp4Url; }
18. set { _Mp4Url = value; }
19. }
20.
21. private string _OggUrl = null;
22. public string OggUrl
23. {
24. get { return _OggUrl; }
25. set { _OggUrl = value; }
26. }
27.
28. private string _Poster = null;
29. public string PosterUrl
30. {
31. get { return _Poster; }
32. set { _Poster = value; }
33. }
34.
35. private bool _AutoPlay = false;
36. public bool AutoPlay
37. {
38. get { return _AutoPlay; }
39. set { _AutoPlay = value; }
40. }
41.
42. private bool _Controls = true;
43. public bool DisplayControlButtons
44. {
45. get { return _Controls; }
46. set { _Controls = value; }
47. }
48.
49. private bool _Loop = false;
50. public bool Loop
51. {
52. get { return _Loop; }
53. set { _Loop = value; }
54. }
55. }
56. }

  步驟5 修改RenderContents方法

  服務端控件的主要目的就是向瀏覽器輸出內容。因此,作為開發者,我們就必須設定好我們的控件要向客戶端瀏覽器輸出什么樣的內容。因此,我們可以重寫RenderContents方法即可,如下代碼:

 1. protected override void RenderContents(HtmlTextWriter output)
2. {
3. }

  要注意的是,該方法有個參數是以HtmlTextWriter為對象的output,它可以設置向瀏覽器輸出HTML,它有很多方法和屬性,比如AddAttribute和RenderBeginTag。

  接下來我們為控件增加向瀏覽器輸出的方法代碼了,如下:

 1. protected override void RenderContents(HtmlTextWriter output)
2. {
3. output.AddAttribute(HtmlTextWriterAttribute.Id, this.ID);
4. output.AddAttribute(HtmlTextWriterAttribute.Width, this.Width.ToString());
5. output.AddAttribute(HtmlTextWriterAttribute.Height, this.Height.ToString());
6.
7. if (DisplayControlButtons == true)
8. {
9. output.AddAttribute("controls", "controls");
10. }
11.
12. if (PosterUrl != null)
13. {
14. output.AddAttribute("poster", PosterUrl);
15. }
16.
17. if (AutoPlay == true)
18. {
19. output.AddAttribute("autoplay", "autoplay");
20. }
21.
22. if (Loop == true)
23. {
24. output.AddAttribute("loop", "loop");
25. }
26. }

  步驟6 輸出VIDEO標簽內容

  緊接著,就可以輸出video標簽內的內容了,接著增加如下代碼:

 1. output.RenderBeginTag("video");
2. if (OggUrl != null)
3. {
4. output.AddAttribute("src", OggUrl);
5. output.AddAttribute("type", "video/ogg");
6. output.RenderBeginTag("source");
7. output.RenderEndTag();
8. }
9.
10. if (Mp4Url != null)
11. {
12. output.AddAttribute("src", Mp4Url);
13. output.AddAttribute("type", "video/mp4");
14. output.RenderBeginTag("source");
15. output.RenderEndTag();
16. }
17. output.RenderEndTag();

  我們在輸出標簽的內容時,先使用了RenderBeginTag方法往瀏覽器端輸出一個標簽video,并使用RenderEndTag指示標簽內容已經輸出完畢。接下來在上面的代碼中我們判斷指定的文件格式的視頻文件是否存在,如果存在的話,則按指定的文件格式輸出。

  最后,為了防止ASP.NET 控件在向瀏覽器輸出時,帶有span標簽,我們可以把它移走,只需要重寫render方法即可,如下:

【領導力】論理想中的技術團隊

【領導力】論理想中的技術團隊

作者: Zachary_Fan 來源: 博客園 發布時間: 2019-12-01 13:55 閱讀: 1641 次 推薦: 15 原文鏈接 [收藏]

  友情提示:本文僅是筆者作為管理者,同時也作為被管理者的真實感觸,從2個角度綜合的思想總結,僅供參考。

  一、什么是領導力

  評定一個領導的能力最核心的基礎素質是領導力,那么領導力是什么?

領導力(Leadership)指在管轄的范圍內充分地利用人力和客觀條件在以最小的成本辦成所需的事提高整個團體的辦事效率的能力。
領導力與組織發展密不可分,因此常常將領導力和組織發展放在一起。

————摘自《百度百科》

  我認為這句定義背后深諳的是如何更好的去“領導人”,只要人心齊了,指哪打哪,才能發揮最大的戰斗力。

  二、容易陷入的誤區

  人心齊并不是表面看上去其樂融融,而是一種內在的專注力量,所謂形散神不散,將團隊的一個目標分解到每個人上,讓不同的人在各自的崗位上為了團隊的一致目標披荊斬棘,這是作為一個領導者該做的。讓大家在各自的領域深耕,最終結合在一起達成一個成果。舉個例子:
  2個都是新上任的領導A和領導B,分別帶領的1個團隊。領導A的團隊日常看到的情況是團隊氛圍活躍,聊著各種生活中所見所聞的話題,看上去很融洽。領導B的團隊日常看上去比較內斂,都專注于在做自己手中的事情。大家可以猜一下,哪個團隊的“戰斗力”更強?A?B?
  答案其是都不一定,我想大家肯定也見過這2種風格的團隊都有成功的案例,也就是說表面看上去如何并不能代表戰斗力,他僅僅和團隊領導的風格個性有關,但是最終的產出成果還是由這位領導的每一個決策+團隊的執行力來影響的。所以在此對一些新上任作為領導的小伙伴們說一句:‍不用把自己的精力花在如何討好你的員工上面,如何將組織的目標和與員工的自我價值的實現結合起來提高執行力和自驅力才是你們需要考慮的問題。
  過于刻意的“團建”的確緩解了領導者的很多焦慮,但并不是提高團隊戰斗力的一劑良藥,因為最終看的還是結果。類似的現象又如加班,這也是個過程的表象。解決這個問題的方式可以通過基于福格行為模型(http://www.behaviormodel.org/)的框架來思考方案。

  三、領導力的通用準則

  首先領導力本身是個行業無關的定義,有一些準則是通用的:

  1. 明確職責(職位、責任),以減少灰色地帶為己任。

  不管在什么崗位上,只要有工作,那么就有責任。為了更好的擔責,需要做好相應的授權。至少不能因為由于給到的資源不夠,導致工作沒完成,這個鍋是誰的?就是作為領導你的鍋。 舉個例子:

  在職場中比較常見的一個情況是,組織遇到了一個問題需要解決,這個時候領導迅速的拉上這個問題的相關人,安排工作說“現在有個什么問題,大家務必想辦法在今天解決”。這時候2種不同類型的員工面臨的情況是這樣的:

  a)老油條型:這事和我沒有直接關系,我等人來找我配合的時候再說。心中一頓悠閑 ╮(╯▽╰)╭
  b)進取型:這是個體現自己的價值的機會,但是不知道需要哪些人來配合,不知道他們會不會配合我。既是機會,也是個燙手的山芋。心中一頓糾結 ≥﹏≤
  最終的結果,有很大可能沒能按時達到領導的要求完成。當然也有少數人能夠沖破重重阻力,最終把事情搞定,這類人本身是“金子”,但是金子并不常有。而且這類金子本身的動力源頭是強烈的實現自我價值的意愿,他們所追求的是自身價值的最大化,所以尋求更大的發展平臺、創業才是這類人的歸宿,留下這類人的途徑是提供更大的舞臺去滿足TA的施展,也就是授予更大的全力和責任。不然“金子”的離開,去尋求更大的平臺只是時間問題。
  總結一句話就是:一件事情明確由一個團隊、一個人負責,不能有重合。唯一的重合是完全重合,那是一種競爭關系,也是需要提前說清楚明確好的。另外注意的是,一但放權了,就盡量不要伸手干預,給一些試錯成本在里面。

  2. 有紅線也有激勵

  這是驅動力的來源,在考慮激勵的時候也需要設立紅線,也就是所謂的獎罰分明。有2種途徑可以達成:物質和精神。
  在物質方面,這個可能對于高層次領導者手段更多,可以提供諸如股票、期權、金錢等物質方面的東西。但是不管獎還是罰,務必要及時,才有殺傷力和后續的威懾力。不能將一個狼牙棒揮成棉花棒,因為這是團隊士氣最大的助推器。但是,激勵也不是靈丹妙藥,如果濫用了,不但沒有預期的作用,甚至可能讓整個團隊的價值觀成為利益導向。
  在精神方面,其實就是在上文中提到的“員工的自我價值的實現”,其實也就是要讓每個人找到成就感。每個人都想成為牛X的人,這就好比跑馬拉松,每個人都想跑全馬證明自己的能力,但是目標定的太遠,往往容易半途而廢。通過不斷的得到成就感來刺激,以達成自我價值的實現,是解決半途而廢,提高自驅力的重要方式。

  3. 心中要有明確的問題重要性和優先級,將挖掘解決問題的關鍵路徑作為己任。

  每個人有不同的價值觀和世界觀,并且它是隨著每個人的知識結構、主觀意識的改變而改變的。那么如何讓組織協調一致、運轉順利的關鍵,就在于如何消除信息不對稱,如何將一個企業的大腦CEO的想法以最低的損耗傳達到最底層是作為領導的你關鍵的職責之一。
  領導者的消息來源必然比你的成員更多,并且對重要性的認知更準確,例如:VP和CXO可以在與CEO的直接溝通中,得知CEO對某些事的決策方式;總監是從VP和CXO那;經理從總監那,以此類推。
  價值觀、世界觀是我們做出決策,衡量重要性和優先級的基礎。企業文化能解決思想層面的問題,但是最終如何落實到每一件事,做的每個決策中,是需要領導者心中非常明確的。通過領導者的認知來挖掘出解決問題的關鍵路徑,將這條路徑比喻成一條繩,得先有繩,才能有“一根繩上的螞蚱”之說,大家都是圍繞著這根繩在做事,而且這根繩越細越短就越聚焦,越有穿透力。這根繩的粗細是和領導者所在的層級和團隊所處的階段是有直接關系的,還是舉個例子:
  有一個創業型公司做一個ToC的產品,其中的開發團隊,遇到一個問題,這個問題有3個解決方案,方案A對應的利益點對公司老板、股東有益,方案B對應的利益點對用戶有益,方案C對應的利益點對自己的員工有益。
  那么如何來決策,我相信對不同的人會有不同的答案。本身方案沒有對錯,只有與組織的價值觀、世界觀匹配程度的差異。
  在這個創業型公司中,為了保證每一個環節都能夠貫徹“用戶第一”的原則,作為開發團隊的領導者,應該將相應的決策點與組員進行深入的溝通,講明為什么做,而不是僅僅是闡述一下要做什么,然后交由組員去實施。一個ToC產品的初期如果做出來沒有核心,甚至是四不像,將對面向用戶群的殺傷力的大大降低。所以這是一根又細又長的繩子。

  4. 接著上面第3點,什么時候需要給組員發散性思維的機會。

  大家都知道軟件開發沒有銀彈,我認為任何事物都一樣,只有最合適,沒有最好。但我覺得如何來考量也很簡單,盡可能廣的來考量成本和收益。發散性是有收益的,收益是可以獲取更加多的想法,能夠考慮到范圍是比少數幾個人想的要廣的。并且提供了實干者向思考者轉變的機會,可以挖掘有潛力的人才。但是它也是需要成本的,因為有些問題對一部分人來說就是一個未知的問題,將一個未知的問題搞清楚,還要抓到其中的痛點,這本來就比從已知方案中找出可以解決它的方案是需要更多的資源的(經驗的優勢就體現在這里)。
  比如像上面的例子中一個企業初期的時間就是生命,一旦延誤戰機,產生的后果真的是導致公司可以倒閉的,所以這個收益和成本相比是微不足道的。相反的,如果收益 > 成本,那么就可以提供發散性思維的機會,企業和團隊在成長,需要培養更多的中流砥柱來支撐擴張。
  作為領導者,務必要注意這個成本大小關系: 每件實事 < 單點決策權 < 范圍決策權,循序漸進方能體現一個“穩”字,提高容錯能力。

  四、技術團隊特有的領導力

  技術團隊特有的領導力特色我認為就1點。因為技術團隊里大部分都是理性的人,一就是一,二就是二。看待作為領導的你也是一樣,能力行就是行,能力不行就是不行。而且一旦認為你能力不行,再轉變到行,其中付出的努力是好幾倍的。越是貼近前線的技術管理者,這個問題越重要,因為你的威信需要一定的技術能力來支撐。

  所以我覺得在團隊、人、方向上扎穩了之余,還是需要盡量將自己的能力范圍能夠覆蓋到所有人,減少產生決策失誤的可能性,團隊較小的情況下甚至要在所有人之上,如下面這個圖1,是一個相對較為理想的能力矩陣范圍(綠色區域為管理者):

【圖1】

  萬丈高樓平地起,細節就是一磚一瓦,越是接近技術第一線的管理者這個越重要,如果沒掌控好就容易出現風格迥異的“磚瓦”不利于長期的健康快速發展。

  五、結語

  其實管理本身需要考量的維度就是多個的,這多個維度本身也是有優先級的。衡量的依據無非還是成本和收益,或者是這個問題的輻射范圍的大小。本篇是以我當下對管理的理解所進行的列舉,可能若干年后回頭看看會有一些觀點是欠妥的,各位權當參考。
  另外之前看到一篇文章,從領導者的4個不同的角度定位來講的,我覺得非常不錯,分享給大家(傳送門在此:http://36kr.com/p/5044486.html)。

15
0

請先登錄 提交中…

標簽:團隊管理 技術團隊

文章列表