我們先把話說在前頭, Javascript的所有函數並不適用在所有的瀏覽器, 這個大家都贊同吧?

所以你一定會跟我一樣想先擷取使用者的瀏覽器版本, 看看它是用IE, MOZILLA還是Opera等等的, 但這樣的方法真的好用嗎? 老實說這是相當難維護的, 因為瀏覽器會一直更新, 如果你都用IF ELSE來判斷它的版本應該會要一直更新吧, 而且你又要怎麼判斷你的使用者會不會比你更快更新它的瀏覽器呢?

舊的方法如下:

javascript:alert(navigator.userAgent);

如果你使用IE7, 它會回傳給你: Mozilla 4.0/ …..

這樣的方法真的不是很好, 在這裡有個不錯的方式來判斷:

if (typeof featureName != "undefined") {
// 程式碼
}

舉例如下:

if (typeof document.getElementById != "undefined") {
alert("getelembyid is supported");

} else {
alert("no getelembyid support");
}

我們要判斷瀏覽器是否支援getElementById 就可以直接用typeof document.xx != "undefined" 來判斷 如果使用者不支援這個函數你就可以再另外想辦法. 另外一種寫法如下:

var getElem = (typeof document.getElementById == "function") ? true : false;
if (getElem) {
// 我們知道GetElementbyId是支援的,
// 所以我們就可以用它.
}

這樣是不是比較實際且容易維護呢?

大家都知道事件的用法就是當某個事件(狀況)被觸發了之後就會去執行某個Function, 尤其是Javascript, 在當紅AJAX的催化下, 了解Javascript的Event用法更加重要, 在這裡就大概介紹一下Javascript的Event用法.

從W3C的發展時間軸來看, DOM(Document Object Model)的模型可以分為兩種, DOM 0 及 DOM 2. 從數字來看就可以知道DOM 0 當然是比較舊的協定, 我們可以從以下的表格來看:

DOM1 協定:

 

Event Name

Description

onblur()

The element has lost focus (that is, it is not selected by the user).

onchange0

The element has either changed (such as by typing into a text field) or the element has lost focus.

onclick0

The mouse has been clicked on an element.

ondblclick()

The mouse has been double-clicked on an element.

onfocus()

The element has gotten focus.

onkeydown()

A keyboard key has been pressed down (as opposed to released) while the element has focus.

onkeypress()

A keyboard key has been pressed while the element has focus.

onkeyup()

A keyboard key has been released while the element has focus.

onload()

The element has loaded (document, frameset, or image).

onmousedown()

A mouse button has been pressed.

onmousemove()

The mouse has been moved.

onmouseout()

The mouse has been moved off of or away from an element.

onmouseover()

The mouse has moved over an element.

onmouseup()

A mouse button has been released.

onreset()

The form element has been reset, such as when a form reset button is pressed.

onresize()

The window’s size has been changed.

onselect()

The text of a form element has been selected.

onsubmit()

The form has been submitted.

onunload()

The document or frameset has been unloaded.

 
DOM2 的進化:

DOM 0 Event

DOM 2 Event

onblur()

blur

onfocus()

focus

onchange()

change

onmouseover()

mouseover

onmouseout()

mouseout

onmousemove()

mousemove

onmousedown()

mousedown

onmouseup()

mouseup

onclick()

click

ondblclick()

dblclick

onkeydown()

keydown

onkeyup()

keyup

onkeypress()

keypress

onsubmit()

submit

onload()

load

onunload()

unload

 新的DOM2 用法可以addEventListener()這個函數來觀察到:

addEventListener(event,function,capture/bubble);

參數event如上表所示, function是要執行的函數, capture與bubble分別是W3C制定得兩種時間模式,簡單來說capture就是從document的開始讀到最後一行, 再執行事件, 而bubble則是先尋找指定的位置再執行事件.
capture/bubble的參數是布林值, True表示用capture, False則是bubble.Windows Internet Explorer也有制定一種EventHandler, 是 attachEvent(), 格式如下:

window.attachEvent("submit",myFunction());

