2009-12-22 14:40

CSS 部屬經驗-圖文列表樣式

樣式



HTML 結構

<ul class="Img2HList ClearIt">
<li class="List Odd">
<div class="Container">
<strong class="Title">
<a><span class="Image"><img src="圖片網址" /></span>標題文字</a>
</strong>

<!--其他相關資訊-->
<p class="Info">描述文字</p>
<div class="Meta">文字</div>
<blockquote>文字</blockquote>
</div>
</li>
<li class="List">
<div class="Container">
<strong class="Title">
<a><span class="Image"><img src="圖片網址" /></span>標題文字</a>
</strong>

<!--其他相關資訊-->
<p class="Info">描述文字</p>
<div class="Meta">文字</div>
<blockquote>文字</blockquote>
</div>
</li>
</ul>



CSS 設定

ul.Img2HList {
margin: 1em 0;
overflow: hidden;
}
ul.Img2HList li.List {
position:relative;
display: block;
float: left;
width: 49%;
margin: 0 0 30px 0;
font-size: 11px;
}
ul.Img2HList .Container {
padding: 0 0 0 79px;
}
ul.Img2HList li.Odd {
clear: left;
}
ul.Img2HList li.Odd .Container{
margin-right: 30px;
}
ul.Img2HList strong.Title {
display: block;
font-size:1.1em;
border-bottom: 1px solid #ccc;
}
ul.Img2HList strong.Title span.Image {
float: left;
margin: 0 0 0 -79px;
cursor: pointer;
}



參考頁面:
Last.fm
Wacanai.com
2009-12-22 09:12

HTML 與 CSS 觀念上的區別

HTML:在定義網頁的 結構語意
  • h1:第一標題
  • h2:第二標題
  • p:段落
  • li:清單條目
  • em:強調
  • strong:更強調
  • blockquote:引言

CSS:在定義網頁的呈現 樣式
  • color:文字顏色
  • text:文字
  • font:字體
  • margin:邊界距離
  • padding:內緣距離
  • background:背景底色
2009-12-21 15:11

Blogger 文章匯入的格式

Blogger 可以接受 Atom 的格式匯入
至於 RSS 的格式就要去找轉換器轉成 Atom 才可以匯入

以下是 Blogeer 匯入時的最簡化的格式

<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet
href="http://www.blogger.com/styles/atom.css"
type="text/css"?
>
<feed xmlns='http://www.w3.org/2005/Atom'
xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'
xmlns:georss='http://www.georss.org/georss'
>
<id>tag:blogger.com,1999:blog-4</id>
<generator version='7.00' uri='http://www.blogger.com'>Blogger</generator>

<entry>
<id>tag:blogger.com,1999:blog-4.post-2</id>
<published>2009-12-19T23:39:20.281+08:00</published>
<title type='text'>標題</title>
<content type='html'>文章內容</content>
<category scheme='http://www.blogger.com/atom/ns#' term='標籤1'/>
<category scheme='http://www.blogger.com/atom/ns#' term='標籤2'/>
</entry>

<entry>
<id>tag:blogger.com,1999:blog-4.post-2</id>
<published>2009-12-19T23:39:20.281+08:00</published>
<title type='text'>標題</title>
<content type='html'>文章內容</content>
<category scheme='http://www.blogger.com/atom/ns#' term='標籤1'/>
<category scheme='http://www.blogger.com/atom/ns#' term='標籤2'/>
</entry>

</feed>
  • generator:產生器識別,Blogger 只接受自己的標示
  • id:可以重複,但必須符合格式
  • published:發佈時間,格式為 ISO8601
  • title:文章標題
  • content:文章內文,可以允許換行符號"\n",內文的 HTML 必須實體逸出
  • category:標籤
2009-12-18 16:50

[HTML] 規劃延生屬性

之前在玩 Firefox 的外掛時,在 XUL 的定義中學到其他屬性設定,當中有些定義還蠻常用到的
如:empty, emptytext, max, min...等

這裡我只是要說明一個簡化開發的 solution,並沒有完整的應用規劃,為了瞭解這個 solution 可以先看看一個簡單的範例 html_extension.zip

其實最近看到 HTML5 已經將很多常見的介面應用加入定義中,但還是可以將系統架構中常用的功能做成延伸屬性,在 HTML5 普及之前這是一個很好的 solution。


在之前的專案中,我做了一下的規劃:
element [延伸屬性]{所有元素共用}
removeDelay="sec" {設定幾秒鐘後自動[移除]此元素}
pulsate="sec" {設定幾秒鐘後自動結束元素[閃爍]}

input,textarea [延伸屬性]
emptyText="為空預設提示" {設定當輸入匡為空時的文字提示}

form > tr [延伸樣式]
class="NotNull" {檢查區塊內的元素是否有選項值}

form > input [延伸屬性]
format="" {表單送出前的格式檢查,但不會檢查是否為空}
  • 'tel':電話
  • 'mobile':行動電話
  • 'email':電子信箱
  • 'url':網路連結
jtype="" {資料輸入時的輔助}
(基本格式輸入)
  • 'uint':無符號整數
  • 'int':整數
  • 'float':浮點數
  • 'id':帳號格式
  • 'alnum':保留字母和数字及底線

(輔助日期輸入)
  • 'date':選擇日期
  • 'start_date':選擇起始日期
  • 'end_date':選擇結束日期

(輔助時間輸入)
  • 'time':選擇時間
  • 'start_time':選擇起始時間
  • 'end_time':選擇結束時間


在下面的 HTML 中可以看到程式碼都便得很簡單

<!--動態效果-->
<div pulsate="4">4秒閃爍</div>
<div removeDelay="10">10秒後消失</div>
<div pulsate="5" removeDelay="8">5秒閃爍&8秒後消失</div>


<!--表單-->
<form class="FormWidget" method="post" action="">
<table class="FormList" border="0">
<caption>輸入限制</caption>

<tr class="NotNull">
<th><label for="data_1">無符號整數 :</label></th>
<td><input type="text" jtype="uint" value="" class="Int" id="data_1" name="data_1"/></td>
</tr>

<tr class="NotNull">
<th><label for="data_2">整數 :</label></th>
<td><input type="text" jtype="int" value="" class="Int" id="data_2" name="data_2"/></td>
</tr>

<tr class="NotNull">
<th><label for="data_3">浮點數 :</label></th>
<td><input type="text" jtype="float" value="" class="Int" id="data_3" name="data_3"/></td>
</tr>

<tr>
<th><label for="data_4">帳號格式 :</label></th>
<td><input type="text" jtype="id" value="" class="Text" id="data_4" name="data_4" emptyText="請輸入帳號"/></td>
</tr>

<tr class="NotNull">
<th><label for="data_5">英數及底線 :</label></th>
<td><input type="text" jtype="" value="" class="Text" id="data_5" name="data_5"/></td>
</tr>
</table>


<table class="FormList" border="0">
<caption>時間 & 日期</caption>

<tr>
<th><label for="data_6">日期 :</label></th>
<td><input type="text" jtype="date" value="" id="data_6" name="data_6"/></td>
</tr>

<tr>
<th><label>日期區間 :</label></th>
<td>
<div class="OptionBar">
<label>起始<input type="text" jtype="start_date" value="" class="Text" name="start_date"/></label>
-
<label>結束<input type="text" jtype="end_date" value="" class="Text" name="end_date"/></label>
</div>
</td>
</tr>

<tr>
<th><label for="data_7">時間 :</label></th>
<td><input type="text" jtype="time" value="" id="data_7" name="data_7"/></td>
</tr>

<tr>
<th><label>時間區間 :</label></th>
<td>
<div class="OptionBar">
<label>起始<input type="text" jtype="start_time" value="" name="start_time"/></label>
-
<label>結束<input type="text" jtype="end_time" value="sdsfsdf" name="end_time"/></label>
</div>
</td>
</tr>
</table>


<table class="FormList" border="0">
<caption>格式檢查</caption>

<tr>
<th><label for="data_8">電話格式 :</label></th>
<td><input type="text" format="tel" value="" class="Text" id="data_8" name="data_8"/></td>
</tr>

<tr class="NotNull">
<th><label for="data_9">行動電話格式 :</label></th>
<td><input type="text" format="mobile" value="0912345678" class="Text" id="data_9" name="data_9"/></td>
</tr>

<tr class="NotNull">
<th><label for="data_10">E-mail 格式 :</label></th>
<td><input type="text" format="email" value="" class="Text" id="data_10" name="data_10"/></td>
</tr>

<tr>
<th><label for="data_11">連結格式 :</label></th>
<td><input type="text" format="url" value="" class="Text" id="data_11" name="data_11"/></td>
</tr>
</table>

<div class="Buttons">
<input type="submit" class="Button" value="儲存"/>
</div>
</form>
2009-11-25 16:00

[PHP] 取得 Google Analytics 的統計資料

這裡我使用GAPI(google-analytics-php-interface)這個工具來取得 Google Analytics 的統計資料

如果不想使用這個工具取得資料,Google Analytics 也有 Protocol 的連接教學 Data Export API - Protocol

在取得資料的過程中,我在一個觀念上問題花了不少時間,主要是下面這兩個參數上的設定:
  • dimensions : 特性類似 SQL 的 GROUP BY
  • metrics : 類似 SQL SELECT 的資料欄位

其他的資料欄位:Dimensions & Metrics Reference


工具的連結範例:
<?php
require_once('gapi.class.php');

/*建立與帳戶的連結*/
$ga = new gapi('email@yourdomain.com','password');


/*取得統計報告*/
$ga->requestReportData(
    145141242,
    array('browser','browserVersion'),
    array('pageviews','visits')
);

foreach($ga->getResults() as $result){
    echo $result;
    echo 'Pageviews:',$result->getPageviews();
    echo 'Visits:',$result->getVisits();
}

echo 'Total pageviews:',$ga->getPageviews(); 
echo 'total visits:',$ga->getVisits();



函數的參數說明:
<?php
requestReportData(
    $report_id,
    $dimensions,
    $metrics,
    $sort_metric=null,
    $filter=null,
    $start_date=null,
    $end_date=null,
    $start_index=1,
    $max_results=30
)

屬性型態描述範例
$report_idString統計報告的ID1892302
$dimensionsArray尺寸欄位,類似 SQL 的群組array('browser')
$metricsArray結果欄位,類似 SQL 的顯示欄位array('pageviews')
$sort_metricArray(選擇性)資料排序依據,"visits" 為 ASC,"-visits" 為 DESCarray('-visits')
$filterString(選擇性)過濾的邏輯條件 
$start_dateString(選擇性)報告的起始時間'YYYY-MM-DD''2009-04-30'
$end_dateString(選擇性)報告的起始時間'YYYY-MM-DD''2009-06-30'
$start_indexInt(選擇性)資料的起始指標1
$max_resultsInt(選擇性)資料的起始指標.最大 1000 筆30
2009-11-24 22:03

今天終於見識到了

今天去一家公司面試
見到一個令我驚訝的事

那就是用 JavaScript 寫 application
整個架構都是 Object-Oriented
光這點還不足已驚訝
架構上幾乎是跟 Java 的 Swing 差不多
所有的 HTML 都是 Object 再控制
整體的顯示效果跟 flash 差不多
真是給他妙的說

不過聽 engineer 說有一個嚴重問題
就是 memory 會用掉 500 Mbyte
engineer 是想利用回收 Object 的方式來減少 memory 的用量
但至於要如何減少 memory 的用量
還真是個大問題

雖然方法很多
但要不影響當前的架構去處理
能用的方法就很有限了
2009-11-04 15:54

[PHP] 利用檔案作資料快取

當沒辦法架設好用的快取機制時
又想利用快取的方式降低 DB 負荷時
不妨使用檔案的方式處理

這裡使用 serialize() 這個函數將變數轉成字串
然後存到文件裡做快取存放
這個函數跟 $_SEEION 用的是一樣的函數

