標籤

Web (5) 電腦 (4) 免費小工具 (2) 創意 (2) 雲端 (2) 電影 (2) PHP (1) jQuery (1) 吃的 (1) 好書 (1) 手機 (1) 網路 (1) 自我勉勵 (1)
顯示具有 Web 標籤的文章。 顯示所有文章
顯示具有 Web 標籤的文章。 顯示所有文章

2015-12-16

因為專案的關係,需要將某一隻擁有龐大的CSS庫的HTML頁面瘦身,所以撰寫這一隻程式。

CSS可以壓縮,但是當壓縮之後的檔案依然很大,而偏偏該HTML內所使用的class其實不多的時候,怎麼辦?

我想到的方法,就是將有用到的class自正在顯示HTML中的瀏覽器內取得,這樣是最精確無誤的,所以,這隻JS程式,就是在瀏覽器開啟這樣的HTML時使用的。

使用方法,就是將該JS安插進HTML內,當HTML被開啟時,即可以在console內看見所有的css了。

如果HTML內的element是會變動或是增減的,也就是說若是HTML顯示的css在不同的時機會有不同的顯示方式時,則可以在想要擷取css時,使用chrome的console內的命令列內下指令「dumpAllCss();」即可。

get_css_from_html.js

2010-08-13

閱讀「雲端策略」

雲端策略:雲端運算與虛擬化技術


「雲端運算」是2010年最夯的名詞,但是它是如何運行的?有哪些相關的技術?這本書是以IBM的角度來解釋雲端,書中絕大多數都是以IBM的技術觀點看待雲端,雖然我個人認為本書對於雲端運算的解釋略有不公,不過若是以一個IBM的外人,可以經由本書看見IBM對該企業的軟體服務如此詳細的說明,也夠值得了。

中華電信也提供雲端運算服務?

對於「雲端運算」一詞,可能已有「可能的權威」已經下了定義,但是從這名詞的氾濫程度來看,可以很肯定的知道,現在的每個網路相關產業都設法跟雲端沾上邊,就算是胡扯也值得。 
從前的主機租賃方案現在換個名詞就變成了雲端運算服務?不過就是自己丟個主機去中華電信機房,或是機房幫你購置架設一個主機,現在則是多一個「虛擬化主機方案」,如此而已。

完整的SDK才是雲端

對的,我個人主觀的認定「雲端運算」的主要元素是SDK,能夠提供極大效能與廣度的軟體應用平台的才是真正的雲端運算;就像Google App Engine一樣,有著完整的程式語言函式庫與開發環境,讓使用者開發應用系統時,得以專注於應用層面的開發,不再需要顧慮作業系統的差異、硬體環境的影響;只要開發雲程式與端程式之間的訊息交換與介面方式,其他的問題都交給雲端服務商即可。在此一定義下,中華電信的雲端運算服務自然不是我認為的雲端,不過就是裝個作業系統可以讓你Run,系統開發與環境的問題依然存在著。

IBM才是雲端的一種

IBM推行「軟體服務」已有相當久的時間了,雖然沒有確切的資料可以知道IBM從何時開始著手「整合性的軟體服務」(我記得應是2000年前就開始了),但是IBM努力至今,總算可以將「雲端運算」與「軟體服務」劃上等號了。IBM有著相當完整的企業應用函式庫,以及管理、分析、設計等服務的支持,它不像GAE那麼開放,卻也提供了相當充足的企業雲端應用方案了。

2010-08-01

HTML 5 隨寫

雖說現在開始玩HTML5可能為時已晚,但是總比都沒有起步好!
請看這「關於HTML5的Wiki
HTML5最具特色的是網頁上即時的畫面處理能力,以及資料暫存能力。

