分類
程式技術

flickr的相片尺寸

上傳到 flickr 的相片會轉出數種尺寸, 一共有哪些尺寸呢? 以這張圖為例:

http://farm9.staticflickr.com/8423/7675009574_9053807c52_b.jpg

上面看到的尺寸分別為:

Square 75, Square 150, Thumbnail, Small 240, Small 320, Medium 500, Medium 640, Medium 800, Large 1024, Large 1600, Large 2048, Original 共計 12 種尺寸, 其中的 Medium 800, Large 1600, Large 2048 這 3種是要在 2012/3/1 後上傳才新增的尺寸.

尺寸說明如下:
Square 75 為 75×75, Square 150 為 150×150, Thumbnail 為長邊100, Small 240 為長邊240, Small 320 為長邊320, Medium 500為長邊 500, Medium 800為長邊 800, Large 1024為長邊 1024, Large 1600 為長邊 1600, Large 2048為長邊 2048, Original 則為原圖.

上面的範例圖來看, 網址為:

http://farm9.staticflickr.com/8423/7675009574_9053807c52_b.jpg

其中最後的 _b 就是他的尺寸代碼, 尺寸代碼共計以下:
Square 75 為 _s, Square 150 為 _q, Thumbnail 為 _t, Small 240 為 _m, Small 320 為 _n, Medium 500為預設無代碼, Medium 800為 _c, Large 1024為 _b, Large 1600 為 _h, Large 2048為_k, Original 則為 _o.

所以上面的 _b 就是 Large 1024了.

調整一下由 flickr setid 取出相簿功能的程式, 將相片尺寸也列入功能, 於是增加了可以選擇相片尺寸的版本:

http://sample.diary.tw/flickrset/

大家可以用看看!

ps. 由於 _o 必須是有 flickr pro 帳號才有的功能, 所以不把這個尺寸加到可選的功能內.

官方資料: http://www.flickr.com/help/photos/#18

分類
程式技術

table分行分色方式

在 HTML 中, 寫表格做報表是再平常不過的事了.

不過若是要分行分色, 一般可以設一個 class出來, 用個淺色的底色來放在奇數行或是偶數行來呈現, 效果就會出來了.

現在要利用 CSS3 的 selector 來進行這個操作, 也就是 nth-child 的語法. 來看看怎麼用吧!

基本上這個 selector 寫在 tr 後, 如:

tr:nth-child(odd)

這樣自然就會是在奇數行應用對應的 css, 可以參考 http://sample.diary.tw/32/1.htm 的 List1.

List1 用的 css 如下:

tbody.sample1 tr:nth-child(odd){ 
    background: #efefef;
}

當然若是需要選擇偶數行, 則可以使用 nth-child(even) 即可.

下面介紹選擇若是需要每 3行一次, 則可以利用以下語法:

tr:nth-child(3n)

自然就會是每 3行為選擇到的, 可以參考 http://sample.diary.tw/32/1.htm 的 List2.

List2 用的 css 如下:

tbody.sample1 tr:nth-child(3n){ 
    background: #efefef;
}

所以這裡出個題目, odd 及 even 等同於什麼呢? 分別為 2n+1 及 2n, 有興趣的朋友們可以自行試看看.

另外再來看一個更複雜的, 3行, 但用兩色, css 就會多一點:

tbody.sample3 tr:nth-child(3n){
    background: #efefef;
}
tbody.sample3 tr:nth-child(3n+1){
    background: #ffefef;
}

效果請參考 http://sample.diary.tw/32/1.htm 的 List3.

這個”第n個小孩”選擇器用的法, 可以參考這裡: http://www.qianduan.net/useful-nth-child-recipies.html , 其實就是數學的代數式, n從 0 開始, 1次加 1, 所以以下為幾種可能:

n+5 代表著第 5, 6, 7, 8, 9….
-n+3 代表著第 3, 2, 1
2n 代表著 2, 4, 6, 8… (因為沒有第 0個, 也等同於 even)
2n+1 代表著 1, 3, 5, 7… (也等同於 odd)
3n 代表著 3, 6, 9 …

這樣就容易看懂了!

分類
.net

LOG4NET的基本操作

這個 LOG4NET是用來做 .net 應用程式LOG使用的套件, 主要用來做除錯, 線上系統記錄, 稽查等應用時可以用來做記錄的套件, 是基於 Apache Project 下的專案, Open Source.

