almost 4 years ago

常用Javascript的人都知道,[this這個關鍵字在一個函式內究竟指向誰]的這個問題很令人頭大,本人在這裡整理了一下Javascript中this的指向的五種不同情況,其中前三種屬於基本的情況,而後兩種情況可基於前三種情況的方式來進行思考。

1.this指向於調用該函式之物件

如果你有學過C/C++,你可能會記得一個物件內的成員函式裡的this指的即是該成員函式所在之物件,但在Javascript裡則有那麼些許不同,Javascript裡的this看的是究竟是誰調用該函式,而不是看該函式被定義在哪個物件內,這個大原則抓到了,基本上就已經可以探知this的奧秘了。底下寫一下這種情況的公式與範例:

公式
物件.函式(); //函式內的this指向該物件
範例
var obj = {
  x: 20,
  f: function(){ console.log(this.x); }
};

obj.f(); //由於調用f函式時,點前面物件為obj,故f內的this指向obj,則輸出為20。


obj.innerobj = {
  x: 30,
  f: function(){ console.log(this.x); }
}

obj.innerobj.f(); //由於調用f函式時,點前面物件為obj.innerobj,故f內的this指向obj.innerobj,則輸出為30。


2.this指向全域物件(瀏覽器:window物件、node.js:GLOBAL物件)

如果調用函式的前方並未有物件,則函式內this就指向全域物件。在瀏覽器內全域物件為window物件,而在node.js中全域物件則為GLOBAL物件。底下一樣寫一下這種情況的公式與範例:

公式
函式(); //函式內的this指向全域物件
範例
var x = 10;
var f = function(){
    console.log(this.x);
};

f(); //由於調用f函式時,前方並未有[物件.]的形式,故f內的this指向全域物件,則輸出全域變數的x(10)。

例外:在使用node.js時,若使用node file.js這樣的方式執行js檔,並不會讓宣告的全域變數掛在全域物件上(意指會利用function將code整個包起來執行),故輸出應為undefined。

前兩種情況常見誤導範例

範例一、物件之成員函式內有函式(感謝NSLin在實務讀書會上的範例Code)
example1.js
var x = 10;
var obj = {
  x: 20,
  f: function(){
    console.log(this.x);
    var foo = function(){ console.log(this.x); }
    foo(); // (2)

  }
};

obj.f();  // (1)

這個範例會輸出多少呢?別忘記大原則,在Javascript裡的this看的是究竟是誰調用該函式,故並不會輸出20 20,而是輸出20 10,為什麼呢?因為(1)obj.f()調用時,f前面物件為obj,故f內的this指向obj。但因為調用f內的(2)foo函式時是用foo(),調用的前方並未有物件,故foo內的this指向全域物件,所以輸出會是全域變數的x的值。

若要讓foo內使用obj.x的值,解法如下:

example1.js
var x = 10;
var obj = {
    x: 20,
  f: function(){
    console.log(this.x);
    var that = this; //使用that保留在這個函式內的this

    var foo = function(){ console.log(that.x); } //使用that取得obj

    foo();
  }
};

obj.f();
範例二、借用函式
example2.js
var x = 10;
var obj = {
    x: 20,
  f: function(){ console.log(this.x); }
};

obj.f(); // (1)


var fOut = obj.f;
fOut(); //(2)


var obj2 = {
    x: 30,
  f: obj.f
}

obj2.f(); // (3)

範例中三次調用之函式的this所指向的物件為何,不知道各位能不能看得出來。雖然用的是同一個函式,但是因為調用的不同,故this所指向的物件就不同。(1)obj.f()的f所指向的是obj,這比較沒有問題,輸出的會是20;而(2)fOut()裡的this,則是因為調用時前方無物件,則this所指的是全域物件,輸出的會是10;最後(3)obj2.f()則是obj2去呼叫f,故f內的this指向的是obj2,輸出的會是30。

3.this指向利用call或apply所指派給this的物件

有個方法可以更動前兩種敘述所讓this指派的值,就是利用call與apply。call與apply都是呼叫該函式並讓該函式的this指向給予call或apply的第一個參數。至於call和apply的差別則是在於其後面給予被調用之函式的參數放入的方法不同,一個是直接攤平放在第二個以後的參數;一個是直接放入一個裡面放要給予之參數的陣列。底下一樣看一下公式和範例:

公式
(A物件.)函式.call(B物件,參數1,參數2,參數3, ......); //函式的this指向B物件(若B物件為null,則指向全域物件)

(A物件.)函式.apply(B物件,[參數1,參數2,參數3, ......]); //函式的this指向B物件(若B物件為null,則指向全域物件)
範例
var obj = {
    x: 20;
  f: function(){ console.log(this.x); }
};

var obj2 = {
    x: 30;
};

obj1.f.call(obj2); //利用call指派f的this為指向obj2,故輸出為30

4.this指向new所產生之新物件

若將函式當作建構式(constructor)來用,則內部的this則指向於new所產生之新物件。

公式
new 建構式(); //建構式內之this指向new所產生之新物件
範例
function Monster(){
    this.hp = 100;
};

var monster = new Monster(); //Monster的this指向new出來之新物件並回傳回來,new的寫法就類似於下面的寫法。

var monster = (function(){
    var _new = { constructor: Monster, __proto__: Monster.prototype }; //在IE內可能不相似

  _new.constructor(); //這也是為何說可以利用前三種情況來變化的原因,constructor呼叫時,this指向的即是_new這個物件。

  return _new;
})();

5.callback函式內的this會指向於調用放入該callback的函式之this所指向之物件

先想想在jQuery中,我們若要讓#button這個元素被click的時候,內容改為"Clicked"這樣的字串,該如何寫呢?

clicked.js
$('#button').click(function(){
    this.html("Clicked");
})

此時這個this居然會指向$('#button')這個物件,感覺很自然,但實際想想會覺得很神奇。假設你寫一個function,它可以吃一個function,並在裡面呼叫傳入的function,你該怎麼寫呢?

function-to-function.js
var f = function(innerf){
    //前面的處理

    innerf(arg1, arg2, arg3, ......);
    //後面的處理

}

但如果這樣寫的話,innerf裡的this根據前述規則就應該是全域物件了!那為什麼常常別人實作的callback函式可讓this指向於調用放入該callback的函式之this所指向之物件呢?這表示大家實作上會遵守一個規則,會將自己的this傳給callback當作它的this來用!這也是為什麼我說這個情況其實也是前三種情況的變化而已了!所以上面的code應該改成如下的形式會比較好:

function-to-function-improved.js
var f = function(innerf){
    //前面的處理

    innerf.call(this, arg1, arg2, arg3, ......);
  //或是innerf.apply(this, [arg1, arg2, arg3, ......])

    //後面的處理

}

參考資料

  1. Javascript的this用法:http://www.ruanyifeng.com/blog/2010/04/using_this_keyword_in_javascript.html
  2. [图解] 你不知道的 JavaScript - “this”:http://www.cnblogs.com/ruxpinsp1/archive/2008/04/20/1162463.html
 
almost 4 years ago

該如何在網頁內放置圖片以及超連結,我照慣例先使用一個範例讓你看,再來解釋這個範例的意義。

pictureHyperlinkExample.html
<!DOCTYPE html>
<html>
    <head>
    <meta charset="UTF-8" />
    <title>圖片與超連結範例</title>
  </head>
  <body>
    <h1 id="top">圖片與超連結</h1> <!-- 設定h1的id為top -->
    <img src="http://www.knightzone.org/image/thumbs/32.jpg" alt="全身圖" /> <!-- 放置圖片 -->
    <a href="http://www.google.com" target="_blank">往Google</a> <!-- 連結並換新分頁 -->
    <p>好幾個段落</p>
    <p>好幾個段落</p>
    <p>好幾個段落</p>
    <p>好幾個段落</p>
    <p>好幾個段落</p>
    <p>好幾個段落</p>
    <p>好幾個段落</p>
    <p>好幾個段落</p>
    <a href="#top">回Top</a> <!-- 連結至id為top的地方 -->
  </body>
</html>

img標籤:放置圖片

如果要在網頁中放置圖片,可使用img標籤,它具有兩個屬性必須設定,一個為src屬性,是放你的圖片的路徑;另外一個則是alt屬性,是放你的圖片的說明文字,也有可能會被用於圖片連結不到時的替代文字。

img.html
<img src="圖片所在路徑" alt="說明文字" />

