顯示具有 程式碼展示 標籤的文章。 顯示所有文章
顯示具有 程式碼展示 標籤的文章。 顯示所有文章
2013-08-17 14:55

[PHP] url, base64, sprite 三種格式的 icons.css 產生器

先做一個假設,如果 icon 的檔名就是 css 的 class 樣式名稱,那麼我們只要掃瞄資料夾的 Icon 圖檔,然後產生對應的 CSS 檔案,這樣就可以省去製作 Sprite 圖檔跟維護 CSS 對應的問題。

第一種 url 格式只是取得路徑的問題。

第二種 base64 格式可以透過 base64_encode(file_get_contents($path)); 就簡單的達成。

第三種 sprite 格式則使用 Imagick 去處理,會比較快樂。


接著以下就是如何達成的程式片段:

<?php

/*把目錄改變到當前文件下*/
chdir(dirname(__FILE__));

/*Sprite 圖與圖的間距*/
$spriteGap = 30;


/*=[ 取得圖檔資訊 ]=*/
$maxWidth = 0;
$maxHeight = 0;
$nextTop = 0;
$imageList = array();

foreach ( glob('icons/*.{png,jpg,gif}',GLOB_BRACE) as $path )
{
    $image = new Imagick($path);
    $name = pathinfo($path,PATHINFO_FILENAME);

    if(isset($imageList[$name])){ 
        throw new Exception("圖片名稱重複 [ $name ]"); 
    }

    $info = array(
        '{top}' => $nextTop,
        '{image}' => $image,
        '{width}' => $image->getImageWidth(),
        '{height}' => $image->getImageHeight(),
        '{name}' => $name,
        '{path}' => $path,
        '{isAnimate}' => false
    );

    $header = '';
    switch($image->getImageFormat()){
        case "PNG":
            $header = 'data:image/png;base64,'; break;
        case "JPEG":
            $header = 'data:image/jpeg;base64,'; break;
        case "GIF":
            $header = 'data:image/gif;base64,'; break;
        default: break;
    }

    $info['{uri}'] = $header.base64_encode(file_get_contents($path));

    $maxWidth = max($maxWidth, $info['{width}']);
    $maxHeight = max($maxHeight, $info['{height}']);

    
    /*檢查圖片是否為動畫*/
    $frameNum = 0;
    foreach($image->deconstructImages() as $i) {
        $frameNum++;
        if ($frameNum > 1) {
            $info['{isAnimate}'] = true;
            break;
        }
    }
    
    if(!$info['{isAnimate}']){
        $nextTop += $info['{height}'] + $spriteGap;
    }


    $imageList[$name] = $info;
}


/*=[ 製作 CSS Sprite 圖檔 ]=*/
$spriteImage = new Imagick();
$spriteImage->newImage($maxWidth, $nextTop, new ImagickPixel());
$spriteImage->setImageFormat('png');
$spriteImage->paintTransparentImage(new ImagickPixel(), 0.0, 0);

foreach ($imageList as $name => $info)
{
    if($info['{isAnimate}']){ continue; } /* 忽略 GIF 動畫 */

    /* 複製 Icon 圖檔到 Sprite */
    $spriteImage->compositeImage(
        $info['{image}'],
        $info['{image}']->getImageCompose(),
        0,
        $info['{top}']
    );

    $info['{image}']->destroy();
    unset($imageList[$name]['{image}']);
}

$spriteImage->writeImage('icons.sprite.png');
$spriteImage->destroy();
$spriteImage = null;


下載完整程式: php_make_icons_css.zip
2013-07-07 13:29

[轉載][CSS] drop-shadows without images

轉載自:CSS drop-shadows without images

Lifted corners

Curled corners

Perspective

Raised box

Single vertical curve

Vertical curves

Single horizontal curve

Horizontal curves

Rotated box

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-04-29 21:34

Web 文件類型壓縮及註解清除器

大部分的 Web 文件壓縮,都是將不要的空白文字或不必要的註解清除,以換取檔案的大小。

之前找尋不到合適的工具,索性就自己寫一個工具,這次將之前的HTML & Smarty、JavaScript、CSS 及 PHP 註解清除器做一個整合,並且做一些使用上的教學。