這裡做個簡單的基本介紹, 其實這套件功能十分強大, 可以只利用 config 檔就可以做得很多深層的設定, 並加以記錄, 而不用改到主程式. (當然, 前提是在主程式內必須要下對應的 log information 才行)

首先先到官方網站下載此專案, 這裡建議抓 compile 好的版本, 內含有說明文件:

http://logging.apache.org/log4net/download_log4net.cgi

這頁下的 log4net-1.2.11-bin-newkey.zip , 下載解開後, 裡面主要是 compile 好的 binary 檔, 找到 bin/net/[版本]/release 下的 log4net.dll 檔, 複製到自己的專案中, 就算初步完成了.

接下來就是在自己的專案裡加入參考 (reference), 並使用它的 namespace:

using log4net;

接下來就是設定 config file, 先列出下面 config xml內容:

<configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>

<log4net>
    <logger name="loginfo">
        <level value="INFO" />
        <appender-ref ref="InfoAppender" />
    </logger>
    <appender name="InfoAppender" type="log4net.Appender.RollingFileAppender">
        <param name="File" value="Log//info.log" />
        <param name="AppendToFile" value="true" />
        <param name="MaxFileSize" value="4096" />
        <param name="MaxSizeRollBackups" value="10" />
        <param name="StaticLogFileName" value="false" />
        <layout type="log4net.Layout.PatternLayout">                
            <param name="ConversionPattern" value="%date [%thread] %-5level %logger - (%file:%line) %message%newline" />
        </layout>
    </appender>
</log4net>

其中的 section name = log4net 是用來說明會有一個 config section 是給 log4net 用的, 而下面的 log4net 才是真的 config 要寫的內容.

這裡只建了一個 logger, 名為 loginfo (名稱可以自訂), 然後 appender-ref 設為 InfoAppender 就是指向再下面的 appender , 這個 appender type 設為 RollingFileAppender 是用檔案來記錄用, 其他內容說明如下: (logger 也可以是 database 等其他的輸出裝置, 這裡以檔案為例)
File: 檔名
AppendToFile: 是否要寫到檔案
MaxFileSize: 單一 log 檔大小上限 (bytes)
MaxSizeRollBackups: 多少檔案一個循環, 當達到 MaxFileSize 時, 會自動附上 CurBackups 來檔案獨立出來, 並於達到這個數值時, 再重頭用(overwrite).
StaticLogFileName: 若設為 true, 則會以 File 名稱為 log檔名, false 則會以 [file].yyyy-mm-dd 的方式記錄
下面的 layout 則是用來設定 log 內容的欄位, %date 是日期時間, %thread 是執行緒, %level 是記錄層級, %logger 是 logger 名稱, %file %line 是原始程式檔名及行數, %message是 log的內容, %newline 就是換行了.

接下來就是在程式內呼叫的方式, 程式如下, 以 asp.net 為例:

protected void Page_Load(object sender, EventArgs e)
{
    log4net.Config.XmlConfigurator.Configure();  
    ILog infologger = LogManager.GetLogger("loginfo");

    infologger.Info("Page_Load - useragent:" + Request.UserAgent);
}

在 page_load 時, 使用 Config.XmlConfigurator.Configure() 將 log4net 的 config 載入, 然後建立一個 ILog 的 interface, 利用 LogManager.GetLogger(“logger name”) 來取得 logger, 再來利用 .Info(“message”) 方法來將要記錄的 log 內容寫入 log 檔.

而除 Info 方法外, 還有 Debug, Error, Fatal, Warn 共計5個 log level.

最後以 asp.net 做的 log 內容如下:

2013-03-13 15:30:37,925 [4] INFO loginfo – (d:\testlog4net\Default.aspx.cs:19) Page_Load – useragent:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; MS-RTC LM 8; InfoPath.1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E)
2013-03-13 15:37:42,721 [4] INFO loginfo – (d:\testlog4net\Default.aspx.cs:19) Page_Load – useragent:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; MS-RTC LM 8; InfoPath.1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E)
2013-03-13 15:37:46,456 [4] INFO loginfo – (d:\testlog4net\Default.aspx.cs:19) Page_Load – useragent:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; MS-RTC LM 8; InfoPath.1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E)
2013-03-13 15:37:46,800 [4] INFO loginfo – (d:\testlog4net\Default.aspx.cs:19) Page_Load – useragent:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; MS-RTC LM 8; InfoPath.1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E)
2013-03-13 15:37:47,112 [4] INFO loginfo – (d:\testlog4net\Default.aspx.cs:19) Page_Load – useragent:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; MS-RTC LM 8; InfoPath.1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E)
2013-03-13 15:37:47,393 [4] INFO loginfo – (d:\testlog4net\Default.aspx.cs:19) Page_Load – useragent:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; MS-RTC LM 8; InfoPath.1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E)
2013-03-13 15:37:52,065 [4] INFO loginfo – (d:\testlog4net\Default.aspx.cs:19) Page_Load – useragent:Mozilla/5.0 (Windows NT 5.2; rv:19.0) Gecko/20100101 Firefox/19.0