<?php
class Cache {
private static $_savePath = '.';
private static $_cached = true;

/**初始化
* @param string $savePath 暫存檔的存放路徑
* @param bool $cached 是否啟用暫存,這個設定可以快速關閉所有暫存的使用
*/
public static function start($savePath='.', $cached=true ) {
self::$_savePath = $savePath.'/';
self::$_cached = (bool)$cached;
}


/**取得暫存資料
* @param string $index 暫存檔的名稱
* @return var 所暫存的資料,當暫存不存在時回傳 null
*/
public static function load($index) {
if(!self::$_cached){ return null; }

$filePath = self::$_savePath.$index.'.cache';
if(file_exists($filePath)){
$value = file_get_contents($filePath);
return unserialize($value);

}else{
return null;
}
}


/**儲存暫存資料
* @param string $index 暫存檔的名稱
* @param var $value 需要暫存的資料
*/
public static function save($index, $value) {
$filePath = self::$_savePath.$index.'.cache';
$value = serialize($value);

try {
file_put_contents($filePath ,$value);
} catch (Exception $e) {
/*檔案讀取失敗*/
throw $e;
}
}

/**清除暫存資料
* @param string $index 暫存檔的名稱,當設定為 null 時清除所有 Cache
*/
public static function remove($index=null) {
/*清除所有 Cache*/
if($index===null){
$dir = opendir(self::$_savePath);
while (false !== ($fileName = readdir($dir))) {
if(strpos($fileName,'.cache')===false) {
continue;
}elseif(file_exists($filePath = self::$_savePath.$fileName)){
unlink($filePath);
}
}
closedir($dir);


/*清除指定 Cache*/
}elseif(file_exists($filePath = self::$_savePath.$index.'.cache')){
unlink($filePath);
}
}
}


使用範例:

<?php
/**(初始化)變數快取類別,設定存放的目錄*/
Cache::start('/www/cache');