當要改變圖片的大小,可使用CSS語法,或是使用width(寬度)與height(高度)屬性,此兩個屬性的值在HTML5中必為數值,單位是像素點(pixel),而若在HTML4.01裡還可以使用%數。建議在你每個img標籤上都盡量加上這兩個屬性,這樣在網頁載入時若連結不到該圖片,還是會保留一塊相同大小的方塊,可避免排版亂掉。

imgwh.html
<img src="圖片所在路徑" alt="說明文字" width="圖片寬度" height="圖片高度"/>

a標籤:放置超連結

若要放置超連結,可使用a標籤,它有href屬性可以設定該連結要往那兒去,當使用者點擊時瀏覽器會跳至該頁面。

a.html
<a href="網頁所在路徑">連結文字</a>

如果不希望連結蓋掉目前的網頁,而是希望開新分頁去顯示連結的網頁,則可加上target屬性,並給予值為_blank

newpage.html
<a href="網頁所在路徑" target="_blank">連結文字</a>

超連結不一定要連到其他的網頁,如果這個網頁過長時,要上上下下滑動很麻煩時,可指定將瀏覽器跳到某個HTML元素位置上,每個HTML元素都可以設定id屬性去給予元素一個id名稱,這樣a標籤就可以連結到該元素上。a標籤僅需要在href屬性的值前方加上#,後面再加上要連結到的元素的id屬性名稱即可。以前HTML4.01會使用a標籤的name屬性去設立錨點,讓超連結可以連結該地方,不過到了HTML5後就刪除name屬性了,一律改使用任何HTML元素的id屬性來設定。

id.html
<h1 id="id名稱">標題</h1>
...
<a href="#id名稱">連結文字</h1>

當然你可以將上面連結到其他網頁以及某個HTML元素位置上的方法結合起來,變成連結到該頁的某個HTML元素上。

otherpageId.html
<a href="網頁所在路徑#id名稱">連結文字</a>

相對路徑與絕對路徑

以上不論是img標籤的src屬性或是a標籤的href屬性皆是放置一個檔案的路徑位置,路徑分成兩種:一種是相對路徑,另外一種則是絕對路徑。

相對路徑

相對路徑是指從你所在的位置該如何走到欲連結到的檔案的位置的路徑表示,底下用幾張我以前的ppt來解說。

假設該網頁名稱為second6.html,若要連結到與網頁在同資料夾的圖片,則直接打上該名字即可。

若要連結到位於跟網頁同資料夾的picture資料夾內的圖片,則打上picture,後面再加上斜線分隔,再打上圖片名稱。如果資料夾非常多層則是一樣的道理,可以寫成同層資料夾/內層資料夾1/內層資料夾2/...以此類推/圖片名稱

若要連結的圖片在網頁所在的資料夾的上一層,則使用..去表示。

絕對路徑

絕對路徑通常是為了連結外部的資料,不在本網站內的資料去使用,因為不是本站的資料,所以無法使用相對路徑去連結到,只能使用絕對路徑去連結。若使用相對路徑,則網頁搬到不同的地方會連結到的位置會不同,端看該網頁的位置在何處;但若使用絕對路徑,則網頁不管搬到不同的地方則連結到的地方會是相同的。若你的資料會跟你的網站一起搬動,建議使用相對路徑;若不會,則使用絕對路徑。

若是使用絕對路徑,則開頭會先寫明協定名稱,接著是IP位置、Domain Name或是電腦內的絕對路徑,例如要連結到Google就寫<a href="http://www.google.com>Google連結</a>,如果要瀏覽網頁者連到他自己電腦的圖片則使用<img src="file:///C:/myphoto.jpeg" />(當然我不建議連到本機端這種用法)。

參考資料

  1. w3schools.com > HTML <a> Tag:http://www.w3schools.com/tags/tag_a.asp
  2. w3schools.com > HTML <img> Tag:http://www.w3schools.com/tags/tag_img.asp
  3. html5 - HTML Anchors with 'name' or 'id'? - Stack Overflow:http://stackoverflow.com/questions/484719/html-anchors-with-name-or-id
 
almost 4 years ago

基於昨天瑪莉羊問我該怎麼將課表的Excel檔轉成圖片,又剛好我要把成績單的Excel檔也要轉成圖片,所以我就查了一下開怎麼做,底下列出如何將試算表轉成圖片。

轉換步驟

  1. 首先先開啟Excel檔案,並將要轉成圖片的範圍框起來。

  2. 再來對該範圍按下Ctrl+C或是點擊滑鼠右鍵選擇複製。

  3. 最後在小畫家(或是其他繪圖軟體)裡面按下Ctrl+V貼上後儲存成圖片即可。