「畫面處理」可以讓網頁逐漸擺脫Flash的陰影,讓網頁可以直接以標籤與JavaScript繪製圖形,或是播放影片,這可是Adobe所不樂見的,也是一堆Flash工作者所抗拒的。
以我程式設計者的觀點而言,Flash實在是很不好的瀏覽應用方式,因為Flash不受規格控管,它只是一個Plugin;在Adobe獨立管理之下,很容易因為程式設計的技術、規格發散等問題,導致瀏覽端不穩定,造成系統安全問題。舉個例來說,就像是IE,一個獨自延伸規格的瀏覽器,僅僅靠著微軟以暴力手段將瀏覽器硬塞給使用者而坐大,從IE6起完全沒有進步,
IE7生命期不到一年,IE8這爛東西相繼推出且依然不知改進,只有換換介面容貌並聲稱將更為安全而了事,這就是獨立管理的問題。

「資料暫存能力」這我可就非常重視了,這功能是資訊系統的一大福音,它可以讓網頁瀏覽器暫存資料,就像是裝一個資料庫在瀏覽端;這個資料庫依然是以暫存為主,不適合用來作為主要儲存空間,它最大的功能,就是作為系統離線時的資料暫存空間,就像是Gmail,它已經支援這個暫存功能,可以在沒有網路連線的狀態下撰寫EMail並且發送,雖然沒有真的發送郵件出去,但是當下次網路連線正常時,該新增的郵件會在同步時被發送。

下面是HTML5的評分,依支援HTML5的程度評分,分數越高支援程度越好,反之則越差。
IE8依然是最低分(毫無建樹的瀏覽器),最高分的是Safari。
您也可以上到 http://www.html5test.com/ 看看自己使用的瀏覽器評分為多少。


Safari 5.0.1


Chrome 5.0.375.125



Firefox 3.5.7



Internet Explorer 8.0.7600.16385

2008-08-02

Enhance Select 讓網頁更美觀

最近玩 jQuery, 這工具不錯用, 但是在入門方面, jQuery確實需要較多的時間才能熟悉.

jQuery 是由 Google 所做的, 原本的目的是為了方便進行 HTML 文件的節點查詢, 應該算是輔助工具, 是作為快速選擇出節點的一種方法, 後來為了更多的應用需求, 就有了 Plugin 的能力(其實也不是特別去加強什麼Plugin, 而是因為 JavaScript的語法本來就較為鬆散, 所以 jQuery 就把某一種方式的語法規劃為 Plugin的語法).