比較特別的是attachEvent不需要指定capture/bubble的參數, 因為在windows IE環境下都是使用Bubble的模式.這裡用圖像的Rollover例子來表現事件的用法:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Rollover</title>
<script type="text/javascript">function moveOver(imgObj) {
  if (typeof window.addEventListener != "undefined") {
  imgObj.addEventListener("mouseover",function(){imgObj.src = imgObj.id +
"_over.png";}, false);
  imgObj.addEventListener("mouseout", function(){imgObj.src = imgObj.id +
"_default.png";}, false);
  } else {
  imgObj.attachEvent("onmouseover",function(){imgObj.src = imgObj.id +
"_over.png";});
  imgObj.attachEvent("onmouseout", function(){imgObj.src = imgObj.id +
"_default.png";});
  }
}

function rollover() {
var images = document.getElementsByTagName("img");
var roll = new RegExp ("rollover");
var preload = [];
for (var i = 0; i < images.length; i++) {
  if (images[i].id.match(roll)) {
  preload[i] = new Image();
  preload[i].src = images[i].id + "_over.png";

  moveOver(images[i]);
  }
}
}
if (typeof window.addEventListener != "undefined") {
  window.addEventListener("load",rollover,false);
} else {
  window.attachEvent("onload",rollover)
}
</script>
</head>
<body>
<p><img id="rollover_home" name="img_home" src="rollover_home_default.png"
alt="Home"></p>
<p><img id="rollover_about" name="img_about" src="rollover_about_default.png"
alt="About"></p>
<p><img id="rollover_blog" name="img_blog" src="rollover_blog_default.png"
alt="Blog"></p>
<p><img id="logo" name="img_logo" src="logo.png" alt="Braingia Logo"></p>
</body>
</html>

上述的 typeof window.addEventListener != "undefined" 程式碼可以判斷使用者的瀏覽器是否支援AddEventListener這個事件模型, 如果不支援就使用attachEvent.

W3C 及 IE 同時支援移除指定的事件, 用途是移除設定的事件, 格式分別如下:

W3C格式:

removeEventListener(event,function,capture/bubble);

Windows IE的格式如下:

detachEvent(event,function);

資料參考: Chapter 14 – Browsers and JavaScript, JavaScript Step by Step, by Steve Suehring

一直以來Javascript的除錯都是非常煩人的步驟, 最近發現有個很棒的程式, 在這裡跟大家分享,

FireBug

這是Open Source軟體, 且完全免費, 是個搭配Firefox的Plugin, 它可以圖像化您的程式碼, 包括了HTML, CSS, 及javascript, 您可以通過它來觀看所有網頁, 不干擾您的瀏覽, 您也可以隨時把它關掉. 最棒的是它直接幫你把程式碼劃分好, 再除錯方面非常方便. 它佔的空間也很小喔~

更過詳情可參考: http://getfirebug.com/

最近在處理用戶電腦時候遇到了以下的問題, 後來找到方法解決了, 在這裡做個紀錄:

處理錯誤碼: 0x800C0133

發生原因可參考: http://www.binbin.net/messages/qa_win_oe/0104.htm

我的解決方式:

Outlook Express有個天生的缺點, 就是當某個資料夾超過2G時便會在收件時出現錯誤訊息, 要求你先壓縮郵件, 以釋放空間, 但我個人是相當不建議把郵件壓縮起來, 因為往往會造成日後開不到, 那你2G的信就不見了(哭~)

可是, 如果你不壓縮, "收件匣"又沒有辦法再接收新的郵件, 怎麼辦呢?

我的作法如下:

1.關閉Outlook Express.

2. 到以下路徑:

C:\Documents and Settings\Administrator\Local Settings\Application Data\Identities\{1936D57C-EA58-4C14-9A09-D10B5B2BFCF5}\Microsoft\Outlook Express

3. 你就看到跟你的Outlook Express裡資料夾相同的.dbx檔, 包括了收件匣.dbx, 刪除的郵件.dbx, 寄件備份.dbx等等. 我們現在要做的事情就是把超過2G的"收件匣.dbx" 命名成其他的名字, 如: "收件匣1.dbx".

4.再度打開Outlook Express, 你就會發現可以收信了! 而且收件匣這個資料夾裡面是空的. (囧….之前的信都去哪裡了?)

5. 不用擔心, 因為Outlook Express就是因為找不到原本的"收件匣.dbx", 就自作主張幫你建立了一個新的 "收件匣.dbx". 新的"收件匣.dbx"當然就是空的囉~

那我要怎麼拿回以前的信件?