參考資料

  1. How to Save an Excel Spreadsheet As an Image or Picture | eHow:http://www.ehow.com/how_5968604_save-excel-spreadsheet-image-picture.html
  2. Excel: Save a worksheet as an image file | CyberText Newsletter:http://cybertext.wordpress.com/2011/06/29/excel-save-a-worksheet-as-an-image-file/
 
almost 4 years ago

電腦裡面只能儲存0與1,並且透過二進位的方式用0與1儲存了數字,透過數字與文字的對應,電腦可以利用儲存數字的方式去儲存文字,並在顯示的時候透過對應表去找出該數字代表的文字為何,這樣的對應儲存模式就被稱為編碼。這世界上有很多語言,故編碼也有很多種,若使用的編碼不對,會導致網頁上出現我們有時候去瀏覽國外網站的時候常常會出現的亂碼現象,如下圖所示:

因此我們必須要確定我們製作出來的網站是用什麼編碼方式儲存的,並且要試著從網頁裡去設定其網頁編碼,讓瀏覽器可以用正確的編碼方式去瀏覽該網站。

常見編碼

各國都有不同的編碼,底下試著列出一些常見的編碼:

語言 常見編碼名稱
繁體中文 Big5
簡體中文 GBK
日文 Shift-JIS
韓文 EUC-KR

由上表可知,每個語言都有其不同的當地的編碼方式,那麼如果要顯示所有國家語言的網站該怎麼辦?

不管你是否要做一個純粹單一語言的網站或是要做多語言的網站,我都會建議你使用Unicode萬國碼的 UTF-8 的編碼方式去儲存網站,這個編碼不僅支援多個國家的語言,有些繁體中文的罕見字其實用Big5是沒辦法表示的,但是用萬國碼卻是OK的!

如何儲存UTF-8格式的網頁

如果使用的是記事本來編輯網頁,可在儲存檔案的時候,點擊底下的編碼的選項,選擇UTF-8即可,如下圖所示:

如果是使用Notepad++來編輯網頁,可在上面工具列的[編碼]裡面選擇[轉換至UTF-8碼格式(檔首無BOM)]即可,如下圖所示:

用meta標籤來設定該網頁的編碼

meta標籤在HTML文件中,是用來設定該文件的meta資料,除了可以用來設定編碼外,還可以設定很多其他跟網頁有關的資料,不過在這裡我只先提該如何設定網頁的編碼。

你可以在head元素內加上<meta charset="編碼名稱" />即可設定網頁的編碼,如果你要設定其為UTF-8的編碼,可如底下範例所示:

UTF-8.html
...
<head>
    <meta charset="UTF-8" />
  <title>標題</title>
</head>
...

在HTML4.01的時候,是使用<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />這麼冗長的敘述,但是現在HTML5,你可以使用上述如此簡短的敘述即可。

參考資料

  1. MOZILLA DEVELOPER NETWORK > 應該避免的過時語法:https://developer.mozilla.org/zh-TW/docs/Web_%E9%96%8B%E7%99%BC/Historical_artifacts_to_avoid
  2. html5 - <meta charset='utf-8'> vs <meta http-equiv='Content-Type'> - Stack Overflow:http://stackoverflow.com/questions/4696499/meta-charset-utf-8-vs-meta-http-equiv-content-type
  3. w3schools.com > HTML <meta> Tag:http://www.w3schools.com/tags/tag_meta.asp
 
almost 4 years ago

HTML文件裡面的內容大概如你在報紙上看到的一篇篇文章,一樣會具備標題、副標題、段落等等格式,我們就先給一個範例來表現一篇文章的HTML文件吧!

article.html
<!DOCTYPE html>
<html>
  <head>
    <title>文章範例</title>
  </head>
  <body>
    <h1>主要標題</h1>
    <h2>副標題</h2>
    <hr />
    <p>第一個段落</p>
    <p>第二個段落</p>
    <p>
      <em>斜體強調</em><br />
      <strong>粗體強調</strong><br />
      <em><strong>粗斜體強調</strong></em>
    </p>
  </body>
</html>

標題表示用標籤