更多的 jQuery 請看看官方網站(http://docs.jquery.com/Main_Page)囉!

至於 Enhance Select 這東西, 則是我對 IE 的無奈下的產物, 我一向是非常不爽 M$, 他把啥都綁在一起, IE 這麼多年來不見任何長進...

任何, 對! 我說的是任何長進都沒有! 就連我新買的 NB 的 Vista 上的 IE7, 連它都說它自己"還是 IE6"(User-Agent的內容), 所以, Firefox竄起是應該的.

有在寫網頁的都知道, IE的 Select物件是不支援大多數的 Style 的, 若是想改變 IE 的 Select 的框框粗細、大小、顏色, 這些是不可能的!

絕對不是 IE 不支援邊框的 style 喔! Input、TextArea、Table的邊框在 IE 上都被支援, 為何獨獨 Select 沒有, 可以說是 IE 的 Bug!? 不, 應該說是 M$ 懶得改! (所以我痛恨托拉斯, 也痛恨美國司法部的懦弱)

那, 難道為了一個 Select 所以我整個網頁設計都要被迫跟隨嗎?

還好有 jQuery... 我利用 jQuery 自己寫了一個 Enhance Select (jQuery的Plugin), 管它是 IE 還是 FF, 這個程式都會把原有的 Select 物件隱藏起來, 換上另一個較為美觀而且更容易自定 Style 的一個 Select 組件.

(注意! 要先會用 jQuery 喔! 這是 jQuery 的 Plugin!)

使用範例(將該網頁上所有的 Select 換成 Enhance Select):
<script type='text/javascript' src='jquery.enhance_select.0.6.js'></script>
<script type='text/javascript'>
$(document).ready(function(){
$('select').enhanceSelect();
});
</script>


範例圖(這是我開發中的產品的一角):

(那個"系統編碼"就是Enhance Select的效果)

程式碼如下:
/*
* jQuery enhance_select plugin
*
* Copyright (c) 2008 Howard Chen
*
* Licensed under the GPL license:
*   http://www.gnu.org/licenses/gpl.html
*
* Revision: $Id$
* Version: 0.6
*/

;(function($) {

$.fn.extend({
enhanceSelect: function(options)
{
if (parseInt(this.attr('size')) == 0)
return this.each(function(){
new $.enhanceSelectComboBox(this, options);
});
else
return this.each(function(){
new $.enhanceSelectMultiLine(this, options);
});
}
});

$.enhanceSelectComboBox = function(selectobj, options)
{
var mSelect = $(selectobj);

var opt = $.extend({
inputClass: 'enhanceSelect',
listClass: 'enhanceSelectList',
hoverClass: 'hover',
selectedClass: 'selected',
edit: false,
width: mSelect.css('width') == 'auto' ? mSelect.width()+20 : parseInt(mSelect.css('width'))+20
}, options);

var mSelectId = selectobj.id;
var mMove = -1;
var mMouseOver = false;
var mMouseDown = false;
var mFocused = false;
var mList = null;
var mInput = null;
var mInputModified = false;
var mSelectOptions = null;
var mDropDownList = false;
var mSelectedTop = -1;

genList();
genInput();
genOptions();

mSelect.hide().before(mInput).before(mList);
mList.append(mSelectOptions).hide();

mInput
.click(function(){
if (!mDropDownList)
dropDown(true);
else
dropDown(false);
mInput.select();
})
.focus(function(){
updateFocus(true);
})
.keydown(function(event){
switch(event.keyCode)
{
// up
case 38:
var li = $($('li.'+opt.selectedClass, mList).get(0));
if (li.prev('li').size() > 0)
{
li.removeClass(opt.selectedClass);
li.prev('li').addClass(opt.selectedClass);
updateSelect();
mInput.select();
}
return false;
// down
case 40:
var li = $($('li.'+opt.selectedClass, mList).get(0));
if (li.next('li').size() > 0)
{
li.removeClass(opt.selectedClass);
li.next('li').addClass(opt.selectedClass);
updateSelect();
mInput.select();
}
return false;
case 9:
case 13:
return true;
default:
if (!opt.edit)
mInput.select();
return false;

if (event.keyCode >= 32)
{
if (mDropDownList)
dropDown(false);
mInputModified = true;
}
}
})
.blur(function(){
if (!mMouseOver)
{
dropDown(false);
if (mInputModified)
{
updateSelect(mInput.val());
mInputModified = false;
}
else
updateSelect();
updateFocus(false);
}
});

mList
.mouseover(function(event){
mMouseOver = true;
})
.mouseout(function(event){
mMouseOver = false;
})
.dblclick(function(eve){
if (window.getSelection)        window.getSelection().removeAllRanges();
else if(document.selection)     document.selection.empty();
})
.mousemove(function(){
if (window.getSelection)        window.getSelection().removeAllRanges();
else if(document.selection)     document.selection.empty();
})
.click(function(){
dropDown(false);
})
.blur(function(event){
if (!mMouseOver)
{
dropDown(false);
updateSelect();
updateFocus(false);
}
});

function genList()
{
mList = $(document.createElement('div'));
mList
.addClass(opt.listClass)
.attr('id', mSelectId+'_list');
}

function genInput()
{
mInput = $(document.createElement('input'));
mInput
.addClass(opt.inputClass)
.attr({
id: mSelectId+'_input',
type: 'text',
autocomplete: 'off',
tabIndex: mSelect.attr('tabindex')
})
.css({
width: opt.width
});

if (!opt.edit)
mInput.attr('readonly', 'readonly');
}

function genOptions()
{
mSelectOptions = document.createElement('ul');
mSelect.children('option').each(function(){
addOption({
val: $(this).val(),
html: $(this).html(),
selected: $(this).is(':selected')
});
});
}

function addOption(options)
{
var aopt = $.extend({
html: '',
val: '',
selected: false
}, options);

if (aopt.val == '' && options.html)
aopt.val = options.html;
if (aopt.html == '' && options.val)
aopt.html = options.val;

var li = document.createElement('li');
mSelectOptions.appendChild(li);

li = $(li);
li
.attr('id', aopt.val)
.html(aopt.html)
.mouseover(function(event){
$(event.target, mList).addClass(opt.hoverClass);
})
.mouseout(function(event){
$(event.target, mList).removeClass(opt.hoverClass);
})
.click(function(event){
$('li', mList).removeClass(opt.selectedClass);
$(this).addClass(opt.selectedClass);
updateSelect();
dropDown(false);
mInput.select();
});

if (aopt.selected)
{
mInput.val(aopt.html);
$('li', mList).removeClass(opt.selectedClass);
li.addClass(opt.selectedClass);
}

return this;
}

function dropDown(val)
{
if (val === null)
return mDropDownList;
if (val != mDropDownList)
{
if (val === true)
{
updateFocus(true);
var MaxHeight = parseInt(mList.css('max-height'));
MaxHeight = MaxHeight > 0 ? MaxHeight : 200;
if (mList.height() > MaxHeight)
mList.css('height', MaxHeight);
mList.css('width', opt.width+18).show();
mDropDownList = true;
mInputModified = false;
mList.attr('scrollTop', 0);
if ($('li.selected', mList).size() > 0)
mList.attr('scrollTop', $('li.selected', mList).offset().top-$('li', mList).offset().top);
}
else
{
mList.hide();
mDropDownList = false;
}
}
return this;
}

function val(newVal)
{
if (newVal === null)
return mInput.val();
$(mSelectOptions).children('li').removeClass(opt.selectedClass);
$(mSelectOptions).children('li #'.newVal).addClass(opt.selectedClass);
updateSelect();
}

function updateFocus(val)
{
if (val != mFocused)
{
mFocused = val;
if (mFocused)
mInputModified = false;
}
}

function updateSelect(val)
{
if (val != null)
{
var newOption = document.createElement('option');
mSelect.get(0).appendChild(newOption);
newOption.value = val;
newOption.selected = true;
mInput.val(val);
}
else
{
var li = $($('li.'+opt.selectedClass, mList).get(0));
mSelect.val(li.attr('id'));
mInput.val(li.html());
}
mSelect.trigger('change');
}
};

$.enhanceSelectMultiLine = function(selectobj, options)
{
var mSelect = $(selectobj);

var opt = $.extend({
listClass: 'enhanceSelectList',
hoverClass: 'hover',
selectedClass: 'selected',
width: mSelect.css('width') == 'auto' ? mSelect.width()+20 : parseInt(mSelect.css('width'))+20
}, options);

var mSelectId = selectobj.id;
var mFocused = false;
var mList = null;
var mSelectOptions = null;
var mSelectedTop = -1;

genList();
genOptions();

mSelect.hide().before(mList);
mList.append(mSelectOptions);

mList
.dblclick(function(eve){
if (window.getSelection)        window.getSelection().removeAllRanges();
else if(document.selection)     document.selection.empty();
})
.mousemove(function(){
if (window.getSelection)        window.getSelection().removeAllRanges();
else if(document.selection)     document.selection.empty();
})
.focus(function(){
updateFocus(true);
})
.blur(function(event){
updateSelect();
updateFocus(false);
});

function genList()
{
mList = $(document.createElement('div'));
mList
.addClass(opt.listClass)
.attr('id', mSelectId+'_list')
.css({
width: opt.width
});
}

function genOptions()
{
mSelectOptions = document.createElement('ul');
mSelect.children('option').each(function(){
addOption({
val: $(this).val(),
html: $(this).html(),
selected: $(this).is(':selected')
});
});
}

function addOption(options)
{
var aopt = $.extend({
html: '',
val: '',
selected: false
}, options);

if (aopt.val == '' && options.html)
aopt.val = options.html;
if (aopt.html == '' && options.val)
aopt.html = options.val;

var li = document.createElement('li');
mSelectOptions.appendChild(li);

li = $(li);
li
.attr('id', aopt.val)
.html(aopt.html)
.mouseover(function(event){
$(event.target, mList).addClass(opt.hoverClass);
})
.mouseout(function(event){
$(event.target, mList).removeClass(opt.hoverClass);
})
.click(function(event){
$('li', mList).removeClass(opt.selectedClass);
$(this).addClass(opt.selectedClass);
updateSelect();
});

if (aopt.selected)
{
$('li', mList).removeClass(opt.selectedClass);
li.addClass(opt.selectedClass);
}

return this;
}

function val(newVal)
{
if (newVal === null)
return $($('li.'+opt.selectedClass, mList).get(0)).attr('id');
$(mSelectOptions).children('li').removeClass(opt.selectedClass);
$(mSelectOptions).children('li #'.newVal).addClass(opt.selectedClass);
updateSelect();
}

function updateFocus(val)
{
if (val != mFocused)
mFocused = val;
}

function updateSelect(val)
{
if (val != null)
{
var newOption = document.createElement('option');
mSelect.get(0).appendChild(newOption);
newOption.value = val;
newOption.selected = true;
}
else
mSelect.val($($('li.'+opt.selectedClass, mList).get(0)).attr('id'));
mSelect.trigger('change');
}
};

})(jQuery);

2008-07-30

兩天了, 為了測一個不明原因的錯誤, 差點被搞瘋了.

最近, 為了產品 HowIM 如火如荼的研發與測試, 總是搞到早上才睡.

HowIM 是什麼? 以後再介紹了.

至於那個讓我測了兩天的問題, 就是 eAccelerator 所產生的, 且聽我概略的描述一下.

首先, 這個 HowIM 產品使用了 Apache + PHP + Sqlite3 作為網頁端的程式架構, 並且在 PHP 多加了 eAccelerator 模組, 以作為加速之用.

由於這產品的某些網頁對於資料的讀取速度有著相當高的要求, 故需要一種共用記憶體的功能, 最好是類似於 ASP 的 Application, 用以減少資料庫的存取.

大約在上個月, 我在網上檢索了所有有關的功能選項, 經大量測試後發現, 在 Windows 上 eAccelerator 提供的共用記憶體功能較為穩定, 而且程式還滿好寫的.

在相關的測試完成後, 我開始在這產品大量使用 eAccelerator 的共用記憶體功能, 主要的函數包括: eaccelerator_lock, eaccelerator_unlock, eaccelerator_get, eaccelerator_put.

在此一階段的開發告一段落時, 我用了其他手邊的電腦測一下, 發現了一個重大的問題, 那就是 eAccelerator 有將共用記憶體依照 $_SERVER['SERVER_NAME'] 分類.

怪怪, 我先前的測試自認是很充足的, 這部分也曾測試過無誤才對, 竟然到現在才發現此一問題.

這問題害我多花了四個小時找替代方案, 在所有的替代方案皆失敗時, 我才又回去找原因起頭.

偏偏網路上對於 eAccelerator 的都是"天下文章一大抄", 少有見解與詳細說明的, 而官方的網站卻又是亂七八糟(據說是停站或是eAccelerator停止開發? eAccelerator網址).

再另外花下了數小時的搜尋時間後, 總算想到了方法, 就是回去看看 eAccelerator 的 Source Code.

終於被我找到了(在 eaccelerator.c 與 cache.c), 原來 eAccelerator 在 php.ini 裡可以設置 eaccelerator.name_space, 這個 eaccelerator.name_space 是所有 eAccelerator 鍵值的 name_space.

當 eaccelerator.name_space 沒被設置時, eAccelerator 會把 $_SERVER['SERVER_NAME'] 當作 Name Space.

也就是說, 假定本機的 IP 是 192.168.11.22, 則在本機使用 http://localhost 與 另一台遠端電腦用 http://192.168.11.22 的網址, 同樣查詢本機的 Apache 時, 所使用的鍵值是被隔開的, 就算是同樣存取同一鍵值也會完全不相干.

在改了 php.ini, 加了 eaccelerator.name_space 後, OK了, 鍵值都相同了.

附加說一下, Windows 下的 PHP 還有其他的共用記憶體方案, 如: MMCache, shmop, 這些方案的問題更大, 會導致 Apache 莫名其妙的當掉, 完全不能用.