6. 首先, 先在OutlookExpress的本機資料夾按右鍵, 選擇新增資料夾, 資料夾的名稱看你個人的喜好, 方便您辨識, 這裡舉例就叫做"2008″好了.

7. 新增 "2008″ 資料夾後, 因為裡面是空的, 在剛剛的目錄底下不會幫你產生 "2008.dbx", 所以我們隨便將"收件匣"裡面的一封信複製到"2008″資料夾裡面. 在檢查看看, 目錄底下出現了新的 "2008.dbx" 了! 酷吧~

8. 現在我們再把Outlook Express關掉.

9. 到

C:\Documents and Settings\Administrator\Local Settings\Application Data\Identities\{1936D57C-EA58-4C14-9A09-D10B5B2BFCF5}\Microsoft\Outlook Express

10. 我們現在要騙系統說2008.dbx就是我們之前命名的"收件匣1.dbx", 所以就把"2008.dbx"先刪掉, 再把"收件匣1.dbx"命名成 "2008.dbx".

11. 打開OutlookExpress, 你就會發現"2008″資料夾裡面多了很多信囉~這些信就是你之前2G爆掉的信啦~ 但值得提醒的是, Outlook Express 的資料夾極限大小是2G,所已表示這個2008資料夾很難在塞入更多的郵件, 建議您還是把它儘量分類出去, 保持在2G以下.

維持良好的刪信, 信件分類的習慣才是最好的解決方法喔 ^_^

希望可以幫助到大家.

Windows Powershell 1.0 是舍米碗糕?

如果你有常用Windows的cmd.exe你就會非常熟悉Windows Powershell 1.0,
只是它現在功能更強大, 能夠做更多的事情. (據說還可以跟Linux的指令功能不相上下)

微軟官網提到:

Windows PowerShell 是微軟為 Windows 環境所開發的 shell 及腳本語言技術,這項全新的技術提供了豐富的控制與自動化的系統管理能力;而「腳本語言」(scripting languages)則是用來編寫程式的電腦語言。腳本語言通常都有簡單、易學、易用的特性,目的就是希望能讓寫程式的人(開發者)快速完成程式的編寫工 作。

Powershell目前已內建在Windows Server 2008, 你也可以安裝在Windows Server 2003.

Windows PowerShell 可安裝於 Windows XP 以及之後的用戶端或伺服端 Windows 作業系統,包括:

用戶端:Windows XP、Windows XP Service Pack 1、Windows XP Service Pack 2、Windows Vista
伺服端:Windows Server 2003、Windows Server 2003 R2、Windows Server 2003 Service Pack 1

而 Windows PowerShell 除了有 32 位元版本,也還有 x64 和 ia64 等兩個 64 位元版本,可以安裝在這兩種 64 位元 Windows 平台。此外,由於執行 Windows PowerShell 需要 .NET Framework 2.0,因此請先替電腦安裝 .NET Framework 2.0。目前 Windows PowerShell 是為 RC1 階段,官方下載的網址請參閱文後(下載前需經過簡單的註冊手續)。下載回來的檔案是 ZIP 壓縮檔,只要解壓縮並執行副檔名為 .msi 的檔案即可安裝,安裝過程相當簡單,只要依照精靈指示即可順利完成。

他是免費下載的喔~ 如果你有志成為System Administrator, 那Powershell將會是你不能錯過的好幫手.

下載連結:

Documentation:

Cheers~

WIMP這個縮寫如果你到wikipedia 去查的話,

他會告訴你這是WIMP stands for "window, icon, menu, pointing device",

但我最近想到其實我一直習慣用WIMP,

就是 Windows Server 2003 + IIS + MYSQL + PHP,

雖然比起LAMP (Linux + Apache + MYSQL + PHP) 或 WAMP (Windows + Apache + MYSQL + PHP)組合來得遜色,

但使用快一年了也發現它的效能及功能都足夠我用了~

網上關於DEBUG WIMP的資訊其實也不多, 如果以後還發現甚麼再跟大家分享吧~

環境: Windows Server 2003 Enterprise

問題: PHP5 + MYSQL4+ IIS (找不到MYSQL模組)

解決方式: PHP4 + MYSQL4 + IIS

最近在Windows Server 2003灌PHP5 + MYSQL時頻頻遇到PHP讀不到MYSQL模組的問題,

花了不少時間去網上找解決方式, 試了都不成功, 至今原因仍不清楚,