使用h1~h6標籤分別可以表示從大到小的1級到6級的標題,當一篇文章出現標題的時候,可以使用此標籤來表示標題的部分。底下是h1~h6各個標籤範例:

header1to6.html
...
<body>
  <h1>一級標題</h1>
  <h2>二級標題</h2>
  <h3>三級標題</h3>
  <h4>四級標題</h4>
  <h5>五級標題</h5>
  <h6>六級標題</h6>
</body>
...

水平線標籤

若要使用水平線來分隔文章,可以使用hr標籤來表示,hr為一個無包內容的標籤,可以寫作<hr />

段落與換行標籤

若文章中要表示段落,可將段落使用p標籤包起來,此時段落上下會與其他段落產生分隔的效果;若僅只要使用簡單的單行換行可使用br標籤,br亦為一個無包內容的標籤,可以寫作<br />

強調標籤

若文章中有需要強調的地方,可使用em標籤做斜體強調、strong標籤去做粗體強調,若要兩者一起使用,則可巢狀式的將一個標籤包起另外一個標籤(就像範例所寫的<em><strong>強調部分</strong></em>)。如果以前有用過HTML的人可能會知道有另外兩個標籤與之效果相同,分別是i(斜體)與b(粗體)標籤。在HTML5開始強調用標籤來表示文章語意的做法後,會建議使用em、strong兩個標籤來取代i與b標籤。

block元素與inline元素

大部分的HTML元素都會定義它為block元素或是inline元素。當使用該標籤會造成該元素與上下元素自動有所分隔,則該標籤所產生的元素為block元素;相對地,若並不會造成與上下元素之間的分隔的話,則為inline元素。本範例中,像是h系列的元素和p元素就屬於block元素;而em元素和strong元素則屬於inline元素。

已被廢棄使用的樣式用標籤

在HTML5當中,已不建議使用center標籤(置中)與font標籤(改變文字樣式,像是文字大小、文字顏色等)來去做樣式變化,目前HTML語法強調是被使用在文件語意上,而樣式美觀的部分就全權交給CSS語法去做處理,故若要置中或是改變文字樣式的部分請使用CSS樣式去做。(其實不只center、font標籤,其他像是align屬性(該元素對齊用)、bgcolor屬性(背景顏色屬性)......等等與樣式有關係的標籤或是屬性都已不建議使用HTML語法做更改,請盡量都使用CSS語法去撰寫)

pre標籤:直接顯示與原語法相同內容

如果有時從別的地方直接複製一篇長篇的文章,要在該文章換行或段落的地方加上<br />或是<p>...</p>實在有點麻煩,這時候只要直接先貼上該文章,然後前後加上<pre>...文章...</pre>即可,這就是pre標籤的用途。

pre.html
...
<body>
  <pre>
這是一篇很長的文章,
害我懶的用br和p標籤,
真是抱歉!
  </pre>
</body>
...

參考資料

  1. html教學 > 第03章。常用標籤:http://m7.dfps.tp.edu.tw/chen/main5/ahtml/03.asp
  2. w3schools.com > HTML <div> and <span>:http://www.w3schools.com/html/html_blocks.asp
  3. w3schools.com > HTML <pre> tag:http://www.w3schools.com/tags/tag_pre.asp
 
almost 4 years ago

由於開學之後會有教學Web技術的讀書會,故我現在就一邊整理HTML+CSS的資料,一邊PO上Logdown這裡讓大家看看。

談到HTML語法,我們先來看一個簡單的HTML範例:

firstWebsite.html
<!DOCTYPE html>
<html>
  <head>
    <title>這裡是標題的部分</title>
  </head>
  <body>
    這裡是內容的部分。 <!-- 此為註解 -->
  </body>
</html>


底下我們開始對這個範例進行講解。

HTML版本宣告

每份HTML文件的第一行通常會放置該HTML是使用哪個版本的宣告,如今HTML5已漸漸成為主流,故我們會用<!DOCTYPE html>這行來進行版本宣告,若你有看過HTML4.01的版本宣告,你一定會知道以前的版本宣告有多麼冗長,它是長這樣的:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">,目前您已經可以盡量使用HTML5的版本宣告,現代的瀏覽器都支援它。

標籤(tag)與元素(element)

HTML文件是以一堆標籤形成的元素所組合而成的,標籤即是使用小於符號、標籤名稱與大於符號所組合而成的,而元素則是由開始標籤、標籤屬性以及標籤所包之內容與結束標籤所組合而成,底下是一個HTML元素的格式:

format.html
<標籤名 屬性1='值' 屬性2='值' ....多個屬性以此類推> 元素內容 </標籤名>

最前面的即是開始標籤,而最後面在標籤名前加上斜線的即為結束標籤。

若元素並無元素內容時,即可簡寫為下列格式:

single.html
<標籤名 屬性1='值' 屬性2='值'  ....多個屬性以此類推 />

即類似於將結束標籤開頭的斜線放置於開始標籤的尾部即可。

html、head、body標籤

每一份html文件的第一個最底部的標籤必定是html標籤,而html標籤的內容通常又會分成兩個標籤,一個是head標籤,另外一個是body標籤。

structure.html
<html>
  <head>
    ...
  </head>
  <body>
    ...
  </body>
</html>

head標籤內放置的是此HTML文件的整體資訊,像是head內一定會放的title標籤即是設定該網頁的標題。

head.html
...
<head>
    <title>這裡是標題的部分</title>
</head>
...

body標籤內則是放置網頁的內容,打在這裡面的內容都會呈現在網頁上。

body.html
...
<body>
    這裡是內容的部分。
</body>
...

註解

你可以利用<!-- 註解文字 -->放置註解,註解文字並不會顯示在網頁上,僅提供你在開發網頁的時候能夠方便了解該段程式碼的含意為何。

參考資料

  1. HTML基本語法:http://kaihang.tripod.com/computer/html/html.html
  2. w3school.com > HTML <html> tag:http://www.w3schools.com/tags/tag_html.asp
  3. 程式設計教學誌 > HTML 4.01:http://pydoing.blogspot.tw/2010/11/html-401-overview.html
 
almost 4 years ago

這篇的出現頗神奇的,主要是因為剛好看到Javascript大全中提到duck-typing,突然想到其實C#也是可以玩玩duck-typing,結果就打算來寫這篇Orz...

看到網路上似乎有人對於var和dynamic兩個的用法有點不了解,敝人就以自己沒用多久的經驗來告訴大家兩者的差別吧!