是不是很容易上手呢, 大家可以再試看看!

官方說明文件:
log4net SDK: https://logging.apache.org/log4net/release/sdk/
RollingFileAppender: https://logging.apache.org/log4net/release/sdk/log4net.Appender.RollingFileAppender.html
其他的 Appender: https://logging.apache.org/log4net/release/sdk/log4net.Appender.html

繼續閱讀:
http://biancheng.dnbcw.info/c/72275.html
http://blog.csdn.net/javc/article/details/4022677

分類
Javascript

反向排序內容(倒排)

今天在整理 http://sample.diary.tw/ 時, 發現 sample 愈來愈多了, 而且內容是由舊往新排, 想說把它反過來排, 新的放在上面, 舊的在下面.

由於內容不多, 把 <li> 手動一筆筆排一下應該不會花太多時間, 不過又想到應該是要用指令來才有效率才對, 於是想說用 sort 指令來操作, 發現 sort 功能強大, 要用來做倒排反而不是很快速方便.

乾脆又來動手寫個小程式好了(又是一個 sample): http://sample.diary.tw/31/1.htm 只利用了 javascript 的 array 功能, 馬上就寫好了一個反向排序功能(倒排功能), 用法很簡單, 就是把文字內容貼進去, 按下[反向排序]按鈕, 就會倒排完成.

程式如下:

//var arrData = document.getElementById("data").value.split("\n");
//arrData = arrData.reverse();
//document.getElementById("data").value = arrData.join("\n");
document.getElementById("data").value = document.getElementById("data").value.split("\n").reverse().join("\n");

前三行可以簡化為最後一行, 簡單說明, 就是把 textarea 內容取出, 用換行 split分割為陣列, 再用 reverse 倒排後, 再利用 join 用換行合併, 塞回去原本的 textarea 完成.

所以現在的 http://sample.diary.tw/ 是由新到舊排了!

分類
Javascript

Youtube影片重覆播放Bookmarklet

有時候需要重覆播放 youtube 上的影片, 當然可以透過一些參數來進行設定, 不過一時要使用的話, 可以透過這個 bookmarklet 來進行, 程式碼如下:

javascript: (function () {
    var url = location.href;
    var videoid = '';
    var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
    var match = url.match(regExp);
    if (match && match[7].length == 11) {
        videoid = match[7];
    }
    if (videoid != '') {
        var nurl = 'http://youtube.googleapis.com/v/' + videoid + '?loop=1';
        window.open(nurl);
    }
})();

利用這個 bookmarklet 可以在瀏覽 youtube 影片時, 想要重覆播放時, 可以按下這個 bookmarklet 來進行重覆播放, 原理就是將原來的 youtube url 找出影片 id 後, 組合出 url: ​http://youtube.googleapis.com/v/?loop=1 這樣的方式.

另外關於 bookmarklet 的新增方式, 就是直接將網頁上的連結, 拖拉到瀏覽器的書籤區即可.

請到這裡進行安裝: http://sample.diary.tw/youtuberepeat/

上面程式碼中, 找出 youtube video id 的 regular expression 是利用這篇文章中的解答: http://stackoverflow.com/questions/3452546/javascript-regex-how-to-get-youtube-video-id-from-url

—————————-
[2013/1/12 21:04]
今天在IE上測試的時候, 發現直連的URL是無法在IE上直接打開的, 只能藉著一個宿主頁面來做EMBED程式的方式來進行, 調整了一下程式, 使目標頁改為:
http://sample.diary.tw/youtuberepeat/r.html?vid=