if(!$sysSetting = Cache::load('sysSetting')){
/*取得資料*/
$sysSetting = $dbAdapter->query("
SELECT `Group`, `Name`, `Value`
FROM `system_setting`
")->fetchAll();


/*快取資料*/
Cache::save('sysSetting', $sysSetting);
}
2009-11-01 16:14

[PHP] 繼承改寫 PDO

根據過去對 PDO 的使用習慣
我從新改寫跟簡化一些函數
基本上跟原本的沒有差太多

物件宣告:

<?php

/*改寫資料連結物件*/
class DB extends PDO {

/* 預設的資料取得格式 */
protected static $_fetch_mode = self :: FETCH_ASSOC;

/**
* @param array $conf
* [host] = "localhost"
* [username] = "root"
* [password] = "1111"
* [dbname] = "test"
* [init] = "SET NAMES 'utf8'; SET group_concat_max_len=65536;"
*
* @return class
*/
public function __construct(array $conf){
parent :: __construct(
'mysql:host='.$conf['host'].';dbname='.$conf['dbname'],
$conf['username'],
$conf['password']
);

/* MySQL 前置設定 */
foreach($conf['init'] as $query){
parent :: exec($query);
}

/*以例外方式處理錯誤*/
$this->setAttribute(
self :: ATTR_ERRMODE,
self :: ERRMODE_EXCEPTION
);

/*改寫資料流物件*/
$this->setAttribute(
self :: ATTR_STATEMENT_CLASS,
array ('DBStatement',array (
$this
)
));
}


/**===============================================================**/
/* 將字串加入引號及反斜線 */
public function quote($var = null){
if(is_array($var)){
foreach ($var as $key => $value) {
$var[$key] = parent :: quote($value);
}
return join(',', $var);

}elseif($var === null){
return 'NULL';
}else{
return parent :: quote($var);
}
}

/* 將 $query 字串與陣列做變數合併 */
public function bind($query, array $bind = array ()){
foreach($bind as $key => $value){
if ($key[0] == '/' && $key[1] == '*') {
continue;
}

$bind[$key] = $this->quote($value);
}

return strtr($query, $bind);
}


/**===============================================================**/
/*重新封裝 exec*/
public function exec($query, array $bind = array ()){
$query = $this->bind($query, $bind);

$stmt = parent :: query($query);
$rowCount = $stmt->rowCount();
$stmt->closeCursor();
$stmt = null;
return $rowCount;
}

/*重新封裝 query*/
public function query($query, array $bind = array ()){
$query = $this->bind($query, $bind);

$stmt = parent :: query($query);
$stmt->setFetchMode(self :: $_fetch_mode);
return $stmt;
}

/*針對僅取得筆數時的便利函數*/
public function queryCount($query, array $bind = array ()){
$query = $this->bind($query, $bind);
$query = sprintf('SELECT COUNT(*) FROM (%s)AS QUERYCOUNT', $query);

$stmt = parent :: query($query);
$rowCount = $stmt->fetchColumn();
$stmt->closeCursor();
$stmt = null;
return $rowCount;

}

}


/*改寫資料流物件*/
class DBStatement extends PDOStatement{
public $dbh;

protected function __construct($dbh){
$this->dbh = $dbh;
}
}


對於資料的操作跟原本的事一樣的
但我習慣將 fetch_mode 設定為 FETCH_ASSOC

使用用範例:

<?php
/* 資料庫連結參數 */
$conf = array(
'host' => "localhost",
'username' => "root",
'password' => "1111",
'dbname' => "test_db",
'init' => "SET NAMES 'utf8'; SET group_concat_max_len=65536;"
);

/* 初始化資料庫連結介面 */
$dbAdapter = new DB($conf);




/*exec 操作*/
$bind = array();
$bind['/*prefix*/'] = 'mw_';/*資料表前綴*/
$bind[':title'] = '文章標題';
$bind[':content'] = '文章內容';

try {
$dbAdapter->exec("
INSERT INTO `/*prefix*/article`
SET `Title` = :title,
`Content` = :content,
`ModifyTime` = NOW()
", $bind);

echo "成功新增";

/*錯誤處理*/
} catch (Exception $e) {
switch ($e->getCode()) {
case 23000:
echo "主鍵重複"; break;

default:
echo "新增失敗"; break;
}

}


/*query 操作*/
$bind = array();
$bind['/*prefix*/'] = 'mw_';/*資料表前綴*/
$bind[':id'] = array('1','2','4');

$data = $dbAdapter->query("
SELECT `Id`, `Title`, `Content`
FROM `/*prefix*/article`
WHERE `Id` IN(:id)
", $bind)->fetchAll();

var_dump($data);


/*queryCount 單只要取得查詢的筆數時*/
$bind = array();
$bind['/*prefix*/'] = 'mw_';/*資料表前綴*/
$bind[':id'] = array('1','2','4');

$count = $dbAdapter->queryCount("
SELECT `Id`, `Title`, `Content`
FROM `/*prefix*/article`
WHERE `Id` IN(:id)
", $bind);

echo $count;


/*bind 取得查詢的 Query 字串*/
$bind = array();
$bind['/*prefix*/'] = 'mw_';/*資料表前綴*/
$bind[':id'] = array('1','2','4');

$query_string = $dbAdapter->bind("
SELECT `Id`, `Title`, `Content`
FROM `/*prefix*/article`
WHERE `Id` IN(:id)
", $bind);

echo $query_string;
2009-11-01 15:18

[PHP] 好用的 HTML 解析工具

PHP Simple HTML DOM Parser Manual

之前為了解析 HTML 所找到的工具
這是 S.C. Chen 所製作的工具
作者文章:PHP Simple HTML DOM Parser 強力解析html工具
檔案下載:PHP Simple HTML DOM Parser

具有以下特點:
  1. 只支援PHP5以上
  2. 可以分析不嚴謹(invalid)的HTML.
  3. 支援簡單的 CSS Selector.
  4. 簡單的DOM操作
  5. 會維持HTML中的原始格式.


對於可以支援 CSS Selector 就夠方便了
幾本上函數操作跟 JavaScript 差不多
使用起來的確蠻方便的

不過在實際使用後發現對於不嚴謹 HTML 的解析會有意想不到的問題出現,由於元素的結束點判斷不正確而出現遞迴效應,造成大量使用記憶體空間,最好還是避免解析不嚴謹 HTML。


使用範例:
<?php
// 示範如何讀取HTML元素
require_once("simple_html_dom.php");

// 產生DOM物件
$dom = file_get_dom('http://www.google.com/');

// 找出所有網頁連結
$result = $dom->find('a');
foreach($result as $v) {
    echo $v->href;
}

// 找出所有網頁圖片
$result = $dom->find('img');
foreach($result as $v) {
    echo $v->src;
}

// 找出所有網頁中所有id=gbar的div標籤
$result = $dom->find('div#gbar');
foreach($result as $v) {
    echo $v->innertext;
}

// 找出所有網頁中所有calss=gb1的span 標籤
$result = $dom->find('span.gb1');
foreach($result as $v) {
    echo $v->outertext;
}

// 找出所有網頁中所有align=center的'td標籤
$result = $dom->find('td[align=center]');
foreach($result as $v) {
    echo $v->outertext;
}

2009-10-21 17:40

[PHP] 利用 strtr() 做變數(樣版)置換

以前在處理 SQL 指令時都是使用 sprintf() 去做變數替換,但常常會遇到兩個問題。
  1. 先後順序固定缺乏彈性,尤其在多語處理的時候
  2. 變數定義缺乏語意(%s),在維護時難以閱讀不直覺


後來找到 strtr() 這個函數可以執行多個字串的取代,在變數替換時蠻方便的,可以有效的克服上面的問題,當然根據使用上的需求最好還是包裝一下。
<?php
$query = "
    INSERT INTO `system_uesr` 
    SET `Id` = :id,
        `Name` = :name
";

$bind = array(
    ":id" => "'1'", 
    ":name" => "'jax'"
);


echo strtr($query, $bind);
// 結果:
//    INSERT INTO `system_uesr` 
//    SET `Id` = '1',
//        `Name` = 'jax' 



參考文章:
PHP: strtr - Manual
PHP strtr() 函数
strtr --- 轉換某些字元
2009-07-24 05:05

CSS 部屬經驗-表格樣式

為了 IE6 的相容這裡我不會用太新穎的選擇器,希望有一天 IE6 的使用群可以消失,這樣在排版時可以不去顧慮 IE6 的問題。

主旨:
  1. 如何規劃一個表格樣式
  2. HTML 結構
  3. CSS 設定

如何規劃一個表格樣式
網路上其實已經有很多表格樣式可以參考了,但除了表格樣式外,欄位的屬性很重要。

利用 class 去作欄位定義,讓每一欄都有不一樣的成員名稱,就算有些欄位根本不需要定義樣式,但建議最好還是保留名稱的設定,也許有一天會去用到,這樣之後要作欄位調整時才不用大興土木,去為每個樣版裡改表格樣式。

在 HTML 的規劃上最好用一個 <div></div> 包起來,再處理邊界上的設定時才不會因為瀏覽器的差異造成問題。



這裡我用到 hover 的方式去處理滑鼠滑過的效果,對於 IE6 的處理方式請看利用 JavaScript 讓 IE6 支援 CSS 2.0 hover 的方法

對於表格在之前有遇過一個奇怪的狀況,就是在設有 white-space:nowrap; 的欄位上寬度只能用 % 去定義,在 (IE6) white-space 在表格中怪問題 有說明。




HTML 結構

<div class="TableList">
<table cellspacing="0" cellpadding="0">
<tr>
<th class="Image">Picture</th>
<th class="Title">Title</th>
<th class="Date">Date</th>
</tr>

<tr class="Odd">
<td class="Image"><!--圖片--></td>
<td class="Title"><!--文字--></td>
<td class="Date"><!--日期--></td>
</tr>
<tr class="Even">
<td class="Image"><!--圖片--></td>
<td class="Title"><!--文字--></td>
<td class="Date"><!--日期--></td>
</tr>
<tr class="Odd">
<td class="Image"><!--圖片--></td>
<td class="Title"><!--文字--></td>
<td class="Date"><!--日期--></td>
</tr>
<tr class="Even">
<td class="Image"><!--圖片--></td>
<td class="Title"><!--文字--></td>
<td class="Date"><!--日期--></td>
</tr>
</table>
</div>



CSS 設定

/*=( 表格列表樣式 )=*/
.TableList {
text-align:center;
padding:1em;
}
.TableList table{
border-collapse:collapse;
font-size:0.9em;
width:100%;
text-align:center;
}


/*欄位間距*/
.TableList th,
.TableList td{
padding:.5em;
}


/*標題列*/
.TableList th{
border:1px solid #fff;
white-space:nowrap;
background:#328aa4 url(tr_bg1.gif) repeat-x;
color:#fff;
}
.TableList th a{color:#fff;}


/*單列底線樣式*/
.TableList tr{
border-bottom:1px solid #fff;
_behavior: url(ie_hover.htc);/*IE6 hover*/
}
/*奇數列底色樣式*/
.TableList tr.Odd {background:#FFF;}
/*偶數列底色樣式*/
.TableList tr.Even {background:#eee;}


/*hover 樣式*/
.TableList tr.hover td,
.TableList tr:hover td{
background:#e5f1f4;
}


/*=( 欄位設定 )=*/
/*圖片*/
.TableList th.Image,
.TableList td.Image{
width:50px;
}
.TableList td.Image img{
width:30px;
height:30px;
}

/*標題*/
.TableList td.Title{
text-align:left;
font-size:14px;
}

/*日期*/
.TableList td.Date{
width:3%;
white-space:nowrap;
}



參考頁面:
Last.fm
Wacanai.com
2009-07-24 04:00

CSS 部屬經驗-表單樣式

為了 IE6 的相容這裡我不會用太新穎的選擇器,希望有一天 IE6 的使用群可以消失,這樣在排版時可以不去顧慮 IE6 的問題。

主旨:
  1. 為什麼要用<table>作表單排版
  2. HTML 結構
  3. CSS 設定


為什麼要用<table>作表單排版
下面是利用 <table> 的排版方式,雖在排版上我非常不喜歡用 <table>,但在使用很多種排版方式及撰寫 JavaScript 的使用者介面輔助後,將 <table> 用在表單上可以有比較好的樣式結構,而且在 JavaScript 的輔助開發上對版面的操作也比較不會造成跑版問題。

如果有過在表單上做過很複雜的 JavaScript 介面輔助後,你一定會瞭解我在說什麼。


實際頁面 Wacanai.com


HTML 結構

<table class="FormList" border="0" cellspacing="0" cellpadding="0">
<tr class="NotNull">
<th><label for="name">欄位名稱</label></th>
<td>
<input class="Full" type="text" value="" id="name" name="name"/>
<small class="Explain">欄位說明</small>
<div class="Error">錯誤訊息</div>
</td>
</tr>

<tr class="NotNull">
<th><label for="email">欄位名稱</label></th>
<td>
<input class="Full" type="text" value="" id="name" name="name"/>
<span class="Error">錯誤訊息</span>
<small class="Explain">欄位說明</small>
</td>
</tr>
</table>

在結構我設置了 JavaScript 會用到的訊息樣式,在下面的 CSS 設定中會先將這些訊息隱藏,之後在用 JavaScript 去處理顯示的動作,這樣的好處是 JavaScript 可以用很簡單的方法做到很複雜的介面輔助。


CSS 設定

/*讓表格寬度撐開*/
table.FormList{
width:100%;
}

/*基本的間距設定*/
table.FormList th,
table.FormList td{
padding:6px 10px 6px 4px;
}
table.FormList th{
width:25%;
text-align: right;
vertical-align:top;
font-weight:normal;
white-space:nowrap;
}

/* 必填項樣式 */
table.FormList tr.NotNull th label{
padding-left:20px;
}

/* 欄位寬度設定 */
table.FormList .Full{
width:95%;
}
table.FormList .Verify{
width:40px;
}

/*標示說明文的樣式*/
table.FormList small.Explain {
display: block;
font-size: 0.8em;
margin: 0 0 5px 0;
padding: 1px 3px;
}


/*錯誤訊息的樣式*/
table.FormList div.Error ,
table.FormList span.Error {
color: #f00;
display: none;
font-size: 1.2em;
font-weight: bold;
}
/*警示訊息的樣式*/
table.FormList div.Warning ,
table.FormList span.Warning {
color: #00f;
display: none;
font-size: 1.2em;
font-weight: bold;
}

/*套用在整列的錯誤樣式*/
table.FormList tr.Error label{
color: #F00;
}
table.FormList tr.Error textarea,
table.FormList tr.Error select,
table.FormList tr.Error input{
border: 1px solid #F00;
}



參考頁面:
Last.fm
Wacanai.com
2009-07-24 02:43

CSS 部屬經驗-按鈕樣式

為了 IE6 的相容這裡我不會用太新穎的選擇器,希望有一天 IE6 的使用群可以消失,這樣在排版時可以不去顧慮 IE6 的問題。

主旨:
  1. 用 <a></a> 元素來作按鈕
  2. 利用原有樣式建立延伸樣式
  3. 套用在 <input> 的樣式

用 <a></a> 元素來作按鈕
連結元素的優點救是 IE6 有支援 hover 偽類,所以使用連結元素用在按鈕上可以用簡單的 CSS 做出點選效果。

當然在 CSS2 上面還有很多樣式上的選擇器,對於美工或使用者介面都有很方便的 CSS 設定,不用為了一點小東西去寫 JavaScript,總結就是 IE6 趕快消失吧!


利用原有樣式建立延伸樣式



在上面的三個按鈕樣式中可以發現只有底圖上的差異,所以在樣式上的規劃可以利用延伸複寫的方式去建立樣式。

首先我先看看這三個按鈕的 HTML 結構:

<a class="Button">
<span>按鈕文字</span>
</a>

<a class="Button AddButton">
<span>按鈕文字</span>
</a>

<a class="Button TagButton">
<span>按鈕文字</span>
</a>

可以發現在 class 上的套用上是有層級的,藉由樣式複寫的方式去延伸原有的樣式。


現在我們來看看 CSS 的設定:

/* 按鈕樣式 */
a.Button {
/*針對 Mozilla 系列瀏覽器的 inline-block*/
display: -moz-inline-box;

display: inline-block;
color: #fff;
text-decoration: none;
text-align: right;
vertical-align: middle;
cursor: pointer;
text-shadow: #163551 0 -1px 1px;

height: 23px;
background: #163551 url(button_right.png) no-repeat right top;
font-size: 11px;
padding: 0 3px 0 0;
}
a.Button strong,
a.Button span{
/*針對 Mozilla 系列瀏覽器的 inline-block*/
display: -moz-inline-box;

display: inline-block;
vertical-align: top;

height: 19px;
padding: 2px 5px 2px 8px;
background: #16517d url(button_left.png) no-repeat left top;
line-height: 19px;
}


/* 按鈕的 hover 效果設定,變換底圖定位及文字顏色 */
a.Button:hover,
a.Button:hover {
background-position: right bottom;
color: #fff;
text-decoration: none;
}
a.Button:hover span,
a.Button:hover strong {
background-position: left bottom;
color: #fff;
text-decoration: none;
}


/* 延伸的按鈕樣式 (AddButton)*/
a.AddButton span,
a.AddButton strong {
padding-left:25px;
color:#003366;
background: #2a2a2a url(button_add_left.png) no-repeat left top;
}

基礎樣式所用到的圖片:

botton_left.png


button_right.png


接著是延伸樣式所用到的圖片:

button_add_left.png


如果還要延伸其他樣式只要改改顏色或圖示就可以了。
上面的 CSS 有用到在 CSS 部屬經驗-樣式命名 提到的限制樣式對象的使用方式,這樣的選擇器設定只能讓樣式套用在連結元素上,這樣的好處是讓樣式與元素有一個關連性。

套用在 <input/> 的樣式
已經為連結元素建立美美的按鈕了,總不能讓 <input/> 這樣醜醜的見人吧!
CSS 樣式:

input.Button {
background: #9b9b9b url(button_bg.png) left top repeat-x;
border: 1px solid #ccc;
border-color: #999 #858585 #666 #858585;
color: #fff;
cursor: pointer;
cursor:hand;
font-size: 11px;
font-weight: bold;
line-height: 16px;
padding: 0 4px;
text-decoration: none;
text-shadow: #9b9b9b 0 -1px 1px;
vertical-align: middle;
vertical-align: baseline;

/*各瀏覽器的圓角設定,這裡捨棄對 IE6 的支援*/
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
-khtml-border-radius: 2px;
}

所用到的圖片:

button_bg.png


這裡我也使用相同的 class 名稱,但在限制樣式對象的作用下這兩個樣式是不會互相衝突的。

參考頁面:
Last.fm
Wacanai.com
2009-07-23 23:46

CSS 部屬經驗-容器樣式

為了 IE6 的相容這裡我不會用太新穎的選擇器,希望有一天 IE6 的使用群可以消失,這樣在排版時可以不去顧慮 IE6 的問題。

主旨:
  1. 容器樣式的概念
  2. 容器樣式定義
  3. 建構一個容器


容器樣式的概念


我們會發現在上面這三個樣式裡外匡是一樣的,除了顏色上的差異,而這些外匡的 HTML 結構也是一樣的,我稱這樣的外匡為容器,主要只提供樣式的框架,不處理資料的呈現。

將容器與樣式分離的好處是版面的呈現變靈活了,讓排版就像堆積木一樣,而樣式的重複利用性也會變高,樣式定義的複雜度也會降低。


上面這張圖就是容器的架構概念,在容器裡放入資料呈現的樣式,再將容器加入頁面排版裡。


容器樣式定義
如果已經瞭解什麼是容器了,接著要開始為容器的定義作一些規範:
  1. 不處理資料的呈現,例如資料的列表。
  2. 容器裡不可以在包含容器,過份的疊加套用會讓整體的架構變的很亂,所以讓容器間的關係保持平等是比較好的。
  3. 不要設定太多會繼承的樣式屬性,這樣會讓包在裡面的樣式要額外設定一些複寫的樣式屬性,例如字體顏色、對齊方式等。
  4. 不要為容器設定高度與寬度的屬性,高度應該要隨著內容而變動,寬度則應該適應版面的大小,這樣才不容易出現跑版的異常問題。


建構一個容器
針對上面的樣式來建構容器的 HTML,當然不一定照著一樣的方式建立,依照容器樣式的需求去建立就行了。

這裡會發現我之前在 CSS 部屬經驗-樣式命名 中提到的樣式成員名稱,這裡我還為每個樣式成員都加上了 "Area" 這個名稱前綴,以避免選擇意外套用到不該套用的元素上。

<div class="AreaBox_1">
<h3 class="AreaTitle">標題文字</h3>
<div class="AreaContent">
<!--
其他樣式元素...
-->
</div>
<div class="AreaBottom">
<div></div>
</div>
</div>


這裡可以看出 CSS 的選擇器的層級最多只有三層,如果樣式的層級太深以後要接手的人會很難進入狀況,層級太淺樣式又會很沒結構感,造成樣式很零散,兩層到三層之間的選擇器設定是比較好維護的。

關於容器的樣式設定我並沒有設定的很完整,請自由發揮吧!

.AreaBox_1 {
/*右上角的底圖*/
background:transparent url(../images/xxxx.gif) no-repeat right top;
/*上下的間距*/
margin:5px auto;
}
.AreaBox_1 .AreaTitle{
/*左上角的底圖*/
background:transparent url(../images/xxxx.gif) no-repeat left top;
/*標題設定*/
color:#585E1A;
font-size:16px;
padding:10px 0 14px 35px;
}
.AreaBox_1 .AreaContent{
/*中間的底圖*/
background:transparent url(../images/xxxx.gif) repeat-y left center;
padding:0 12px;
}
.AreaBox_1 .AreaBottom{
/*右下角的底圖*/
background:transparent url(../images/xxxx.gif) repeat-y right top;
}
.AreaBox_1 .AreaBottom div{
/*左下角的底圖*/
background:transparent url(../images/xxxx.gif) repeat-y left top;
height:10px;
}



參考頁面:
Last.fm
Wacanai.com
2009-07-22 20:42

CSS 部屬經驗-頁面排版

為了 IE6 的相容這裡我不會用太新穎的選擇器,希望有一天 IE6 的使用群可以消失,這樣在排版時可以不去顧慮 IE6 的問題。

主旨:
  1. 分析版面架構
  2. 定義所需要的排版區域
  3. 為需要設置寬度的區域增加外匡
  4. 建立 HTML 架構
  5. CSS 排版設定


如何分析版面架構
一般網頁架構都差不多,大部分都是由幾個主要的區域建構而成,只是在部屬上有些差異而已。

在下面幾個網頁排版中我們可以發現,除了兩欄或三籃的差異外,基本上整體的頁面部屬是一樣的。

天然の屋


TERRANOVA 朵拉大地


Jamboree購物網


定義所需要的排版區域
根據上面第一個版型,可以分析出以下的版面架構,要部屬這樣的架構其實不難,依照一個很直覺的方式去部屬就可以了。



為需要設置寬度的區域增加外匡
在之前的文章 寬度(width)不要與其他屬性同時設定[CSS] 有提到寬度定義的手則,所以接著要為具有寬度定義的區域增加外匡,然後在外匡上設定寬度的大小。

不管是排版或是樣式定義,除非必要的樣式,其餘請不要設置高度與寬度的樣式屬性,頁面是會隨著內容而變動的,愈是增加不必要的限制,頁面愈容易跑版。




建立 HTML 架構
依照上面的架構圖我們可以建立以下的 HTML 架構。
這裡也是一個很簡單架設觀念,只要把每個方匡都想成是 <div></div>,然後在從外到內一層一層去部屬就可以了。

對於 ContentWrapper 的結構位置建議放置在分欄區域(MainWrapper)的起始位置,這樣可以讓內容資訊有較好的 SEO。

<div id="ContainerWrapper" class="ClearIt">
<div id="Container">

<div id="Header" class="ClearIt">
Header
</div>

<div id="Banner">
Banner
</div>

<div id="MainWrapper" class="ClearIt">
<div id="ContentWrapper">
<div id="Content">
Content
</div>
</div>

<div id="SidebarWrapper">
<div id="Sidebar">
Sidebar
</div>
</div>
</div>

</div>
</div>

<div id="FooterWrapper">
<div id="Footer">
Footer
</div>
</div>



CSS 排版設定
要設定 CSS 也是一個簡單的事情,先將所有的 id 取出至 CSS 檔建出以下的文件。

/* 整體頁面區域 */
#ContainerWrapper{}
#Container{}

/* 頁首區域 */
#Header{}

/* 橫幅區域 */
#Banner{}

/* 主要內容區域 */
#MainWrapper{}

/* 主欄區域 */
#ContentWrapper{}
#Content{}

/* 側欄 區域 */
#SidebarWrapper{}
#Sidebar{}

/* 頁尾 區域 */
#FooterWrapper{}
#Footer{}


接著為版型作位置及寬度上的配置,在設定時會很難察覺區域的情況,建議為每個區域都先設置不同的底色加以區別。

/*先定義代替 <div style="display:block;"></div> 的樣式設定*/
.ClearIt:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
/*針對 IE6 的方式*/
.ClearIt {
_zoom: 1;
}


/* 整體頁面區域 */
#ContainerWrapper{
/* 設定寬度並整體置中 */
width:982px;
margin:0 auto;
}
#Container{}


/* 頁首區域 */
#Header{}


/* 橫幅區域 */
#Banner{}


/* 主要內容區域 */
#MainWrapper{}


/* 主欄區域 */
#ContentWrapper{
/* 設定主欄的位置 */
float:right;

/* 設定內容溢出的處理方式,這裡建議設置隱藏,避免非預期的跑版出現。 */
overflow:hidden;

/* 設定主欄的寬度 */
width:736px;
}
#Content{
/* 這裡建議設定最小高度,當內容高度不足時,不置於讓版面變得很奇怪。 */
min-height:500px;

/*IE6 最小高的設定*/
_height:500px;
_overflow:visible;
}


/* 側欄 區域 */
#SidebarWrapper{
/* 設定側欄的位置 */
float:left;

/* 設定內容溢出的處理方式,這裡建議設置隱藏,避免非預期的跑版出現。 */
overflow:hidden;

/* 設定側欄的寬度 */
width:202px;
}
#Sidebar{}


/* 頁尾 區域 */
#FooterWrapper{
/* 設定寬度並整體置中 */
width:982px;
margin:0 auto;
}
#Footer{}


剩下的就是去調整其他區域的底圖、padding 及 margin,那些網頁美工的設定。


參考頁面:
Last.fm
Wacanai.com
2009-07-20 20:41

CSS 部屬經驗-樣式命名

為了 IE6 的相容這裡我不會用太新穎的選擇器,希望有一天 IE6 的使用群可以消失,這樣在排版時可以不去顧慮 IE6 的問題。

主旨:
  1. 定義樣式的命名方式,區分 CSS 與 JavaScript 的使用
  2. id , class , tag 等選擇器得使用時機

為什麼要定義定義樣式的命名方式?
CSS 在選擇器的宣告上十分自由,但為了讓其他人也能順利的閱讀自己寫的樣式,定義一個有規則的命名方式,可以減少不必要的誤會跟問題。

這裡我自己作了命名的定義:
  • CSS 命名規則:
    1. 單字開頭大寫,不使用底線(_)間隔,除最後的數字代號前(.Style_1)
    2. 除特定版型架構命名,不得以 id 方式宣告樣式,唯一樣式才可以使用 id 命名(#SidebarWrapperLeft)
    3. 所有可沿用的樣式都才採用 class 方式宣告

  • JS 命名規則:
    1. 所有單字小寫,使用底線(_)間隔(action_bt)
    2. 與 JS 元素獲取相關命名均不可帶有樣式屬性
雖然有 CSS , JS 及 HTML 樣版可以將程式與美工的部分分離,但在 HTML 架構的規劃上仍需要協同開發,為區分樣式與 JS 的程式操作最好是將命名規則分開。


如何去決定選擇器的使用?
  • id 選擇器:
    在 id 的使用上我分成[頁面排版]及[例外樣式]
    1. 頁面排版:排版是不會重複的樣式定義,而且必須擁有不容易被複寫的特性,使用 id 選擇器去定義樣式是在好不過的。

      常用的命名詞彙:
      Outer外匡
      Container容器
      Status狀態
      Header頁首
      Banner頁面橫幅
      Nav/Navigation領航
      Navbar領航列
      Content/Container內容
      Main頁面主體
      Sidebar側欄
      Footer頁尾
      Wrapper具有寬度定義的區塊


    2. 例外樣式:在頁面中具有特別需要美工修飾的樣式時,利用 id 選擇器去強制複寫原有樣式。
      這是為了特殊樣式而保留的彈性,但不建議經常性的使用,這樣就違反 CSS 樣式統一的特性,未來維護時只會帶來更多的不便。


  • class 選擇器 :
    在 class 的使用上我分成[樣式定義]及[元素類型]
    1. 樣式定義:樣式規劃上最主要的用途定義,去規劃所有可重複利用的樣式,例如:按鈕、列表、表單等區塊性的樣式。

      常用的命名詞彙:
      Summary摘要
      Widget工具集
      Toolbar工具列
      Navbar領航列
      Menu項目單
      TextLink文字連結列
      PageLink頁面連結列
      Tab頁籤
      Search搜尋
      Form表單
      List列表
      TextList文字列表
      ImageList圖片列表
      Button按鈕
      AreaBox區塊匡
      InfoBox資訊匡
      PageInfo頁面資訊
      DropMenu下拉選單
      heading/Title標題
      SecDivide區段標題


    2. 樣式成員名稱:在樣式編排時為了補 tag 不足(樣式成員),利用 class 去定義內層的原件樣式。
      命名時可依據區塊在樣式裡的角色去取名。

      常用的命名詞彙:
      Title標題
      Date日期
      Buttons按鈕群
      Bottom底部
      Logo網站標誌
      Image圖片
      Action動作
      status狀態
      Content內容
      Even偶數
      Odd奇數
      First最前的
      List最後的


  • tag (HTML 標籤)選擇器:
    在 tag 的使用上我分成[限制樣式對象]及[樣式成員]
    1. 限制樣式對象:在樣式選擇器前加入可使用此樣式的tag(HTML 標籤),去區別可使用此樣式的元素。

    2. 樣式成員:在樣式定義結構中所使用到的 tag,別太依賴 tag 去定義樣式,在 HTML 中的 tag 是有限的,適時的用 class 去區別樣式成員。
      判斷方式,當子節點超過 2 層或同類 tag 超過一個以上時,最好使用樣式成員名稱的 class 命名去增加樣式成員


在這些定義中可能還是很模糊,在之後的文章中會介紹如何去規劃樣式,在那些範例中會使用到上面的規則,應該會比較容易瞭解。

參考頁面:
Last.fm
Wacanai.com
2009-07-19 04:00

(轉載) CSS hack 區分IE6,IE7,IE8,Firefox,Opera,Google,PCManCB

今天 Cara 問了一個我沒用過的 CSS hack 方法
最後在 英創達網路有限公司 找到詳細的差異比較表
這個表清楚的各版本 CSS 的區分方法


IE6IE7IE8FirefoxOperaGooglePCManCB範例
>YYYNNNY.type {
>color: #F00;
}
.YYNNNNY.type {
.color: #F00;
}
*YYNNNNY.type {
*color: #F00;
}
_YNNNNNN.type {
_color: #F00;
}
!importantNYYYYYY.type {
color: #F00 !important;
}
*+YYNNNNY.type {
*+color: #F00;
}

2009-07-19 02:14

Eclipse 3.4 3.5 連結 MySQL

首先 Eclipse 必須裝有 DataBase Tool 的套件
再來系統要安裝 JDBC for MySQL 的函示庫

這跟 3.3 的需求不同
函示庫必須安裝在 Java 的目錄下
要不然就會得到以下的錯誤訊息
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver

在 Ubuntu 下你可以使用以下指令安裝
sudo apt-get install libmysql-java

或著到 MySQL 官網下載 mysql-connector-java-5.1.8.tar.gz
然後將 jar 解開至 /usr/share/java 下


看圖說故事
Eclipse MySQL JDBC
在 Eclipse 中建立新連結

Eclipse MySQL JDBC
選取資料庫類型
並填寫連線名稱

Eclipse MySQL JDBC
先建立連結驅動器
之後再填寫這些設定值
要不然也無發測試連線

Eclipse MySQL JDBC
選取資料庫版本

Eclipse MySQL JDBC
這裡要先刪除原有的設定
要不然會出現下面的錯誤訊息
Unable to locate JAR/zip in file system as specified by the driver definition: mysql-connector-java-5.1.0-bin.jar

然後再加入新的連結函示庫

Eclipse MySQL JDBC
函示庫的位址在 /usr/share/java

Eclipse MySQL JDBC
這樣就可以成功建立連結了
再來就是把剩下的設定填一填就好了

之後開啟 Eclipse 後只要在剛建好的連結上執行連接就可以了

參考來源:
Using Eclipse Dali with Hibernate as Persistence Provider
2009-07-19 01:03

利用 AlphaImageLoader 解決 IE6 對 png 圖檔的透明問題

之前都利用 JavaScript 的 htc 去解決 png 的透明問題
但是在 JavaScript 作動前 png 是不會正常顯示的
在學會 AlphaImageLoader 的使用後發現效果還蠻好的

但是會有一些奇怪後遺症
就是區域內的連接都失效了
解決的方式就是在利用一個元素放在區域內
然後設有 position:relative; 的屬性
連結修正無法生效在設有 position:absolute; 的區域內

CSS :

#ContainerWrapper{
background: transparent url(/images/border_bg.png) repeat-y;
width:982px;
margin:0 auto;

/*IE6 PNG 檔透明修正設定*/
_background: transparent;
_filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/images/border_bg.png', sizingMethod='scale');
}

#ContainerWrapper #Container{
/*修正 AlphaImageLoader 造成的連結失效問題*/
_position:relative;
}


HTML:

<div id="ContainerWrapper">
<div id="Container">
</div>
</div>



AlphaImageLoader 的參數值
  1. enabled:布林值(Boolean)。是否開啟濾鏡(基本上可以忽略這個設定)
    • true:開啟濾鏡(預設值)
    • false:關閉濾鏡

  2. sizingMethod:字串(String)。設定圖片在元素容器裡的顯示方式
    • crop:剪切圖片以符合應元素尺寸
    • image:使元素尺寸符合圖片尺寸(預設值)
    • scale:縮放圖片以符合元素尺寸

  3. src :字串(String)。指定圖片的路徑,注意這個路徑是指加載濾鏡的頁面相對於圖片的路徑而不是css文件相對於圖片的路徑。
    建議統一使用以 DocumentRoot 為準的絕對路徑

參考來源:
Microsoft.AlphaImageLoader滤镜讲解
2009-07-19 00:49

InnoDB 匯入時關閉 Foreign Key 檢查 [MySQL]

在設有 Foreign Key 的資料表在寫入時都會檢查資料的正確性
可是再匯入原有資料時會因為表順序而產生錯誤問題
這時候就必須關閉 Foreign Key 檢查

我都會在原始資料的 sql 文件最前面加入這兩行
第一:先關閉 Foreign Key 檢查,避免匯入失敗
第二:確定文件的編碼格式,避免亂碼的問題

-- 關閉 Foreign Key 檢查, 0 是關閉,1 是開啟
-- 設定只會在這次的連結中生效
SET FOREIGN_KEY_CHECKS = 0;

-- 指定匯入的編碼方式
SET NAMES 'UTF8';
2009-07-09 21:32

(轉載)mysqldump 5.1 資料備份詳細指令 [MySQL]

轉載自:MySQL 5.1參考手冊

mysqldump - 資料庫備份程式

mysqldump [options] db_name [tables]
mysqldump [options] --database DB1 [DB2 DB3...]
mysqldump [options] --all--database
如果沒有指定任何資料表或使用了---database或--all--database選項,則轉儲整個資料庫。

要想獲得您的版本的mysqldump支援的選項,執行mysqldump ---help。

如果運行mysqldump沒有--quick或--opt選項,mysqldump在轉儲結果前將整個結果集裝入內存。如果轉儲大資料庫可能會出現問題。該選項預設啟用,但可以用--skip-opt禁用。

如果使用最新版本的mysqldump程式生成一個轉儲重裝到很舊版本的MySQL伺服器中,不應使用--opt或-e選項。


選項 OPTIONS

--help,-?
顯示幫助消息並退出。

--add-drop--database
在每個CREATE DATABASE語句前新增DROP DATABASE語句。

--add-drop-tables
在每個CREATE TABLE語句前新增DROP TABLE語句。

--add-locking
用LOCK TABLES和UNLOCK TABLES語句引用每個資料表轉儲。重載轉儲檔案時插入得更快。參見7.2.16節,「INSERT語句的速度」。

--all--database,-A
轉儲所有資料庫中的所有資料表。與使用---database選項相同,在命令行中命名所有資料庫。

--allow-keywords
允許建立關鍵字列名。應在每個列名前面加上資料表名前綴。

---comments[={0|1}]
如果設置為 0,禁止轉儲檔案中的其它訊息,例如程式版本、伺服器版本和主機。--skip—comments與---comments=0的結果相同。 預設值為1,即包括額外訊息。

--compact
產生少量輸出。該選項禁用註釋並啟用--skip-add-drop-tables、--no-set-names、--skip-disable-keys和--skip-add-locking選項。

--compatible=name
產生與其它資料庫系統或舊的MySQL伺服器更兼容的輸出。值可以為ansi、mysql323、mysql40、postgresql、oracle、mssql、db2、maxdb、no_key_options、no_tables_options或者no_field_options。要使用幾個值,用逗號將它們隔開。這些值與設置伺服器SQL模式的相應選項有相同的含義。參見5.3.2節,「SQL伺服器模式」。

該選項不能保證同其它伺服器之間的相容性。它只啟用那些目前能夠使轉儲輸出更兼容的SQL模式值。例如,--compatible=oracle 不映射Oracle類型或使用Oracle註釋語法的數據類型。

--complete-insert,-c
使用包括列名的完整的INSERT語句。

--compress,-C
壓縮在客戶端和伺服器之間發送的所有訊息(如果二者均支援壓縮)。

--create-option
在CREATE TABLE語句中包括所有MySQL資料表選項。

--database,-B
轉儲幾個資料庫。通常情況,mysqldump將命令行中的第1個名字參量看作資料庫名,後面的名看作資料表名。使用該選項,它將所有名字參量看作資料庫名。CREATE DATABASE IF NOT EXISTS db_name和USE db_name語句包含在每個新資料庫前的輸出中。

--debug[=debug_options],-# [debug_options]
寫調試日誌。debug_options字串通常為'd:t:o,file_name'。

--default-character-set=charset
使用charsetas預設字元編碼。參見5.10.1節,「數據和排序用字元編碼」。如果沒有指定,mysqldump使用utf8。

--delayed-insert
使用INSERT DELAYED語句插入行。

--delete-master-logs
在主複製伺服器上,完成轉儲操作後刪除二進制日誌。該選項自動啟用--master-data。

--disable-keys,-K
對於每個資料表,用/*!40000 ALTER TABLE tbl_name DISABLE KEYS */;和/*!40000 ALTER TABLE tbl_name ENABLE KEYS */;語句引用INSERT語句。這樣可以更快地裝載轉儲檔案,因為在插入所有行後建立索引。該選項只適合MyISAM資料表。

--extended-insert,-e
使用包括幾個VALUES列資料表的多行INSERT語法。這樣使轉儲檔案更小,重載檔案時可以加速插入。

--fields-terminated-by=...
--fields-enclosed-by=...
--fields-optionally-enclosed-by=...
--fields-escaped-by=...
--lines-terminated-by=...
這些選項結合-T選項使用,與LOAD DATA INFILE的相應子句有相同的含義。參見13.2.5節,「LOAD DATA INFILE語法」。

--first-slave,-x
不贊成使用,現在重新命名為--lock-all-tables。

--flush-logs,-F
開始轉儲前刷新MySQL伺服器日誌檔案。該選項要求RELOAD權限。請注意如果結合--all--database(或-A)選項使用該選項,根據每個轉儲的資料庫刷新日誌。

例外情況是當使用--lock-all-tables或--master-data的時候:在這種情況下,日誌只刷新一次,在所有 資料表被鎖定後刷新。如果您想要同時轉儲和刷新日誌,應使用--flush-logs連同--lock-all-tables或--master-data。

--force,-f
在資料表轉儲過程中,即使出現SQL錯誤也繼續。

--host=host_name,-h host_name
從給定主機的MySQL伺服器轉儲數據。預設主機是localhost。

--hex-blob
使用十六進制符號轉儲二進制字串列(例如,'abc' 變為0x616263)。影響到的列有BINARY、VARBINARY、BLOB。

--lock-all-tables,-x
將資料庫中的所有資料表加鎖。在整體轉儲過程中通過全局讀鎖定來實現。該選項自動關閉--single-transaction和--lock-tables。

--lock-tables,-l
開始轉儲前鎖定所有資料表。用READ LOCAL鎖定資料表以允許並行插入MyISAM資料表。對於事務資料表例如InnoDB和BDB,--single-transaction是一個更好的選項,因為它不根本需要鎖定資料表。

請注意當轉儲多個資料庫時,--lock-tables分別為每個資料庫鎖定資料表。因此,該選項不能保證轉儲檔案中的資料表在資料庫之間的邏輯一致性。不同資料庫資料表的轉儲狀態可以完全不同。

--master-data[=value]
該選項將二進制日誌的位置和檔案名寫入到輸出中。該選項要求有RELOAD權限,並且必須啟用二進制日誌。如果該選項值等於1,位置和檔案名被寫入CHANGE MASTER語句形式的轉儲輸出,如果您使用該SQL轉儲主伺服器以設置從伺服器,從伺服器從主伺服器二進制日誌的正確位置開始。如果選項值等於2,CHANGE MASTER語句被寫成SQL註釋。如果value被省略,這是預設動作。

--master-data選項啟用--lock-all-tables,除非還指定--single-transaction(在這種情況下,只在剛開始轉儲時短時間獲得全局讀鎖定。又見--single-transaction。在任何一種情況下,日誌相關動作發生在轉儲時。該選項自動關閉--lock-tables。

--no-create-db,-n
該選項禁用CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name語句,如果給出---database或--all--database選項,則包含到輸出中。

--no-create-info,-t
不寫重新建立每個轉儲資料表的CREATE TABLE語句。

--no-data,-d
不寫資料表的任何行訊息。如果您只想轉儲資料表的結構這很有用。

--opt
該選項是速記;等同於指定 --add-drop-tables --add-locking --create-option --disable-keys --extended-insert --lock-tables --quick --set-charset。

它可以給出很快的轉儲操作並產生一個可以很快裝入MySQL伺服器的轉儲檔案。該選項預設開啟,但可以用--skip-opt禁用。要想只禁用確信用-opt啟用的選項,使用--skip形式;例如,--skip-add-drop-tables或--skip-quick。

--password[=password],-p[password]
連接伺服器時使用的密碼。如果您使用短選項形式(-p),不能在選項和密碼之間有一個空格。如果在命令行中,忽略了--password或-p選項後面的 密碼值,將提示您輸入一個。

--port=port_num,-P port_num
用於連接的TCP/IP端口號。

--protocol={TCP | SOCKET | PIPE | MEMORY}
使用的連接協議。

--quick,-q
該選項用於轉儲大的資料表。它強制mysqldump從伺服器一次一行地檢索資料表中的行而不是檢索所有行並在輸出前將它緩存到內存中。

--quote-names,-Q
用『`』字元引用資料庫、資料表和列名。如果伺服器SQL模式包括ANSI_QUOTES選項,用『"』字元引用名。預設啟用該選項。可以用--skip-quote-names禁用,但該選項應跟在其它選項後面,例如可以啟用--quote-names的--compatible。

--result-file=file,-r file
將輸出轉向給定的檔案。該選項應用在Windows中,因為它禁止將新行『\n』字元轉換為『\r\n』回車、返回/新行序列。

--routines,-R
在轉儲的資料庫中轉儲儲存程式(函數和程式)。使用---routines產生的輸出包含CREATE PROCEDURE和CREATE FUNCTION語句以重新建立子程式。但是,這些語句不包括屬性,例如子程式定義者或建立和修改時間戳。這說明當重載子程式時,對它們進行建立時定義者應設置為重載用戶,時間戳等於重載時間。

如果您需要建立的子程式使用原來的定義者和時間戳屬性,不使用--routines。相反,使用一個具有mysql資料庫相應權限的MySQL帳號直接轉儲和重載mysql.proc資料表的內容。

該選項在MySQL 5.1.2中新增進來。在此之前,儲存程式不轉儲。

--set-charset
將SET NAMES default_character_set加到輸出中。該選項預設啟用。要想禁用SET NAMES語句,使用--skip-set-charset。

--single-transaction
該選項從伺服器轉儲數據之前發出一個BEGIN SQL語句。它只適用於事務資料表,例如InnoDB和BDB,因為然後它將在發出BEGIN而沒有阻塞任何應用程式時轉儲一致的資料庫狀態。

當使用該選項時,應記住只有InnoDB資料表能以一致的狀態被轉儲。例如,使用該選項時任何轉儲的MyISAM或HEAP資料表仍然可以更改狀態。

--single-transaction選項和--lock-tables選項是互斥的,因為LOCK TABLES會使任何掛起的事務隱含提交。

要想轉儲大的資料表,應結合--quick使用該選項。

--socket=path,-S path
當連接localhost(為預設主機)時使用的套接字檔案。

--skip--comments
參見---comments選項的描述。

--tab=path,-T path
產生tab分割的數據檔案。對於每個轉儲的資料表,mysqldump建立一個包含建立資料表的CREATE TABLE語句的tbl_name.sql檔案,和一個包含其數據的tbl_name.txt檔案。選項值為寫入檔案的目錄。

預設情況,.txt數據檔案的格式是在列值和每行後面的新行之間使用tab字元。可以使用--fields-xxx和--行--xxx選項明顯指定格式。

註釋:該選項只適用於mysqldump與mysqld伺服器在同一台機器上運行時。您必須具有FILE權限,並且伺服器必須有在您指定的目錄中有寫檔案的授權。

--tables
覆蓋---database或-B選項。選項後面的所有參量被看作資料表名。

--triggers
為每個轉儲的資料表轉儲觸發器。該選項預設啟用;用--skip-triggers禁用它。

--tz-utc
在轉儲檔案中加入SET TIME_ZONE='+00:00'以便TIMESTAMP列可以在具有不同時區的伺服器之間轉儲和重載。(不使用該選項,TIMESTAMP列在具有本地時區的源伺服器和目的伺服器之間轉儲和重載)。--tz-utc也可以保護由於夏令時帶來的更改。--tz-utc預設啟用。要想禁用它,使用--skip-tz-utc。該選項在MySQL 5.1.2中加入。

--user=user_name,-u user_name
連接伺服器時使用的MySQL帳號。

--verbose,-v
冗長模式。打印出程式操作的詳細訊息。

--version,-V
顯示版本訊息並退出。

--where='where-condition', -w 'where-condition'
只轉儲給定的WHERE條件選擇的記錄。請注意如果條件包含命令解釋符專用空格或字元,一定要將條件引用起來。
例如:
"--where=user='jimf'"

"-wuserid>1"

"-wuserid<1"

--xml,-X
將轉儲輸出寫成XML。

--var_name=value
用來選項設置下面的變數:

max_allowed_packet

客戶端/伺服器之間通信的緩存區的最大大小。最大為1GB。
net_buffer_length

客戶端/伺服器之間通信的緩存區的初始大小。當建立多行插入語句時(如同使用選項--extended-insert或--opt),mysqldump建立長度達net_buffer_length的行。如果增加該變數,還應確保在MySQL伺服器中的net_buffer_length變數至少這麼大。

還可以使用--set-variable=var_name=value或-O var_name=value語法設置變數。然而,現在不贊成使用該語法。


範例


# mysqldump最常用於備份一個整個的資料庫:
mysqldump --opt db_name > backup-file.sql

# 您可以這樣將轉儲檔案讀回到伺服器:
mysql `db_name` < `backup-file.sql`
# 或者為:
mysql -e "source /path-to--backup/backup-file.sql" `db_name`



# mysqldump也可用於從一個MySQL伺服器向另一個伺服器複製數據時裝載資料庫:
mysqldump --opt `db_name` | mysql --host=`remote_host` -C `db_name`



# 可以用一個命令轉儲幾個資料庫:
mysqldump ---database `db_name1` [`db_name2` ...] > `my_databases.sql`



# 如果您想要轉儲所有資料庫,使用--all--database選項:
mysqldump --all-databases > `all_databases.sql`

# 如果資料表保存在InnoDB儲存引擎中,mysqldump提供了一種聯機備份的途徑(參見下面的命令)。該備份只需要在開始轉儲時對所有資料表進行全局讀鎖定(使用FLUSH TABLES WITH READ LOCK)。獲得鎖定後,讀取二進制日誌的相應內容並將鎖釋放。因此如果並且只有當發出FLUSH...時正執行一個長的更新語句,MySQL伺服器才停止直到長語句結束,然後轉儲則釋放鎖。因此如果MySQL伺服器只接收到短("短執行時間")的更新語句,即使有大量的語句,也不會注意到鎖期間。
mysqldump --all-databases --single-transaction > `all_databases.sql`



# 對於點對點恢復(也稱為「前滾」,當您需要恢復舊的備份並重放該備份以後的更改時),循環二進制日誌(參見5.11.3節,「二進制日誌」)或至少知道轉儲對應的二進制日誌內容很有用:
mysqldump --all-databases --master-data=2 > `all_databases.sql`
# 或
mysqldump --all-databases --flush-logs --master-data=2 > `all_databases.sql`

# 如果資料表保存在InnoDB儲存引擎中,同時使用--master-data和--single-transaction提供了一個很方便的方式來進行適合點對點恢復的聯機備份。



# 單純匯出資料,不匯出任何欄位結構
mysqldump -u`username` --opt -c -n -t --skip-triggers `dbname` > `databases.sql`
2009-07-09 17:38

[PHP] 時區設定(date.timezone)

方法一:更改 php.ini 中的 date.timezone
[Date]
; Defines the default timezone used by the date functions
date.timezone = Asia/Taipei


方法二:利用 set_ini()
<?php
ini_set('date.timezone','Asia/Taipei');
//.......
?>


參考來源:
php 改時區(改為台北時區)
php时区设置
2009-07-09 16:50

MySQL 加解密函數


--[單向加密]
-- MD5 演算法
MD5(str)

-- MySQL 密碼演算法
PASSWORD(str)

-- Unix crypt 演算法
ENCRYPT(str[,salt])

-- 安全散列演算法
SHA1(str)
SHA(str)


--[雙向加密]
-- MySQL 中的低階加解密演算法,
DECODE() -- 解密
ENCODE() -- 加密

-- 以 Advanced Encryption Standard 演算法加解密
AES_DECRYPT(crypt_str,key_str) -- 解密
AES_ENCRYPT(str,key_str)) -- 加密

-- 以 DES 演算法加解密,需要 SSL 的支援
DES_DECRYPT(crypt_str[,key_str]) -- 解密
DES_ENCRYPT(str[,{key_num|key_str}]) -- 加密


--[資料壓縮]
COMPRESS(string_to_compress) -- 壓縮
UNCOMPRESS(string_to_uncompress) -- 解壓縮
UNCOMPRESSED_LENGTH(compressed_string) -- 回傳壓縮前的字串長度


對於 key_str 的設定建議使用 MySQL 變數處理

-- 在 MySQL 中設定金鑰變數
SELECT @key:='sfdgsjhgjgsdfsg'

-- 在查詢資料時可以使用金鑰變數,這樣就可以不用在程式中傳遞金鑰了
-- 在程式撰寫時看起來也比較簡潔
SELECT
`Id`,
AES_DECRYPT(`Name`,@key)AS`Name`,
AES_DECRYPT(`Email`,@key)AS`Email`
FROM `system_uesr`


對於加密過的資料必須存放在二進位( BLOB )的欄位格式中,詳細的型態格式請察看10.5. Data Type Storage Requirements

類型 大小(單位:字節)
 TinyBlob 最大 255
 Blob 最大 65K
 MediumBlob 最大 16M
 LongBlob 最大 4G



參考來源:
MySQL 5.1 Reference Manual :: 11.11.2 Encryption and Compression Functions
2009-07-09 16:17

Eclipse 3.3 , 3.4 and 3.5 中文化語言包

之前為中文化找好久
終於再 JavaWorld@TW 找到下載聯結

先到下載頁面 Babel Language Packs 選擇所對應的版本名稱
Eclipse 3.3 Europa R0.8.0
Eclipse 3.4 Ganymede R0.8.0
Eclipse 3.5 Galileo R0.8.0
Eclipse 3.6 Helios R0.8.0


再來就是找到繁體中文的區段

然後下載所需要的語言包

條目說明:
BabelLanguagePack-eclipse-zh_TW_3.4.0.v20090620043401.zip (97.67%)
eclipse - 主要的語言包,如果有使用 CDT 外掛可以再多下載 tools.cdt 語言包
zh_TW - 語系
3.4.0 - 支援的版本
v20090620043401 - 更新時間
97.67% - 中文化的%

將語言包解壓縮至 Eclipse 的程式目錄裡
然後重新開啟 Eclipse 就可以了
2009-07-09 15:47

Ubuntu 時間及時區設定 [Linux]

前面要先說一個很基礎的觀念
系統時間與 BIOS 時間是不一樣的
因為系統時間會再加上一個時區設定
而 BIOS 則是以 UTC 時間為準

# 取得時區設定檔,請選擇你需要的時區
sudo tzselect

# 更換系統時區檔
sudo ln -sf /usr/share/zoneinfo/Asia/Taipei /etc/localtime

# 讓核心時間與網路時間伺服器對時
sudo ntpdate pool.ntp.org

# 更新 BIOS 的時間
sudo hwclock -w

# 編輯系統排程,再裏面加入下面這行,讓系統排程每日對時一次
sudo crontab -e
@daily /usr/sbin/ntpdate pool.ntp.org > /dev/null


參考資料:
[Ubuntu]Ubuntu 更改時區
Ntpdate - Ubuntu 正體中文 Wiki
2009-05-30 04:14

[JavaScript] 物件導向-類別宣告


// 宣告類別
function Attack(key) {
/*=( 建構子及初始化成員變數 )================== */
// 設定字符表
this.keyStr = key;

// 將字串切割成陣列
this.keyArray = this.keyStr.match(/./gi);

// 進位基底
this.base = this.keyArray.length;

this.passwd = [0];


/*=( 成員函數 )================== */
// 前進一個字符
this.pushPasswd = function(){
var p = this.passwd;
var b = this.base;
var i = 0;

p[i]++;
while(p[i] >= b){
p[i++] = 0;
if(p[i] != undefined){
p[i]++;
}else{
p[i] = 0;
}

}
return this;
};

// 設定初始字串
this.setPasswd = function(str){
this.passwd = [0];

if(str){
var s = str.match(/./gi);
var k = this.keyStr;

for(var i=0,l=s.length; i<l; i++){
num = k.indexOf( str[i] );
if(num<0){ num = 0; }
this.passwd[l-i-1] = num;
}
}
return this;
};

// 取得當前字串
this.getPasswd = function(){
var temp = '';
var k = this.keyArray;
var p = this.passwd;

for(var i=0,l=p.length; i<l; i++){
temp = k[ p[i] ] + temp;
}
return temp;

};
}


// 建立物件
var try1 = new Attack('abcdefghijklmnopqrstuvwxyz0123456789');

// 物件操作
try1.setPasswd('asdf');
try1.getPasswd();
2009-05-29 16:02

Picasa 所有的縮圖尺寸(size)

Picasa 在上傳圖片後就會為圖片建立各種尺寸的縮圖
如果想變更預設提供連結的圖片大小
可以修改圖片的 URL 去達成
只是要看這類似亂碼的 URL 會有點累人


以下面這個圖片的 URL 來看:
http://lh6.ggpht.com/_b8lN_UbLoEc/Sfi2pSkc_4I/AAAAAAAAENA/ECO_WzQk2og/s400/as_001.jpg

當中的 s400 就是縮圖的尺寸
簡單的說就是高度與寬度的最大值

Picasa 提供以下的縮圖尺寸:
  • s32
  • s48
  • s64
  • s72
  • s94
  • s104
  • s110
  • s128
  • s160
  • s200
  • s220
  • s288
  • s320
  • s400
  • s512
  • s576
  • s640
  • s720
  • s800
  • s912
  • s1024
  • s1152
  • s1280
  • s1440
  • s1600

如果要取得原始大小的 URL 的話只要去掉 s400 就可以了
例如:
http://lh6.ggpht.com/_b8lN_UbLoEc/Sfi2pSkc_4I/AAAAAAAAENA/ECO_WzQk2og/as_001.jpg
2009-05-29 02:52

Ajax(XMLHttpRequest) 同步與非同步(異步)連結

首先針對 Internet Explorer 的連結物件做統一的處理,將 ActiveXObject 包裝成與 Mozilla 中的 XMLHttpRequest 相同的物件,這樣我們就可以排除瀏覽器的問題。

/* 針對不同瀏覽器的前置處理宣告 */
if (typeof(XMLHttpRequest)=="undefined" && window.ActiveXObject) {
XMLHttpRequest=function(){
var arrSignatures = [
"MSXML2.XMLHTTP.5.0",
"MSXML2.XMLHTTP.4.0",
"MSXML2.XMLHTTP.3.0",
"MSXML2.XMLHTTP",
"Microsoft.XMLHTTP"];
for (var i = 0; i < arrSignatures.length; i++) {
try{
var oRequest = new ActiveXObject(arrSignatures[i]);
return oRequest;
}catch(oError){/*ignore*/}
}
throw new Error("MSXML is not installed on your system.");
};
}



我們可以直接用 XMLHttpRequest 去處理 Ajax 連結,這是以[GET]方式建立[非同步]的傳送連接,如果要使用 POST 做連結請參考之前的文章[Ajax 使用 POST 傳送]。
POST 的差別只在於 open,setRequestHeader,send 這三個地方的設定。

/**=( 以[GET]方式建立[非同步]傳送連接 )====================*/

// 產生要求資料的 URL 及 GET 參數
var sURL = "check_in.php?user=xxxx&pass=xxxx";

// 建立 XMLHttpRequest 物件,並且送要求
var oRequest = new XMLHttpRequest();

// 設定連結方式及位址,並以非同步方式處理
oRequest.open("GET", sURL, true);
/*
void open(
in AUTF8String method, 傳送的方式
in AUTF8String url, 要求的位址
[optional] in boolean async, 同步方式(預設 true 非同步)
[optional] in AString user, 使用者名稱(預設為空字串)
[optional] in AString password 使用者密碼(預設為空字串)
);
*/

// 建立接收狀態的事件處理
oRequest.onreadystatechange = function(){
/*
當狀態變更時都會呼叫此事件
可利用 readyState 取得目前的狀態
所有可能的傳送狀態值如下:
0 (還沒開始)
1 (讀取中)
2 (已讀取)
3 (資訊交換中)
4 (請求完成)
*/
switch(oRequest.readyState){
case 0: // 開始前的程式處理
break;
case 1: // 讀取中的程式處理
break;
case 2: // 已讀取的程式處理
break;
case 3: // 資訊交換中的程式處理
break;
case 4: // 請求完成的程式處理
/* (在此處加入開啟已停用選項的設置) */

/*可以從responseText或responseXML取得傳回的資料*/
// 處理傳回為 200 的 HTTP 狀態碼
if (oRequest.status == 200) {
// 接受資料成功


// 將 responseText 中的文字轉成 JSON 物件
json = eval('('+oRequest.responseText+')');

// 處理其他錯誤 HTTP 狀態碼
}else{
/*接收資料失敗,可以從 statusText 取得錯誤狀態資訊*/
alert(oRequest.statusText);
}
break;
}

}

/* (在此處可以加入一些網頁選項停用的設置,以防止重複送出) */

// 送出 Ajax 要求
oRequest.send(null);
/*
以POST傳送時,這裡可以輸入(XML,串流,字串,JSON格式)
以GET傳送時,這裡只要輸入 null 或是空的
*/

// 強制中斷
//oRequest.abort();
/* 此函數方法可用在必要時,強制終止非同步請求 */



建立[同步]的 Ajax 傳送連接只要將 onreadystatechange 裡的程序移到 send 後面就可以了,如果非必要,最好還是不要以[同步]方式做連結,再處理死結的時候會多一些必要的處理,除非保證連結是 100% 正常且可行的。

/**=( 以[GET]方式建立[同步]傳送連接 )====================*/

// 產生要求資料的 URL 及 GET 參數
var sURL = "check_in.php?user=xxxx&pass=xxxx";

// 建立 XMLHttpRequest 物件,並且送要求
var oRequest = new XMLHttpRequest();

// 設定連結方式及位址,並以同步方式處理
oRequest.open("GET", sURL, false);
/*
void open(
in AUTF8String method, 傳送的方式
in AUTF8String url, 要求的位址
[optional] in boolean async, 同步方式(預設 true 非同步)
[optional] in AString user, 使用者名稱(預設為空字串)
[optional] in AString password 使用者密碼(預設為空字串)
);
*/

/* 開始前的程式處理... */

/* 讀取中的程式處理... */

// 送出 Ajax 要求
oRequest.send(null);
/*
以POST傳送時,這裡可以輸入(XML,串流,字串,JSON格式)
以GET傳送時,這裡只要輸入 null 或是空的
*/

// 請求完成的程式處理
/*可以從responseText或responseXML取得傳回的資料*/
// 處理傳回為 200 的 HTTP 狀態碼
if (oRequest.status == 200) {
// 接受資料成功

// 將 responseText 中的文字轉成 JSON 物件
json = eval('('+oRequest.responseText+')');

// 處理其他錯誤 HTTP 狀態碼
}else{
/*接收資料失敗,可以從 statusText 取得錯誤狀態資訊*/
alert(oRequest.statusText);
}



參考來源:
XMLHttpRequest - MDC
XMLHttpRequest的同步请求和Firefox的问题_网银

爪哇豆的秘密:AJAX深度歷險1(Getting Started)
Ajax内部交流文档
MoztwWiki:AJAX 上手篇
維基百科:AJAX
語言技術:Ajax Gossip
2009-05-23 12:36

[Firefox 套件開發] 建立檔案選取對話匡並儲存檔案



//*建立檔案選取對話匡*/
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.
classes["@mozilla.org/filepicker;1"].
createInstance(nsIFilePicker);

// 對話匡標題及開啟形式
fp.init(window, "儲存文件", nsIFilePicker.modeSave);
/*
常數 數值 描述
modeOpen 0 載入一個檔案或目錄
modeSave 1 儲存一個檔案或目錄
modeGetFolder 2 選擇一個資料夾目錄
modeOpenMultiple 3 載入多個檔案
*/


// 預設副檔名
fp.defaultExtension = 'txt';
// 預設檔名
fp.defaultString = 'file_name';
// 檔案類型過濾
fp.appendFilter("純文字檔","*.txt");

// 使用檔案類型過濾
fp.appendFilters(nsIFilePicker.filterHTML | nsIFilePicker.filterXML);
/*
常數 數值 描述
filterAll 0x01 符合 *.* 的副檔名
filterHTML 0x02 符合 *.html, *.htm 的副檔名
filterText 0x04 符合 *.txt 的副檔名
filterImages 0x08 符合 *.png, *.gif, *.jpg, *.jpeg 的副檔名
filterXML 0x10 符合 *.xml 的副檔名
filterXUL 0x20 符合 *.xul 的副檔名
filterApps 0x40 符合系統平台的應用程式類型
*/


// 顯示對話匡
var result = fp.show();

/*
常數 數值 描述
returnOK 0 當使用者點擊對話匡中的"確認"
returnCancel 1 當使用者點擊對話匡中的"取消"
returnReplace 2 當使用者選擇一個已存在的檔案並同意複寫
*/
if (result != nsIFilePicker.returnCancel) {
//建立檔案資料流
var stream = Components.
classes["@mozilla.org/network/file-output-stream;1"].
createInstance(Components.interfaces.nsIFileOutputStream);

// 移除已存在檔案文件
if(fp.file.exists()){fp.file.remove(true);}
// 建立新檔案文件
fp.file.create(fp.file.NORMAL_FILE_TYPE, 0666);

// 開啟檔案資料流
stream.init(fp.file, 0x02, 0x200, null);

var str = "test string"

// 將字串寫入檔案文件
stream.write(str, str.length);

// 關閉檔案資料流
stream.close();
}


參考來源:
Open and Save Dialogs - MDC
nsIFilePicker - MDC
Writing textual data - MDC
File I/O - MDC
nsIOutputStream - MDC
2009-05-23 12:25

[Firefox 套件開發] 建立檔案選取對話匡並讀取檔案



//*建立檔案選取對話匡*/
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.
classes["@mozilla.org/filepicker;1"].
createInstance(nsIFilePicker);

// 對話匡標題及開啟形式
fp.init(window, "讀取文件", nsIFilePicker.modeOpen);
/*
常數 數值 描述
modeOpen 0 載入一個檔案或目錄
modeSave 1 儲存一個檔案或目錄
modeGetFolder 2 選擇一個資料夾目錄
modeOpenMultiple 3 載入多個檔案
*/


// 預設副檔名
fp.defaultExtension = 'txt';
// 預設檔名
fp.defaultString = 'file_name';
// 檔案類型過濾
fp.appendFilter("純文字檔","*.txt");

// 使用檔案類型過濾
fp.appendFilters(nsIFilePicker.filterHTML | nsIFilePicker.filterXML);
/*
常數 數值 描述
filterAll 0x01 符合 *.* 的副檔名
filterHTML 0x02 符合 *.html, *.htm 的副檔名
filterText 0x04 符合 *.txt 的副檔名
filterImages 0x08 符合 *.png, *.gif, *.jpg, *.jpeg 的副檔名
filterXML 0x10 符合 *.xml 的副檔名
filterXUL 0x20 符合 *.xul 的副檔名
filterApps 0x40 符合系統平台的應用程式類型
*/


// 顯示對話匡
var result = fp.show();

/*
常數 數值 描述
returnOK 0 當使用者點擊對話匡中的"確認"
returnCancel 1 當使用者點擊對話匡中的"取消"
returnReplace 2 當使用者選擇一個已存在的檔案並同意複寫
*/
if (result != nsIFilePicker.returnOK) {
//建立檔案資料流
var stream = Components.
classes["@mozilla.org/network/file-input-stream;1"].
createInstance(Components.interfaces.nsIFileInputStream);
var cstream = Components.
classes["@mozilla.org/intl/converter-input-stream;1"].
createInstance(Components.interfaces.nsIConverterInputStream);

// 開啟檔案資料流
stream.init(fp.file, -1, 0, 0);
// 設定檔案讀取編碼方式
cstream.init(stream, "UTF-8", 0, 0);

var templates='';
let (str = {}) {
// 讀取整個文件,並把它放在 str.value
cstream.readString(-1, str);
templates = str.value;
}

// 顯示檔案內容
alert(templates);


// 關閉檔案資料流
cstream.close();
stream.close();
}


參考來源:
Open and Save Dialogs - MDC
nsIFilePicker - MDC
Reading textual data - MDC
File I/O - MDC
nsIInputStream - MDC
2009-05-21 11:43

[JavaScript] 取得選取範圍中的連結

getSelection 這個函數雖然可以取得使用者選取的文字,但要取得所選取的元素時,要用反向的方式去處理。

簡單的說 Selection 並沒有直接提供元素取得的方法,必須透過查驗元素是否在選取範圍內的方式,去找尋被選取的元素。


// 頁面選取的物件
var selection=window.getSelection();

// 取得頁面中所有的連結元素
var links=document.links;

// 掃瞄所有的連結元素
for(var i=0,l=links.length; i<l; i++){
// 檢查連結元素是否在選取的範圍裡
if(selection.containsNode(links[i],true)){
console.log(links[i]);
}
}
2009-05-21 00:03

[Firefox 套件開發] 取得當前的網頁 DOM 物件及視窗框架


/*
取得當前的網頁 DOM 物件,
這等於平常在網頁中 JavaScript 的 document。
*/
var doc = window.content.document;
// or
var doc = window.top.getBrowser().contentDocument;

// 當要改變視窗的 URL 頁面時
doc.location = "http://www.google.com.tw/";

// 取得指定 ID 的 DOM 元素
var content = doc.getElementById("content");

/*
PS: 這裡的 window 是指整個瀏覽器,
而非一般網頁中的 window,
在開發時別造成混淆了。
*/



/* 取得所有的瀏覽匡,這個物件將會是所有分頁共用的 */
var browser = window.top.getBrowser();

// 當頁面加載結束時的事件
contentOnLoad=function(e){
alert("onLoad");

// 如果事件只需要執行一次,或動態註冊,記得在結束時註銷事件
browser.removeEventListener("load",contentOnLoad,false);
};
// 註冊事件
browser.addEventListener("load",contentOnLoad,false);

2009-05-20 17:08

[Firefox 套件開發] CSS 延生屬性

在為了設定 broadcaster 中 window 的底色
無意見找到 Firefox 中 CSS 的延生屬性表
Mozilla CSS Extensions - MDC

當中有蠻多好玩得屬性質
雖然只限於 Mozilla 的瀏覽器

下面的屬性將會顯示你瀏覽器目前所使用的底色:

 -moz-Field 
 -moz-Dialog 
 Window 
 Highlight 

2009-05-20 16:37

[Firefox 套件開發] 設立快捷鍵

在 Firefox 套件中要建立自己的快捷鍵是非常容易的,只要在 XUL 中設定需要的按鍵及事件的對應就可以了。

<?xml version="1.0"?>

<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

    <!-- 建立快捷鍵 -->
    <keyset>
        <key id="key1"
             modifiers="control"
             key="Q"
             oncommand="alert('crtl+Q')" />

        <key id="key2"
             modifiers="control alt"
             key="C"
             oncommand="alert('crtl+alt+C')" />

        <key id="key3"
             modifiers="shift control"
             key="C"
             oncommand="alert('shift+crtl+C')" />

        <key id="key4"
             keycode="VK_F6"
             oncommand="alert('F6')"/>

        <key id="key5"
             modifiers="shift control"
             key="B"
             command="broadcaster1" />
    </keyset>

</window>


屬性
command
型態:command Id
監測內容的命令來設置編號元素。

disabled
型態:Bool(true,false)
顯示的元素是否被禁用。如果因素設置為True ,該元素被禁用。disabled 的內容通常是繪製灰色文字。如果內容是 disabled,用戶沒有回應的行動,甚至沒有收件人的重點,指揮事件不會發生。

key
型態:字符(character)
觸發鍵的字母值,必要的屬性設置。

keycode
型態:鍵盤按鍵的代碼字串
鍵盤上不是每個按鍵都有字母值,如 F1,Enter,Back...等,這個屬性可用來代替 key 的設置,去設定特殊的按鍵。
下面是常用的按鍵代碼:
VK_CANCELVK_BACKVK_TABVK_CLEAR
VK_RETURNVK_ENTERVK_SHIFTVK_CONTROL
VK_ALTVK_PAUSEVK_CAPS_LOCKVK_ESCAPE
VK_SPACEVK_PAGE_UPVK_PAGE_DOWNVK_END
VK_HOMEVK_LEFTVK_UPVK_RIGHT
VK_DOWNVK_PRINTSCREENVK_INSERTVK_DELETE
VK_0VK_1VK_2VK_3
VK_4VK_5VK_6VK_7
VK_8VK_9VK_SEMICOLONVK_EQUALS
VK_AVK_BVK_CVK_D
VK_EVK_FVK_GVK_H
VK_IVK_JVK_KVK_L
VK_MVK_NVK_OVK_P
VK_QVK_RVK_SVK_T
VK_UVK_VVK_WVK_X
VK_YVK_ZVK_NUMPAD0VK_NUMPAD1
VK_NUMPAD2VK_NUMPAD3VK_NUMPAD4VK_NUMPAD5
VK_NUMPAD6VK_NUMPAD7VK_NUMPAD8VK_NUMPAD9
VK_MULTIPLYVK_ADDVK_SEPARATORVK_SUBTRACT
VK_DECIMALVK_DIVIDEVK_F1VK_F2
VK_F3VK_F4VK_F5VK_F6
VK_F7VK_F8VK_F9VK_F10
VK_F11VK_F12VK_F13VK_F14
VK_F15VK_F16VK_F17VK_F18
VK_F19VK_F20VK_F21VK_F22
VK_F23VK_F24VK_NUM_LOCKVK_SCROLL_LOCK
VK_COMMAVK_PERIODVK_SLASHVK_BACK_QUOTE
VK_OPEN_BRACKETVK_BACK_SLASHVK_CLOSE_BRACKETVK_QUOTE
VK_HELP   


keytext
型態:字串
鍵盤快捷鍵標籤,這段文字將顯示在設有快捷鍵的 menuitem 中,並串接在 label 屬性後面。

modifiers
型態:組合鍵清單
快捷鍵中的組合鍵。組合鍵以空格分隔的或逗號。key 是不存在的平台上,將被分配到其他 key。
  • shift: Shift 鍵。
  • alt: Alt 鍵。在Mac 上是 Option 鍵。因為在 Mac 上文本輸入特別的文字的 Alt+Letter 的組合被預約,與其他的 modifier 聯結被使用。
  • meta: Meta 鍵。在 Mac 上是 Command 鍵。
  • control: Ctrl(Control) 鍵。
  • accel: 用戶的平台上的快捷鍵使用的鑰匙。通常成為使用的價值。
  • access: menu 和其他的要素的訪問鍵。在Windows 上面是 Alt 鍵。與要素的 accesskey 聯結被使用。
  • any:代表上述的全部,表示任意的 modifier key。

oncommand
型態:Script code
此事件處理程序被激活時,該命令要求。這是選擇一個菜單項時所發生的用戶命令或按下鍵盤快捷鍵分配給它。

參考來源:
key - MDC
keyset - MDC
firefox扩展开发(七) : 键盘快捷键
2009-05-20 15:00

[PHP] 取得 URL 頁面上的 title 內容


<?php
/*
功能: 取得 URL 頁面上的 <title> 內容

參數:$_POST['url']
*/

// 設定最長執行的秒數
ini_set ("expect.timeout", 30);
set_time_limit(30);

// 檢查 URL
if(!isset($_POST['url']) || $_POST['url'] == ''){
echo "URL 錯誤";
exit;
}


/* 取得 URL 頁面資料 */
// 初始化 CURL
$ch = curl_init();

// 設定 URL
curl_setopt($ch, CURLOPT_URL, $_POST['url']);
// 讓 curl_exec() 獲取的信息以資料流的形式返回,而不是直接輸出。
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
// 在發起連接前等待的時間,如果設置為0,則不等待
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 0);
// 設定 CURL 最長執行的秒數
curl_setopt ($ch, CURLOPT_TIMEOUT, 30);

// 嘗試取得文件內容
$store = curl_exec ($ch);


// 檢查文件是否正確取得
if (curl_errno($ch)){
echo "無法取得 URL 資料";
//echo curl_error($ch);/*顯示錯誤訊息*/
exit;
}

// 關閉 CURL
curl_close($ch);


// 解析 HTML 的 <head> 區段
preg_match("/<head.*>(.*)<\/head>/smUi",$store, $htmlHeaders);
if(!count($htmlHeaders)){
echo "無法解析資料中的 <head> 區段";
exit;
}

// 取得 <head> 中 meta 設定的編碼格式
if(preg_match("/<meta[^>]*http-equiv[^>]*charset=(.*)(\"|')/Ui",$htmlHeaders[1], $results)){
$charset = $results[1];
}else{
$charset = "None";
}

// 取得 <title> 中的文字
if(preg_match("/<title>(.*)<\/title>/Ui",$htmlHeaders[1], $htmlTitles)){
if(!count($htmlTitles)){
echo "無法解析 <title> 的內容";
exit;
}

// 將 <title> 的文字編碼格式轉成 UTF-8
if($charset == "None"){
$title=$htmlTitles[1];
}else{
$title=iconv($charset, "UTF-8", $htmlTitles[1]);
}
echo $title;
}

2009-05-20 14:25

[PHP] 裁切圖片並縮小至指定大小


<?php
/*
功能:裁切圖片並縮小至指定大小

參數:
$_GET['f'] 圖檔名稱:0001.jpg

$_GET['x'] 圖片裁切水平方向的起始位址(px):10
$_GET['y'] 圖片裁切垂直方向的起始位址(px):20

$_GET['w'] 圖片裁切選取的寬度(px):300
$_GET['h'] 圖片裁切選取的高度(px):200
*/

// 縮小圖片的指定大小(px)
$decreaseSize=160;


// 設定 header 中的圖片類型
header("Content-type:image/jpg");

// 檢查是否有給予圖片名稱,否則結束裁切
if (!isset($_GET['f']) || $_GET['f']==''){ exit; }

// 設定 header 中的圖片名稱
header("Content-Disposition:filename=".$_GET['f']);

// 開啟暫存目錄中的圖片
$source = @imageCreateFromJpeg("/tmp/".$_GET['f']);

if (!$source){
// 圖片開啟錯誤...
exit;
}


// 取得圖片原始寬度與高度
$sourceWidth = imagesX($source);
$sourceHeight = imagesY($source);


/* 裁切圖片 */
// 圖片選取的寬度與高度
$cropWidth = intval($_GET['w']);
$cropHeight = intval($_GET['h']);

// 檢查裁切寬度是否在範圍裡
if (!$cropWidth || $cropWidth > $sourceWidth){ // 寬度為零或超過最大寬度
$cropWidth = $sourceWidth;
}elseif ($cropWidth < $decreaseSize){ // 低於最小寬度
$cropWidth=$decreaseSize;
}

// 檢查裁切高度是否在範圍裡
if (!$cropHeight || $cropHeight > $sourceHeight){ // 高度為零或超過最大高度
$cropHeight = $sourceHeight;
}elseif ($cropHeight < $decreaseSize){ // 低於最小高度
$cropHeight = $decreaseSize;
}


// 圖片選取的起始位址
$cropX = intval($_GET['x']);
$cropY = intval($_GET['y']);

// 檢查起始位址
if ($cropX > ($sourceWidth-$cropWidth)){
$cropX = $sourceWidth-$cropWidth;
}
if ($cropY > ($sourceHeight-$cropHeight)){
$cropY = $sourceHeight-$cropHeight;
}


// 建立裁切所需要的圖片空間
$crop = imageCreateTrueColor($cropWidth, $cropHeight);

// 複製選定的圖片範圍(剪裁圖片)
imageCopy(
$crop,
$source,
0,
0,
$cropX,
$cropY,
$cropWidth,
$cropHeight
);


/*縮小圖片 */
// 計算縮圖尺寸
if ($cropWidth<$cropHeight) {
$decreaseWidth = $decreaseSize;
$decreaseHeight = intval($cropHeight*$decreaseSize/$cropWidth);
} else {
$decreaseHeight=$decreaseSize;
$decreaseWidth = intval($cropWidth*$decreaseSize/$cropHeight);
}

// 建立縮圖所需要的圖片空間
$decrease = imageCreateTrueColor($decreaseWidth, $decreaseHeight);

// 複製並縮小圖片
imageCopyResampled(
$decrease,
$crop,
0,
0,
0,
0,
$decreaseWidth,
$decreaseHeight,
$cropWidth,
$cropHeight
);


// 顯示圖片
imageJpeg($decrease);


// 關閉圖片
imageDestroy($source);
imageDestroy($crop);
imageDestroy($decrease);


相關文章:
php 圖檔上傳檢查
在固定大小的排版中做圖片選取
MooCrop 正方形選取( Square )