但後來試了裝裝看PHP4的最新版本(不用PHP5), 再跑跑看,

MYSQL的模組就在PHPINFO()出現了! (記得要把php4ts.dll放在C:\Windows\system32\下)

這個文章應該對喜歡把PHP灌在WINDOWS 環境底下的人有用吧.
雖然是治標不治本的辦法(因為沒辦法用PHP5還滿懊惱的)

個人測試問題發生的背景如下:
環境: Windows Server 2003
先灌MYSQL 5.1 =>OK
再灌PHP4 =>OK
灌PHPMYADMIN =>設定Secret_blowfish OK=>跑的時候出現

Client does not support authentication protocol requested
by server; consider upgrading MySQL client

MYSQL官方的解決方式如下:

MySQL 5.0 uses an authentication protocol based on a password hashing algorithm that is incompatible with that used by older (pre-4.1) clients. If you upgrade the server from 4.0, attempts to connect to it with an older client may fail with the following message:

shell> mysql Client does not support authentication protocol requested by server; consider upgrading MySQL client

To solve this problem, you should use one of the following approaches:

  • Upgrade all client programs to use a 4.1.1 or newer client library.
  • When connecting to the server with a pre-4.1 client program, use an account that still has a pre-4.1-style password.
  • Reset the password to pre-4.1 style for each user that needs to use a pre-4.1 client program. This can be done using the SET PASSWORD statement and the OLD_PASSWORD() function:
    mysql> SET PASSWORD FOR
    -> 'some_user'@'some_host' = OLD_PASSWORD('newpwd');

    Alternatively, use UPDATE and FLUSH PRIVILEGES:

    mysql> UPDATE mysql.user SET Password = OLD_PASSWORD('newpwd')
    -> WHERE Host = 'some_host' AND User = 'some_user';
    mysql> FLUSH PRIVILEGES;

    Substitute the password you want to use for “newpwd” in the preceding examples. MySQL cannot tell you what the original password was, so you’ll need to pick a new one.

  • Tell the server to use the older password hashing algorithm:
    1. Start mysqld with the --old-passwords option.
    2. Assign an old-format password to each account that has had its password updated to the longer 4.1 format. You can identify these accounts with the following query:
      mysql> SELECT Host, User, Password FROM mysql.user
      -> WHERE LENGTH(Password) > 16;

      For each account record displayed by the query, use the Host and User values and assign a password using the OLD_PASSWORD() function and either SET PASSWORD or UPDATE, as described earlier.

Note

In older versions of PHP, the mysql extension does not support the authentication protocol in MySQL 4.1.1 and higher. This is true regardless of the PHP version being used. If you wish to use the mysql extension with MySQL 4.1 or newer, you may need to follow one of the options discussed above for configuring MySQL to work with old clients. The mysqli extension (stands for "MySQL, Improved"; added in PHP 5) is compatible with the improved password hashing employed in MySQL 4.1 and higher, and no special configuration of MySQL need be done to use this MySQL client library. For more information about the mysqli extension, see http://php.net/mysqli.

It may also be possible to compile the older mysql extension against the new MySQL client library. This is beyond the scope of this Manual; consult the PHP documentation for more information. You also be able to obtain assistance with these issues in our MySQL with PHP forum.

For additional background on password hashing and authentication, see Section 5.4.9, “Password Hashing as of MySQL 4.1”.

後來試了之後就可以RUN了, 如果各位也遇到這個情況不妨試試.

主要是針對不同的帳戶, 可能是版本的問題, 只要設定OLD_PASSWORD, 再FLUSH一次MYSQL應該就沒問題了.

原文可參考: http://dev.mysql.com/doc/refman/5.0/en/old-client.html

當我們要把一個MYSQL的資料庫輸出,
搬移到另一臺機器的MYSQL時,
如果是全英文的資料庫還好, 最怕的是遇到中文字編碼的問題.
如果欄位是VARCHAR的dataType, 搬移後用網頁顯示時會是" ??? "..
相信是因為big5跟UTF-8之間轉換所造成的問題.
我的解決方式是把相關的資料格式從VARCHAR 變成 BLOB.
中文字就能正常顯示了.

這樣做的缺點是資料格式若是BLOB則會減低效率,
而且用PHP函式對中文字作字串處理時會有問題.

僅供參考囉~