即可帶出對應的播放器, 並能在播放後再自動播放, 不過在這段測試時, 發現這個 loop=1 的參數有時有功能, 有時沒有功能, 在對照了 http://www.youtuberepeater.com/ 網站時, 發現再加一個參數能確保正確 loop, 就是 version=2 的參數, 在 http://sample.diary.tw/youtuberepeat/ 上的兩個 bookmarklet 一併做調整, 也就是原本的改為
http://youtube.googleapis.com/v/?loop=1&version=2
而新做的第二個有宿主的bookmarklet 中的 embed參數也補上.

分類
Database

資料庫整筆ROW比對

在資料庫操作時, 有時會需要比對資料表的內容是否一致, 或是某些資料的某些欄位是否一樣, 若是使用 SQL 指令來逐行比對, 會是個比較麻煩的操作方式, 使用 CHECKSUM 函數, 可以方便地將待比對的資料(多欄亦可), 計算出 hash index (int)後, 再進行比對, 舉例如下:

兩個 table 資料:

table TBL_TMP1
fno fdata fcreatetime
1 ‘data 1’ ‘2012/1/1’
2 ‘data 2’ ‘2012/2/3’
3 ‘data 3’ ‘2012/2/4’
4 ‘data 4’ ‘2012/4/1’

table TBL_TMP2
fno fdata fcreatetime
1 ‘data 001’ ‘2012/1/1’
2 ‘data 2’ ‘2012/2/12’
3 ‘data 3’ ‘2012/2/4’
4 ‘data 4’ ‘2012/4/1’

若要找出資料不同的資料列, 可以使用如下指令:

SELECT * FROM
(SELECT *, CHECKSUM(*) AS CHK FROM TBL_TMP1) a INNER JOIN
(SELECT *, CHECKSUM(*) AS CHK FROM TBL_TMP2) b
ON a.fno = b.fno AND a.CHK != b.CHK

其中用了 CHECKSUM(*) 是將 table 中的各欄位合併起來計算 hash index, 再將兩個 table 含有 hash index (欄位名 CHK)拿來比對, 列出不同的資料, 結果如下:
1 data 1 2012-01-01 00:00:00.000 803471792 1 data 001 2012-01-01 00:00:00.000 1877235137
2 data 2 2012-02-03 00:00:00.000 266601110 2 data 2 2012-02-12 00:00:00.000 266601103

是很方便的工具函數.

附上建立上面 sample code 的 create table 及 insert data 指令:

CREATE TABLE TBL_TMP2 (fno int, fdata varchar(20), fcreatetime datetime)

INSERT INTO TBL_TMP1 values (1, 'data 1', '2012/1/1')
INSERT INTO TBL_TMP1 values (2, 'data 2', '2012/2/3')
INSERT INTO TBL_TMP1 values (3, 'data 3', '2012/2/4')
INSERT INTO TBL_TMP1 values (4, 'data 4', '2012/4/1')

INSERT INTO TBL_TMP2 values (1, 'data 001', '2012/1/1')
INSERT INTO TBL_TMP2 values (2, 'data 2', '2012/2/12')
INSERT INTO TBL_TMP2 values (3, 'data 3', '2012/2/4')
INSERT INTO TBL_TMP2 values (4, 'data 4', '2012/4/1')

大家可以試看看, 若是只要比對前兩欄, 則指令如下:

SELECT * FROM
(SELECT *, CHECKSUM(fno, fdata) AS CHK FROM TBL_TMP1) a INNER JOIN
(SELECT *, CHECKSUM(fno, fdata) AS CHK FROM TBL_TMP2) b
ON a.fno = b.fno AND a.CHK != b.CHK

結果如下, 就是只有第一筆資料的前兩欄不同而已:
1 data 1 2012-01-01 00:00:00.000 -1291957785 1 data 001 2012-01-01 00:00:00.000 -1493283680
如同我們想要的結果一樣. 這樣一來可以方便活用這個 CHECKSUM 函數, 十分方便好用!

相關資料:
http://msdn.microsoft.com/en-us/library/ms189788.aspx

資料上寫到是 SQL Server 2005 以上版本可用, 不過其實在 SQL Server 2000 也有這個指令:
http://msdn.microsoft.com/en-us/library/aa258245%28v=sql.80%29.aspx

分類
Javascript 懶得分類

強大的HTML5離線作業

HTML5裡令人驚豔的一項特性就是可以離線瀏覽功能.

利用這項功能, 可以很容易地讓網頁在沒有網路的環境下, 也能順利讓使用者閱讀及使用, 而且實作上也相當單純, 只需要注意寫好更新網頁的邏輯及時間點即可.