修改特點:
  • 整合之前的文件類型至一個工具上
  • 只針對 html , htm , css , js 及 php 副檔名的文件做處理
  • 增加參數選擇

web_clear 參數說明

web_clear [-hvc] (filename)
[-h | -?] : 顯示參數說明
[-v] : 顯示被執行的檔案列表
[-c] : 單純只清除註解
(filename) : 檔案路徑或目錄路徑


Windows 下的操作


可以透過拖移文件或資料夾的方式執行此工具。

也可以透過命令列或批次檔去執行

@ECHO off

web_clear.exe -v "Z:\Web" Z:\WebServer\1.html Z:\WebServer\1.css

PAUSE


Linux 下的操作

透過命令列或 Shell 去執行

#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

./web_clear -v /home/test/index.php

# 也可以配合 find 去執行
#./web_clear -v `find /home/test -name '*.css' -or -name '*.js'`

exit 0


檔案下載:

web_clear.tar.gz


web_clear
|-- linux
| |-- source
| | |-- web_clear.c
| | `-- web_clear.l
| |
| |-- clear_file.sh
| `-- web_clear
|
`-- windows
|-- source
| |-- web_clear.c
| `-- web_clear.l
|
|-- clear_file.bat
`-- web_clear.exe

4 directories, 8 files
2009-04-29 17:22

[PHP] 線上編碼文件轉換器

這是利用 iconv 及 curl 去做線上文件編碼轉換,之前為了讓桌面行事曆能夠讀取 Google Calendar 而做的轉換器。


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

if($_GET['url']){
// 設定原始編碼及目標編碼
$source=($_GET['source'])? $_GET['source']: 'UTF-8';
$target=($_GET['target'])? $_GET['target']: 'BIG5';

// 取得 URL
$url=$_GET['url'];

// 初始化 CURL
$ch = curl_init();

// 設定 URL
curl_setopt($ch, CURLOPT_URL, $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 iconv($source,$target, $store);
exit;
}
}
?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>線上編碼文件轉換器</title>
</head>
<body style="width:28em;margin:5% auto;text-align:center;">
<form method="get" action="">
<fieldset>
<legend>線上編碼文件轉換器</legend>
<label>URL : <input type="text" name="url" size="48" /></label>
<p>
<input type="text" name="source" size="12" value="UTF-8" />
-&gt; 轉換至 -&gt;
<input type="text" name="target" size="12" value="BIG5" />
</p>
<p><input type="submit" value="開始轉換"/></p>
</fieldset>
</form>
</body>
</html>



參考文章:
PHP程式學習筆記本(PHP.Javascript.Mysql.cakephp.Jquery.Smarty): php.curl詳解
2009-03-19 01:25

[Shell] 利用 tar 作資料備份

一般在 console 使用 tar 做備份壓縮時,都會習慣使用相對路徑做壓縮,在解壓縮時也比較方便,可是再寫 Shell 做 crontab 排程時,也想要使用相對路徑做壓縮的話,必須用一些方法,下面的 script 還加上過濾檔案的機制,可以排除一些隱藏檔或特定目錄的備份。

#!/bin/bash
# Program : 備份指定目錄
# History : 2009/03/19
# Author : Jax
# E-mail : weskerjax@gmail.com
# Website : http://jax-work-archive.blogspot.com/

PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH

# 排除不需要備份的檔案類型
EXCLUDE=""
FILTER=(
"*.bak"           # 排除副檔名為 .bak 的檔案
".*"              # 排除所有隱藏檔
"/CVS/"           # 排除所有目錄為 CVS 的目錄
"Smarty/cache"    # 排除路徑為 Smarty/cache 的目錄
"Smarty/tpl_c"    # 排除路徑為 Smarty/tpl_c 的目錄
)
for i in "${FILTER[@]}" ; do
    EXCLUDE="$EXCLUDE --exclude=$i"
done

# 時間參數
DATE=$(date +%Y%m%d)

# 配份目錄
TARGET_DIR="/home/web"

# 備份檔名路徑目錄
ZIP_FILE="/home/backup/backup_$DATE.tar.bz2"

# 執行壓縮指令
tar -jcf $ZIP_FILE $EXCLUDE -C $TARGET_DIR $(ls $TARGET_DIR)

exit 0;


原始檔:server_backup.sh
2008-12-06 02:18

離開頁面前的對話匡 window.onBeforeUnload 事件

在頁面改變前會觸發 window.onBeforeUnload 事件
但要怎麼產生出離開前的確認匡呢?
根據在 MSDN(onbeforeunload Event) 找到的說明
When a string is assigned to the returnValue property of window.event, a dialog box appears that gives users the option to stay on the current page and retain the string that was assigned to it. The default statement that appears in the dialog box, "Are you sure you want to navigate away from this page? ... Press OK to continue, or Cancel to stay on the current page.", cannot be removed or altered.

我們只要對這個事件 return 一個訊息就可以達成
除了 undefined 以外的所有值都會產生確認匡

那到底要怎麼做呢?
/*註冊事件*/
window.onbeforeunload = function(){
    return "是否要離開此頁面";
};

/*解除事件*/
window.onbeforeunload = null;


就這樣簡單的幾行就可以達成
真是簡單到不行
而且大多數的瀏覽器都支援

展示頁面(Demo Page)
2008-11-15 18:04

在固定大小的排版中做圖片選取

之前所用的圖片裁切介面(MooCrop 正方形選取( Square ))
在大尺寸圖片的選取上不是很直覺
明明就只是要裁出一張固定大小的圖
卻暫了大量的版面配置
所以我採用網路地圖的機制做了一個裁切工具
這個想法目前還只是個雛形

展示頁面(Demo Page)
2008-10-07 02:03

CSS fixed 定位( FF / IE6 )

fixed 定位主要是以 window 物件區塊做定位依據,所以不會隨頁面捲動而變動定位。

以往要達成這種模式的定位都要利用 JavaScript 的 onscroll 事件去達成,是蠻吃重的一種方法,而且流暢度也不好,會有閃爍的現象。

利用 fixed 定位可以簡化 JavaScript 的開發和負擔,而且又穩定且簡單設定。

body{
    height:1200px;

    /* prevent screen flash in IE6(解決 IE6 不正常閃爍) */
    background:url(nothing.txt) white fixed;
}

div{
    background:#FF0066;
    border:4px solid #FF9999;
}

/* 水平置中 */
.fixed-center{
    width:100px;
    height:100px;
    position:fixed;
    top:50%;
    left:50%;

    /* 上邊界計算 */
    /* -(border-top-width + padding-top + (height/2) ) */
    /* 或者是整體高除以二(offsetHeight/2) */
    margin-top:-52px;

    /* 左邊界計算 */
    /* -(border-left-width + padding-left + (width/2) ) */
    /* 或者是整體寬除以二(offsetWidth/2) */
    margin-left:-52px;

    /* position fixed for IE6 */
    _position: absolute;
    _margin-top:0;

    /* clientHeight:不包含邊匡的區塊高度( padding + height ) */
    /* offsetHeight:包含邊匡的區塊高度( border + padding + height ) */
    _top:expression(documentElement.scrollTop + ( documentElement.clientHeight-this.offsetHeight )/2
    );
}

.fixed-top-center{
    width:100px;
    height:100px;
    position:fixed;
    top:0;
    left:50%;
    margin-left:-52px;

    /* position fixed for IE6 */
    _position: absolute;
    _top:expression(documentElement.scrollTop);
}

.fixed-bottom-center{
    width:100px;
    height:100px;
    position:fixed;

    bottom:0;
    left:50%;
    margin-left:-52px;

    /* position fixed for IE6 */
    _position: absolute;
    _top:expression( documentElement.scrollTop+documentElement.clientHeight-this.offsetHeight );
}


展示頁面(Demo Page)

參考來源:上下左右置中、不隨頁面捲動的內容-小正正教室
2008-09-13 17:51

利用 JavaScript 讓 IE6 支援 CSS 2.0 hover 的方法

利用 IE6 特有的 expression 屬性質,去執行 JavaScript 程式。
好處是可以簡化開發,讓設計師可以自己去控制想要的樣式。
壞處是執行大量的 expression 會讓 IE6 很吃重。


ie_hover.htc 中的程式碼:
this.onmouseover=function(){
    if(!this.className.match(/(^|\s)hover(\s|$)/)){
        this.className=(this.className+' hover')
            .replace(/\s{2,}/g,' ')
            .replace(/^\s+|\s+$/g, '');
    }
}
this.onmouseout=function(){
    this.className=this.className
        .replace(/(^|\s)hover(\s|$)/,' ')
        .replace(/\s{2,}/g,' ')
        .replace(/^\s+|\s+$/g, '');
}
this.style.behavior=null;


ie_hover.html 中的 CSS:
p{
    padding-left:30px;
    behavior: url(ie_hover.htc);
}
p:hover,
p.hover{
    padding-left:0;
}


展示頁面(Demo Page)
2008-09-09 08:12

CSS 三欄排版

  1. float 排版
    CSS 三欄排版
    這是在 Table 排版之後最常見的排版方式,利用 float 與 clear 的屬性設定去達成的分欄排版。

    最近發現除了利用 clear 屬性的空 Tag 以外還有其他的方式可以達到這個效果,在最外層的 div 上加入以下屬性也可以達到相同的效果:
    * html #demo_1{
        height: 1%;
    }
    #demo_1:after {
        content: ".";
        display: block;
        height: 0;
        clear: both;
        visibility: hidden;
    }
    #demo_1 {
        zoom: 1;
    }
    


  2. table 排版
    CSS 三欄排版
    這是最早期排版方式,雖然有種種的缺點,但還是有很多網站使用,除了利用原有的 Table Tag,也可以使用其他 Tag 設定 display 屬性去達到 Table 排版的效果,雖然在寬度的定義上的彈性,但還是建議保持只有一個欄位的彈性寬度,過多的彈性寬度只會造成意想不到的後果。


  3. margin and float 排版
    CSS 三欄排版
    這是利用中欄的 margin 屬性空出側欄位空間,再利用 float 及負邊界方式去達成的三欄排版,因為 float 屬性不會對整體高度做出貢獻,如果需要側欄的高度影響,必須上擁有 clear 屬性的 Tag 或利用第一個範例的方法,由於中欄沒有 float 屬性所以不能在內容使用 clear 屬性。


  4. margin and position排版
    CSS 三欄排版
    這是利用中欄的 margin 屬性空出側欄位空間,再利用 position 的定位方式去達成的三欄排版,因為 position 屬性不像 float 屬性,可以利用 clear 屬性做出高度的貢獻,所以側欄的高度不可以大於主欄,要不然會造成顯示重疊。


  5. padding and float排版
    CSS 三欄排版
    這是結合 (float 排版) 及 (margin and float 排版) 的排版方式,主要是解決 (margin and float 排版) 的主欄中不可以使用 clear 屬性的問題,CSS 的差別只在於利用外匡的 padding 屬性去做預留空間的設定。


優劣差異:
floattablemargin
float
margin
position
padding
float
靈活性
親和力
HTML 結構簡單複雜簡單簡單簡單
寬度彈性noyesyesyesyes
允許彈性的欄位數0all111
overflow 容錯
瀏覽器的解析差異
欄位的高度影響allallall1all


展示頁面(Demo Page)
2008-06-01 19:34

HTML & Smarty、JavaScript、CSS 及 PHP 註解清除器

之前為了上線前去除不要的註解及多餘的空白符號,一直在找合適的工具,可是找到大部分都是 windows 的軟體,想找 Linux 的卻沒找到,於是就自己用 Lex 寫了一些,幾本上我分成四個語言的清除器,設計上是直接覆寫原始的檔案,所以在應用前請先自行複製備份,由於清除器沒有做語法驗證,再撰寫時需要特別嚴謹 ( PS: 程式碼中常被忽略的結束符號 ";" )。

清除規則:
  • HTML & Smarty
    • 清除 < 及 > 前後的空白及換行(\n)符號
    • 清除 HTML 註解 (<!-- 註解 -->)
    • 清除 Smarty 註解 ({* 註解 *})
    • 清除 JavaScript 單行及多行註解 (/* 註解 */ , //註解)
    • 清除 JavaScript 多餘的空白及換行(\n)符號
    • 完整保留單引號及雙引號內的字串
  • JavaScript
    • 清除多餘的空白及換行(\n)符號
    • 清除單行及多行註解 (/* 註解 */ , //註解)
    • 完整保留單引號及雙引號內的字串
  • CSS
    • 清除多餘的空白及換行(\n)符號
    • 清除多行註解 (/* 註解 */)
    • 完整保留單引號及雙引號內的字串
  • PHP
    • 清除行首及行尾的空白符號
    • 清除無用的空白行
    • 清除單行及多行註解 (/* 註解 */ , //註解)
    • 完整保留單引號及雙引號內的字串

這已經經過很多次的測試跟修改了,目前還沒有出現特別的狀況,有需要的人可以用用看,在 linux 上必許要安裝 flex 及 gcc 才可以編譯,當然 windows 也有的flex 及 gcc 的編譯器。

檔案連結
2008-05-03 22:00

JavaScript 效率優化

最近開始重視 JavaScript 的效率問題,原因在於感到自己寫的網頁越來越不流暢,其中大量的計算跟無法避免的迴圈愈來愈多,加上 UI 介面跟動態效果的需要,使得瀏覽器的負荷過大,所以這是個需要重視的問題,這直接的影響網站名聲的好壞。

要如何作效率優化呢?因為 JavaScript 是直譯語言,無法透過編譯器加以優化,所以只能從撰寫方式下手。

下面有一個效率很差的例子:
for (var i=0; i<data.length; i++) {
    document.getElementById("link").innerHTML += data[i];
    document.getElementById("link").hreh += "&" + data[i];
    document.getElementById("link").title += data[i] + ",";
    document.getElementById("link").className += data[i] + " ";
    document.getElementById("link").name += data[i] + "_";
}


當中有幾個影響效率的問題:
  1. 過渡的使用 getElementById 搜尋 DOM 物件,尤其是在 for 迴圈中
  2. 大量的存取 length、innerHTML 等成員變數
  3. 多次的存取 data[i],這跟上一個差不多



這些問題的修改方法:
/*利用暫存變數作處理*/
var temp1='', temp2='', temp3='', temp4='', temp5='';

/*利用 l 紀錄 length 的值,以避免多次存取成員變數*/
for (var i=0,l=data.length; i<l; i++) {
    /*利用 d 紀錄 data[i] 的值,以避免多次存取成員變數*/
    d = data[i];
    temp1 += d;
    temp2 += "&" + d;
    temp3 += d + ",";
    temp4 += d + " ";
    temp5 += d + "_";
}

/*利用暫存變數紀錄 DOM 物件*/
var link = document.getElementById("link");
link.innerHTML += temp1;
link.hreh += temp2;
link.title += temp3;
link.className += temp4;
link.name += temp5;



實驗 1000 筆資料的結果:
第 1 個耗時:5625(msec)
第 2 個耗時:47(msec)
展示(demo)

參考來源:
JavaScript loop performance
随時innerHTMLに書き込んだ場合と一括して書き込んだ場合
innerHTMLとinnerText/textContentの速度比較
getElementByID、変数、withによる参照速度比較
シリアルサーチと正規表現の速度比較
2008-05-02 22:56

用 JavaScript 作 HTML 比較(diff)

為了做到文字比較,我利用『最長共同部分序列』(Longest Common Subsequence)演算法,這是屬於動態規劃演算法的一種,特點就是以空間換速度,在比較過程需要 (m+1)*(n+1) 的記憶體空間,效率是 m*n,m 跟 n 的數量取決於文章的長度與切割的大小,我的切割方式是以空白符號及 HTML tag 作分界,對英文的切割有正向的優勢,所以在中文上就有點糟,但因為切割的長度大效率會比較快。
/*切割文字*/
function toReg(str){
    var array = str.match(/<[^>]*>|[^< ,.\r\n\t]+[ ,.\r\n\t]*/ig);
    result = [];
    for(var i = 0, l = array.length; i < l; i++) {
        if(array[i].charAt(0) == '<') {
            temp = array[i].match(/[^<][^> ]*/i);
            result[i] = {
                txt: array[i],
                tag: temp
            };
        }else{
            result[i] = {
                txt: array[i],
                tag: false
            };
        }
    }
    return result;
}

/*最長共同部分序列*/
function LCS(na, oa){
    var m = na.length, n = oa.length;
    var i, j;
    var d = [];

    /*Dynamic*/
    for(i = 0; i <= m; i++) {
        d[i] = [];
        d[i][0] = 0;
    }
    for(j = 1; j <= n; j++) {
        d[0][j] = 0;
    }

    /*動態規劃演算法*/
    for(i = 1; i <= m; i++) {
        for(j = 1; j <= n; j++) {
            if(na[i - 1].txt == oa[j - 1].txt) {
                d[i][j] = d[i - 1][j - 1] + 1;
            }else if(na[i - 1].tag && na[i - 1].tag==oa[j - 1].tag) {
                d[i][j] = d[i - 1][j - 1] + 1;
            }else if (d[i][j - 1] > d[i - 1][j]) {
                d[i][j] = d[i][j - 1];
            }else {
                d[i][j] = d[i - 1][j];
            }
        }
    }

    /*標註共同部分序列*/
    i = m;
    j = n;
    while (i > 0 && j > 0) {
        if(d[i][j] == d[i - 1][j]) {
            i--;
        }else if(d[i][j] == d[i][j - 1]) {
            j--;
        }else{
            i--;
            j--;
            na[i].com = j;
            oa[j].com = i;
        }
    }
    delete d;
}

/*合併比較陣列*/
function merge(na, oa){
    var m = na.length, n = oa.length;
    var result = [];
    if(!m && !n) { return null; }

    var i;
    var oldPrint = 0;
    for(i = 0; i < m; i++) {
        /*有共同的資料*/
        if(na[i].com != undefined) {
            /*有刪除的舊資料*/
            if(na[i].com > oldPrint) {
                var maxRow=(na[i].com < n) ? na[i].com : n;
                for(j = oldPrint; j < maxRow; j++) {
                    if(oa[j].tag) {
                        result.push(oa[j].txt);
                    }else{
                        result.push('<del>' + oa[j].txt + '</del>');
                    }
                }
            }
            /*記錄下一次舊資料的指標*/
            oldPrint = na[i].com + 1;
            /*儲存共同的資料*/
            result.push(na[i].txt);

        /*新的差異資料*/
        }else{
            if(na[i].tag) {
                result.push(na[i].txt);
            }else{
                result.push('<ins>' + na[i].txt + '</ins>');
            }
        }
    }
    return result;
}

展示(demo)
2008-04-06 22:50

MooCrop 正方形選取( Square )

MooCrop 是建構 MooTools 上的圖片裁切類別
不過本身沒有方形鎖定的功能
我利用一個簡單的觀念改寫原本的函數
將兩個方向的寬高同時加減
在初始為正方形的狀況下
不管如何縮放都會達成正方形

我還增加預覽裁切功能

範例(example)
展示(demo)
2007-10-13 13:26

線性代數 計算機

這是在讀二技時寫的,當初是用 C++ 去寫 RREF(),後來為了能有圖形介面,又用 Java 改寫,並且加了其他的運算進去,學了 JavaScript 之後又將他移到網頁上,基本上是用瀏覽器再做運算,在結構上整個語法並不是很好,當時學藝不精,不過功能上是正常的。

檔案連結
2007-09-23 17:07

利用 ASP 對 Access 資料庫重組

由於 Access 資料庫沒有支援的 SQL 指令可做重組 而且在做刪除資料時,還是不會將空間釋放出來 這種狀況只能從 Server 上做重組釋放的動作 但不是每個人都可以進入 Server 上做這個動作 所以另外的辦法就是從 ASP 網頁上執行
<%
'CompactDB 成功將回傳 true,失敗將回傳 false
'DBUrl 以主目錄開始的資料庫相對位址字串
'passwd 資料庫密碼,如果沒有請輸入空字串
Function CompactDB(DBUrl,passwd)
  Set fso = CreateObject("Scripting.FileSystemObject")
  Dim strDB
  strDB = server.MapPath(DBUrl)
  Dim strNewDB
  strNewDB = server.MapPath(DBUrl & ".tmp")

  Dim login
  If(passwd<>"") Then
    login = ";Jet OLEDB:Database Password=" & passwd & ";"
  Else
    login = ""
  End If

  If fso.FileExists(strDB) Then
      '壓縮資料庫
    Set Engine = CreateObject("JRO.JetEngine")
    strPvd = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
    Engine.CompactDatabase strPvd&strDB&login,strPvd&strNewDB&login
    Set Engine = nothing

      '刪除舊的資料庫
    fso.DeleteFile strDB
    fso.MoveFile strNewDB,strDB

      '回傳已成功的訊息
    CompactDB = true
  Else
      '回傳失敗訊息
    CompactDB = false
  End If
  Set fso = nothing
End Function
%>
檔案連結
2007-09-21 23:24

HTML 外出單 產生器

這是在軍中寫的一個外出單自動產生器
完全是用 Notepad 來寫的
經過很多次的修改
大部分能找到的錯誤都更改了
也許還會有學弟需要用到
所以在這裡貼出來

檔案連結
2007-09-19 01:31

利用物件的方式設定事件

這是我第一次使用物件的方式設定事件處理,以前都是用 HTML 去處理事件的呼叫,在利用 JavaScript 將表格模擬成按鈕中就是用這種模式去運作的,那麼用物件去設定有什麼好處呢?

第一用這個方法去處理的話,可以減少網頁檔案的大小,也減少 HTML 上的複雜度,讓網頁有更好的結構感,使 HTML 更容易閱讀,且更容易撰寫。

第二對於大量使用相同的事件有更好處理,重複使用性高,將程式碼獨立成個體的文件,只要在適當的位址中載入,就能重複使用相同的程式碼。

第三對於事件的新增及修改有更大的靈活度,不必在新增事件時要去改每個物件的 HTML,可以統一管理相同物件的新增及修改。

所以在大量使用相同程式碼時,這是一個不錯的選擇。
/* 取得所有名稱為 s_but 的物件群組 */
var spanButtons = document.getElementsByName("s_but");

/* 設定群組中每一個物件的事件 */
for (var i = 0; i < spanButtons.length; i++) {
/* 設定當滑鼠按下時的事件函數 */
spanButtons[i].onmousedown = downChange;
/* 設定當滑鼠重疊時的事件函數 */
spanButtons[i].onmouseover = overChange;
/* 設定當滑鼠離開時的事件函數 */
spanButtons[i].onmouseout = outChange;
}

/*Down Change*/
function downChange(){
this.style.borderStyle = "inset";
this.style.backgroundColor = "#EEDDDD";
}

/*Out Change*/
function outChange(){
this.style.borderColor = "";
this.style.borderStyle = "outset";
this.style.backgroundColor = "#FFFFFF";
}

/*Over Change*/
function overChange(){
this.style.borderColor = "#FF0000";
}
檔案連結
2007-09-03 04:54

利用 Date() 檢查日期格式

這是利用 JavaScript 中現有的函數 Date() 作日期驗證
使用的原理是將輸入值轉成正規的文字字串
再用 Date() 新增一個日期物件
如果是正確日期將會和輸入是一樣的字串
利用這個原理做到日期格式的驗證
/*-- (判斷日期格式是否正確) -------------------------*/
function isDate(year, month, day){
    var dateStr;
    if (!month || !day) {
        if (month == '') {
            dateStr = year + "/1/1"
        }else if (day == '') {
            dateStr = year + '/' + month + '/1';
        }else {
            dateStr = year.replace(/[.-]/g, '/');
        }
    }else {
        dateStr = year + '/' + month + '/' + day;
    }
    dateStr = dateStr.replace(/\/0+/g, '/');

    var accDate = new Date(dateStr);
    var tempDate = accDate.getFullYear() + "/";
    tempDate += (accDate.getMonth() + 1) + "/";
    tempDate += accDate.getDate();

    if (dateStr == tempDate) {
        return true;
    }
    return false;
}

/*檢查格式*/
isDate("2007/2/12")
isDate("2007-2-12")
isDate("2007.2.12")
isDate("2007/02/02")

isDate("2007", "2", "12")
isDate("2007", "2", "")
isDate(2007, 2, 12)

檔案連結