var: 編譯時期決定型別 (C# 3.0)

var基本上來說,並沒有跳脫強型別的規範,也就是說,用var宣告出來的變數,依然還是屬於靜態型別的變數。var僅僅是讓你在宣告變數時,若可以明確判斷該變數為何種型別的話,就可以不必在變數宣告式寫上其型別,寫上var即可。

varExample.cs
var s = "XD"; //由於可從後面指派的變數得知s為string型別,故可寫var
var model = new Model(); //由於可從後面指派的變數得知model為Model型別,故可寫var
var i; //此處編譯時會出錯,因為無法確定i的型別為何。
s = 1; //此處編譯時會出錯,因為s會是string型別的變數,無法儲存整數值

var一般被稱作隱含型別,它其實會在編譯的時候,編譯器自動幫你判斷該變數為何種型別,並幫你在var處填上該型別的名稱,像上面的例子var s = "XD"在編譯的時候,會用string代替掉原本的var。

舉一個簡單且常見的例子,當要對Dictionary型別去做foreach的瀏覽時,我們可直接使用var來代替掉用來當作每個單項的變數的宣告,底下範例:

dictionary.cs
Dictionary<string, int> dict = new Dictionary<string, int>();
/* 增加dict的資料 */

foreach( var pair in dict ){  //原本應該寫foreach(KeyValuePair<string, int> pair in dict)
 /* 對pair做事情 */
}

dynamic:執行時期決定型別 (C# 4.0)

這個dynamic就是真正的動態變數,類似於Javascript、Python、Ruby...等等這些語言的變數,一個變數的型態決定於被指派的時候,底下是個範例:

dynamicExample.cs
dynamic dyn; //宣告一個dynamic的變數
dyn = 2; //可以指派整數進去
dyn += 3; //當dyn內存的是整數時,此行會對
dyn = "XD"; //可以改變裡面存的變數為string型別的值
dyn += "XD"; //當dyn內存的是字串時,此行會對
dyn += 3; //當dyn內存的是字串時,此行會在執行時期發生錯誤,但編譯會過。
dyn.HelloEveryBody(); //dyn內存的值具有HelloEveryBody方法可調用的話會對,但若沒有則在執行時期會錯,但編譯會過。

由於變數可以動態的替換各種不同型態的值,編譯器會無法在編譯期找出錯誤,若要找出錯誤,只能等執行時期看看裡面的變數是否可做該運算而決定。

而這個地方也說明了你可以用C#來做duck-typing的事情,底下用個簡單的範例作為收尾。

quack.cs
void Quack(dynamic duck){
    duck.quack(); //只要傳進來的值具有quack方法可調用,則就會正確執行,不管其型別為何。
}

參考資料

  1. MSDN > var (C# 參考):http://msdn.microsoft.com/zh-tw/library/bb383973.aspx
  2. MSDN > dynamic (C# 參考):http://msdn.microsoft.com/zh-tw/library/dd264741.aspx
  3. What's the difference between dynamic(C# 4) and var? - Stack Overflow:http://stackoverflow.com/questions/961581/whats-the-difference-between-dynamicc-4-and-var
  4. var, dynamic 差別以及如何實作像 ViewBag 一樣的物件 - Kelp Code:http://kelp.phate.org/2011/11/var-dynamic-viewbag.html
 
almost 4 years ago

之前在網站上搞了一個Logo用的CSS3動畫,然後現在這個部落格的標題也用了CSS3動畫,故現在想來好好地整理一下跟CSS3動畫相關的功能,底下就開始說明該如何建立CSS3動畫。

使用@keyframes建立動畫內容

首先先在CSS檔內建立@keyframes去制定動畫的內容,其Syntax在下方:

keyframes.css
@keyframes 動畫名稱 {
    關鍵影格選擇器1 { 眾多css樣式; }
    關鍵影格選擇器2 { 眾多css樣式; }
  ...
}

概念類似Flash當中的關鍵影格,在動畫內建立各個位置的時候,其css樣式為何,到最後就交由瀏覽器去做補間效果。

關鍵影格選擇器的部分可使用:

  1. 0-100% : 在時間的幾%時為何種css樣式。
  2. from、to : 其實意思與0%和100%一樣。 上列兩種選擇器範例如下:
    percent-selector.css
    @keyframes myAnimation
    {
    0% { margin-top: 0px; background-color: yellow;}
    50% { margin-top: 50px; background-color: red; }
    100% { margin-top: 100px; background-color: blue; }
    }
    
    from-to-selector.css
    @keyframes myAnimationFromTo
    {
    from { margin-top: 20px; color: yellow; }
    to { margin-top: 80px; color: blue; }
    }
    
    建立好@keyframes動畫內容後,接著就要在欲放置該動畫的CSS樣式表內加入animation屬性。

Animation屬性

Animation屬性的Syntax於下:

animation.css
animation: name duration timing-function delay iteration-count direction;

或者依照上面每一項的名稱皆可分開寫:

animation-split.css
animation-name: 動畫名稱;
animation-duration: 動畫作用時間;
animation-timing-function: 動畫補間時運用的計算公式;
animation-delay: 動畫需間隔多久後才開始;
animation-iteration-count: 動畫作用次數;
animation-direction: 動畫作用的方向;

animation-name指的就是上面定義的@keyframes的名稱,找到你想用的@keyframes的名稱,填上去即可。

接著可以從animation-duration去指定其動畫時間,這也是為什麼上面定義@keyframes不是使用時間,而是使用%,這可以讓同一個動畫重複使用,並且不一定要執行相同的時間。

timing-function有linear、ease、ease-in、ease-out、ease-in-out可以用,或者可用cubic-bezier(n,n,n,n)來自己制定(0 <= n <= 1)。

至於iteration-count如果要無限多次可用infinite。

最後動畫作用的方向指的是動作作用的時候可以是@keyframes相反的方向(to->from、100%->0%)(reverse),或是作用完後又回頭(alternate)、或是先相反再變正常順序(alternate-reverse)。

底下用個範例去使用上面定義的myAnimation動畫:

div-animation.css
div{
  width: 100px;
  height: 100px;
  animation: myAnimation 3s ease 0s infinite alternate;
}

大體上製作一個CSS Animation就是這樣的一個流程,你也可以搭配CSS3的transform屬性去作出更多移動、翻轉、放大縮小的效果,甚至是3D翻轉喔!!

如果不想自己coding出動畫,想藉助一些工具來做動畫,可以參考使用CSS 3.0 Maker唷!

-webkit-前綴字

由於目前通用性的寫法在Chrome上還是不能用,請在CSS多複製一份@keyframes動畫與animation屬性,並在前面加上-webkit-前綴字,如下列範例所示:

webkit.css
@keyframes myAnimation
{
    0% { margin-top: 0px; background-color: yellow;}
  50% { margin-top: 50px; background-color: red; }
  100% { margin-top: 100px; background-color: blue; }
}

@-webkit-keyframes myAnimation
{
    0% { margin-top: 0px; background-color: yellow;}
  50% { margin-top: 50px; background-color: red; }
  100% { margin-top: 100px; background-color: blue; }
}

div{
  width: 100px;
  height: 100px;
  animation: myAnimation 3s ease 0s infinite alternate;
  -webkit-animation: myAnimation 3s ease 0s infinite alternate;
}

參考資料

  1. w3schools.com > CSS3 @keyframes Rule:http://www.w3schools.com/cssref/css3_pr_animation-keyframes.asp
  2. w3schools.com > CSS3 animation Property:http://www.w3schools.com/cssref/css3_pr_animation.asp
  3. 池水間 - 你需要知道的CSS3動畫技術 ::: 睡蓮‧池水間 - waterlily-lsl.com:http://waterlily-lsl.com/modules/article/view.article.php/c2/232/p2
  4. CSS 3.0 Maker:http://css3maker.com/
 
almost 4 years ago

其實在使用上篇使用YQL來進行Cross Domain AJAX之前,我是先使用別人寫好的PHP網頁將要抓取之網站資訊轉成JSONP格式回來。

ba-simple-proxy.php

此頁別人寫好的PHP連結在此:ba-simple-proxy.php

簡單來說,這PHP就是當作一個代理網頁,給它網址它就會抓取該網址所指的網頁內容,並用JSONP的格式回傳回來。

使用前先將該頁PHP內的 $enable_jsop = false; 從false改為true,然後上傳到PHP伺服器,接著使用AJAX抓取資料的js部分寫上:

xdomainajax.js
$.getJSON( /* ba-simple-proxy.php所在地 + "?callback=?&url=" + 欲抓資料之網頁所在的網址 */ , function(data){
    /* data.contents即是該網頁內容 */
});

這樣就可以進行Cross Domain AJAX了!

參考資料

  1. Cross Domain AJAX 抓網頁撈過界以及如何整合兩個部落格的標籤:http://user.frdm.info/ckhung/b/js/xdomain.php
  2. Design2U » Cross Domain Ajax 跨網域抓取資料(JSONP):http://design2u.me/blog/936/cross-domain-ajax-cross-domain-data-has-been-retrieved-jsonp
  3. SIMPLE PHP PROXY: GET EXTERNAL HTML, JSON AND MORE!:http://benalman.com/code/projects/php-simple-proxy/docs/files/ba-simple-proxy-php.html
 
almost 4 years ago

在這次撰寫無名備份工具的途中,由於寫的是Web應用程式,我要抓取無名部落格上的資料就必須要使用到AJAX,但是基於安全性的問題,AJAX在回應非JSONP的情況下,僅支援同域名之間的抓取資料,那麼該怎樣才能跨越域名去抓取資料呢?

使用YQL

查了一下發現有人是使用Yahoo所提供的一套API-YQL來進行跨域抓資料的動作,而正好有人也幫你把它包裝起來寫成一個jQuery的plugin,讓你引用該javascript碼後使用$.get就可以直接跨越域名去抓取資料。

底下正是該plugin的github位址(使用此plugin,也必須引入jQuery函式庫):
https://github.com/padolsey/jQuery-Plugins/tree/master/cross-domain-ajax/

引用以上的plugin後,在要做讀取資料的地方寫入底下的Code:

xdomainajax.js
$.get(/* 此處放置欲抓取之資料所在的URL */, function(data){
    /* data.responseText即為所在該URL的網頁內容 */
});

大體上我就是這樣成功的將資料抓進來了!!

參考資料

  1. Cross Domain AJAX 抓網頁撈過界以及如何整合兩個部落格的標籤:http://user.frdm.info/ckhung/b/js/xdomain.php
  2. Cross-domain requests with jQuery:http://james.padolsey.com/javascript/cross-domain-requests-with-jquery/
  3. Cross domain mod for jQuery (Github):https://github.com/padolsey/jQuery-Plugins/tree/master/cross-domain-ajax/