一般來說, 只需要把 manifest 設定好, 基本的離線瀏覽功能就差不多完成了, manifest 的設定容易, 就是把”要”在離線瀏覽的網頁及內容, 寫在 manifest 裡, 例如網頁是

http://test.com/mypage.htm

內容有一個 js/myjs.js
另外還有兩張圖為 imgs/1.jpg 及 imgs/2.jpg

則在 mypage.htm 中的 html tag 裡, 多加上 manifest=”mypage.manifest” 而且在 mypage.manifest 中, 加上以下內容(純文字):

CACHE MANIFEST
mypage.htm
js/myjs.js
imgs/1.jpg
imgs/2.jpg

這樣就完成了. 有意思的地方是即使用 mypage.php 這樣的動態內容, 一樣可以利用這樣的方式將內容存在客戶端中.

如此一來, 即使在沒有網路的狀況下, 也可以順利瀏覽這個網頁內容 http://test.com/mypage.htm

接下來要說明的是更新方式, 一旦寫入到客戶端的內容, 即使原本的 mypage.htm 更新, 就算是有連線時, 該內容也不會更新(而且即使是動態的 aspx, php 等也都是一樣的), 簡單地說, 在 manifest 中的內容, 就是完全使用客戶端的內容, 不管 server 上的內容, 更新的方式就是更新 manifest 的檔案, 瀏覽器會檢視 manifest 內容來進行更新, 而且會自動更新(在線上時的第一次讀到 manifest 更新時, window.applicationCache.status 會變成狀態 4 (window.applicationCache.UPDATEREADY), 此時可以手動更新, 使用 window.applicationCache.update(); 即可做手動更新, 即使在這次的訪問不更新, 在下一次的訪問時, 瀏覽器也會自動更新.

利用這點, 就可以很容易地實作出離線瀏覽內容的網頁.

若希望只更新這些快取內容, 最簡單的作法是在 mypage.manifest 中, 多加個時間或版本號, 如下:

CACHE MANIFEST
#VER 000151

mypage.htm
js/myjs.js
imgs/1.jpg
imgs/2.jpg

其中的 # 代表著這行為註解, 所以可以自由寫入內容, 上例是寫個版本號 000151, 若要強迫客戶端更新時, 可以將這個 manifest 檔的版本號改為 000151 (若其他內容都可以), 這樣就可以方便容易地來維護在客戶端離線的內容更新.

這裡有一篇很清楚的介紹文, 可以參考
http://www.ibm.com/developerworks/cn/web/1011_guozb_html5off/

另外, 配合良好的設計結構, 可以將離線/在線的功能都實作出來, 方便在無法連線時, 也能使用的網頁, HTML5 的這個功能, 的確非常強大!

在實作測試時, 發現若是有設定 manifest 的網頁, 有些瀏覽器對有些 server request 即使沒有設定在 manifest 中, 也會有快取或存取的異常狀況, 建議在 manifest 的最後, 再多加上

NETWORK:
*

這兩行, 可以讓不正常工作的 server request 正常運作.

相關資料:
http://diveintohtml5.info/offline.html

w3c 的資料:
http://www.w3.org/TR/html5/offline.html

Apple Safari的資料:
http://developer.apple.com/library/safari/#documentation/iPhone/Conceptual/SafariJSDatabaseGuide/OfflineApplicationCache/OfflineApplicationCache.html

分類
Javascript

半浮動DIV區域 part2

才寫了”半浮動DIV區域”這個文章 (link), 又發現還有另一種應用情境, 就是捲到下面, 若半浮動區域的底部觸到了 footer , 則要順勢往上, 不再固定.

參考應用如: http://www.yinshiweb.com/ 右側的側欄.

先來看看原始的長相, 一樣是上面 top, 中間 main, 並含有 content 及 flow_div 兩個區域, 還有最下方的 footer. 不含捲動的狀況如: http://sample.diary.tw/29/o.htm

接下來要加上程式碼, 原來的半浮動DIV區域, 只需要用 CSS 配合捲動 event 就可以達成, 但若在浮動區域觸底時, 要跟著捲動上去, 就必須將該 absolute css 的 top 位置用 footer 的 top 減去 flow_div 的高度才行, 不過這個值是動態的, 所以就只能在 runtime 時, 用 jQuery 的 css 屬性來給定, 先看浮動及跟著捲的兩個狀態配合的 css:

.fixed{
    position:fixed;
    top:0px;
}
.absolute{
    position: absolute;
    /*top: should be top2 value, modified by jQuery*/
}

其中的 absolute 的 top 得由後面的程式來給定及移除, javascript 如下:

$(document).ready(function(){
    // calculate the original top
    var top = $('#flow_div').offset().top - parseFloat($('#flow_div').css('marginTop').replace(/auto/, 0));
    var top2 = $('#footer').offset().top - $('#flow_div').height();     
    
    $(window).scroll(function (event){
        var y = $(this).scrollTop();
        if(y>=top){
            if(y<top2){
                // state 3.
                $('#flow_div').addClass('fixed');
                $('#flow_div').removeClass('absolute');
                $('#flow_div').css('top', '0px');
            }else{
                // state 2.
                $('#flow_div').removeClass('fixed');
                $('#flow_div').addClass('absolute');
                $('#flow_div').css('top', top2 + 'px');
            }
        }else{
            // state 1.
            $('#flow_div').removeClass('fixed');
            $('#flow_div').removeClass('absolute');
            $('#flow_div').css('top', '0px');
        }
    });    
});

一樣要先算出 top 及 top2 兩個值, 然後在 scroll event 中判斷三種狀況,
state 1. 原始狀態, 還沒捲到 flow_div
state 2. 捲到 flow_div 了, 但底部還未頂到 footer
state 3. 捲到 flow_div 底部頂到 footer 了

完成的結果請參考: http://sample.diary.tw/29/2.htm

分類
Javascript

半浮動DIV區域

一般網頁利用CSS排版, 通常分為上中下三段, 分別為 top, main, footer.

其中在 main 做一些特效, 讓一個區域能在捲動時, 會固定在畫面上. 這樣的特效, 需要配合 javascript (或 jQuery ) 來進行才能達成, 先來看一下效果: link.

除了上(top), 中(main), 下(footer)外, 另外在 main 中還有一個 content 及 flow_div 兩個區域. 在向下捲動時, 若 flow_div 捲動超過畫面上方時, 則會變成固定在畫面上.

程式的實作方式利用 jQuery 來進行, 先看程式碼:

$(document).ready(function(){
    // calculate the original top
    var top = $('#flow_div').offset().top - parseFloat($('#flow_div').css('marginTop').replace(/auto/, 0));    
    $(window).scroll(function (event){
        var y = $(this).scrollTop();
        if(y>=top){
            $('#flow_div').addClass('fixed');
        }else{
            $('#flow_div').removeClass('fixed');
        }
    });
});

在 document ready 時, 先把 #flow_div 的 top 距離算出來, 接下來在 window 的 scroll event 裡, 把 window 的捲動距離算出來後, 和上述的 top 變數比較, 若是超過了, 就把 #flow_div 多加上一個 class 名為 fixed, 讓它固定, 反之則將 fixed class 移除, 也就是跟著畫面捲動.

其中 fixed class 內容重點在於: position: fixed; top: 0px; , 也就是固定在距離畫面上方為 0, 看起來就是浮在原來的內容之上, 若還沒有捲動, 就移除這個 class, 會跟著捲動.

很有意思的一個排版特效.

範例頁: http://sample.diary.tw/29/1.htm

分類
Javascript

多個檔案上傳-multiple upload with HTML5

在以往 form 中使用上傳元件, 只能做單檔上傳, 一個 input type=file 只能做一個檔案, 若是需要做多個檔案同時上傳, 得需要使用多組 input type=file 或是利用 flash 來達成.

不過在 HTML5 中, 定義了 multiple 屬性, 讓 input type=file 可以同時傳上來多個檔案. 來看看用法吧.

<form method=post enctype='multipart/form-data'>
file(s):<input type="file" name=ufile id=ufile multiple />
<input type="submit" value="upload" / >
</form>

就這麼簡單, 在原來的 input type=file 多加個 multiple 即可, 這樣功能就可以達成多個檔案上傳了, 不過若是要限制檔案數, 就得要用 client javascript 來進行檢查, 在 onsubmit 時, 做個數檢查即可.

接下來就看範例囉, 放在這裡: http://sample.diary.tw/28/lm.php

這個範例利用了 file 及 size 屬性將上傳檔案的檔名及大小列出來, 不過不會上傳, 不用擔心, 純在客戶端執行的!