JavaScript 函式筆記
喔要做法令易讀器於是翻了JavaScript的文章,筆記一些如下:
......
... read more
我不了解瞎子,因為未曾閉眼欣賞煙火。
今年,我生平第一次考了大學指考。
雖然確實也會去找工作,但我仍想保有「學生」身分,以便享受各種優惠和學校資源。雖然要再考個碩班或博班也是不錯的選擇,但不想搞研究的我,還是選擇在準備論文之餘,花個三、四週準備大學聯招指考。
為了在提倡性開放和性交易之時可以自保,並且為同志平權出一份力,我選擇的目標是法律系(也因此,以往擅長的理科就直接不準備);而為了省錢並且要有夠多的學校資源,志願序仍是以國立大學優先;為了實際接觸各團體(諸如同志熱線、日日春、愛滋權促會),我選擇台北。
不過看樣子考的並不理想,以下是各科成績和心得(試題與選擇題答案請參考大考中心網站),順序請容我調動:
年初的海地7.0強震考了兩題,其他部分也不會很難作答。有碩班將畢業的朋友聽我提到4-6, 13-14這幾題的可笑之後,在沒準備的狀態下拿題目來做,也有62分。
我覺得全國地理最高分是93分已經是出奇的低了,結果報考公民的四萬多個考生,最高分居然只有83分多(而且這還是唯一沒有非選題的科目)!!??今年好歹也有155個科系採計啊..
公民是被我排在地理和歷史之後才準備的科目,但卻是最讓我「感動」的科目,而它讓我感動的原因就在於:它是跟現實生活最為貼近的科目。第一冊是加深國中公民課的深度,提及心理學、性別平等、婚姻、家庭、群體、文化;第二冊是法律,包含刑法、民法、行政法,還有訴訟程序(其中關於「繼承」的段落是我覺得甚至應該被列做必考的生活常識);第三冊則是政治和憲法;第四冊則是經濟。除了第一冊之外,全都是我們就算不看電視新聞也都會實際運用到的東西,但是採計的科系和認真唸它的人卻這麼少,真是讓人痛心!!
考題部分其實也出得很實際,包含了家暴法(第2題)、性別平等(第3題)、高等教育現象(第4題)、媒體現象(第5題)、同志平權(第6題)、社會運動(第7題)、墮胎民意趨勢(第8題,出題老師們大概還是不敢碰廢死議題)、名譽損害(第11題)、隱私權(第12題)、弱勢特權(第13題,我答錯了,但覺得我的選項才是對的)、國家賠償與國家補償的差異(第15題)、釋憲門檻(第16題)....,我甚至覺得這科應該叫做「公民與『道德』」,也在此懇請看文的各位研究一下這些考題跟現實中的社會議題。
完全沒準備的科目,不過畢竟七年來除了課業之外,逛網路時常看原文網站也多少有幫助,所以這個分數並不意外,相比之下是最問心無愧的分數。
但也不是沒有可檢討之處。作文題目[Smell]讓我想了好久到底應該寫哪個方向。直覺上是飲食類的描述,但除了香、臭之外,酸、甜、苦、辣中後兩者的英文我卻是怎麼也想不起來。後來雖然抱著搞笑的心態寫了[精液的氣味],但似乎把「自慰」(masturbation)拼錯了。
題型是我中學時就覺得很不解的出法,21至35題共佔20%,但答題方式卻跟小學時的「連連看」沒有兩樣,也就是說確定某幾題之後,要猜對其他題就很容易了(因為可能的選項變少)。
原本是最害怕的科目,結果雖然確實沒有考好(比均標差0.3分,幸好登記分發沒有指考標的限制),但沒考好的原因卻不是原本擔心的國學常識或古文釋義判斷,而是沒戴錶又忘了國文的時間根本不夠的我,作文(佔27%)只寫了一段。
跟小時候聽到的聯考方向相比,白話文文意判斷真是讓我又驚又喜,除了比例不低於古文釋義判斷之外(7, 11-15, 19這幾題都是白話文),問的方式也很像是英文的閱讀測驗;而16, 17題雖是文言文,但考的是基本邏輯和人格,要答錯也很困難。
我覺得考這分數很丟臉,請容許我逃避。
不愧是背科,我幾乎跳過沒讀的有機物考很多,不過電子軌域似乎就還好,其餘則大多是實驗題。
雖然沒寫完,但其實自己原本預期是有55分的呢....物理是我高中時覺得可以靠「背公式」就順利解決的科目,但這次沒能湊出時間溫習那些七年沒碰的公式,導致電磁學的部分和光學名詞定義的部分失分嚴重。
居然有均標,真是莫名其妙!明明高三起就沒碰生物的我應該是這科要考最差的啊!
以目標是法律系來說,歷史不到均標是蠻詭異的事情,但我真的背不起來嘛....
本週一成績公布後,為了確實評估自己的落點,於是做了一個大考分發科系資料查詢,可以查詢各科系前三年的最低錄取分數和加權平均(另徵求96年(含)以前各科系採計權重的Excel檔或網頁)。原本看來,應該會是在東吳大學。但結果公布是在輔大,那就試試跨系修體育課去騷擾體育健將們吧
不過週三(2010-07-21)時大考中心公布了:明年指考跟學測都不倒扣(詳見新聞稿),所以我的系統如果真要改成完整的落點分析的話,難度就又變更高了呢....
......原本是想要看看PHP Plurk API,在亂點roga部落格的MySQL分類時看到了roga大在去年六月有在想SQL的問題,於是心血來潮地試了一下。
DELETE FROM tbl
USING tbl INNER JOIN (
SELECT id, count(*) AS place
FROM (
SELECT t1.id
FROM tbl AS t1, tbl AS t2
WHERE t1.url_id = t2.url_id
AND t1.id <= t2.id
) AS t3
GROUP BY id
) AS t4
WHERE tbl.id = t4.id
AND t4.place > 1500
其中tbl是roga大大的url_detail_history,單純是名字太長所以被我換掉。此法受限於資料庫系統對Multiple-table DELETE的支援度,已知MySQL支援。SELECT MAX(id) FROM tbl WHERE url_id = 'XXXX'
SELECT url_id, COUNT(*)
FROM tbl
GROUP BY url_id
雖然沒什麼困難,不過我們稍比較一下這個和前一個SQL後會發現:SELECT id
FROM tbl
WHERE url_id = 'XXXX'
ORDER BY id DESC
LIMIT n
+---------+-------+
| student | score |
+---------+-------+
| 1 | 7 |
| 2 | 5 |
| 4 | 3 |
| 5 | 4 |
+---------+-------+
而我們要產出的結果為:+---------+-------+-------+
| student | score | place |
+---------+-------+-------+
| 1 | 7 | 1 |
| 2 | 5 | 2 |
| 4 | 3 | 4 |
| 5 | 4 | 3 |
+---------+-------+-------+
也就是學生1是第一名;學生5是第三名;...SELECT t1.student, t2.student
FROM ss AS t1, ss AS t2
WHERE t1.score <= t2.score
結果為:+------------+------------+
| t1.student | t2.student |
+------------+------------+
| 1 | 1 |
| 2 | 1 |
| 2 | 2 |
| 4 | 1 |
| 4 | 2 |
| 4 | 4 |
| 4 | 5 |
| 5 | 1 |
| 5 | 2 |
| 5 | 4 |
+------------+------------+
SELECT t1.student
FROM ss AS t1, ss AS t2
WHERE t1.score <= t2.score
假設這張表叫做t3,那麼「列出分數不比自己低的人的總數」,SQL指令就是:SELECT student, COUNT(*)
FROM t3
GROUP BY student
(有沒有覺得最後的指令簡潔到令人吐血?)SELECT student, COUNT(*) AS place
FROM (
SELECT t1.student
FROM ss AS t1, ss AS t2
WHERE t1.score <= t2.score
) t3
GROUP BY student
得出來的就會是名次列表+---------+---------+-------+
| student | subject | score |
+---------+---------+-------+
其中Primary Key為(student, subject),那麼題目就變成「各學生在各科目的排名」,SQL指令為:SELECT student, subject, COUNT(*)
FROM (
SELECT t1.student, t1.subject
FROM ss AS t1, ss AS t2
WHERE t1.score <= t2.score
AND t1.subject = t2.subject
) t3
GROUP BY student, subject
DELETE FROM tbl
USING tbl INNER JOIN (
SELECT id, count(*) AS place
FROM (
SELECT t1.id
FROM tbl AS t1, tbl AS t2
WHERE t1.url_id = t2.url_id
AND t1.id <= t2.id
) AS t3
GROUP BY id
) AS t4
WHERE tbl.id = t4.id
AND t4.place > 1500
至於哪邊用大於,哪邊用小於,可得想清楚了....前置作業:
連線到資料庫通常都很好解決(如果MySQL Server有設定好的話):mysql_connect('localhost', 'username', 'password');
mysql_select_db('myDB');
這段程式碼通常會寫在一個給所有頁面引入的檔,假設上面兩行被我們存檔為"database.php",那麼遇到需要對資料庫連線的時候只要PHP呼叫:require_once 'database.php';
就可以了。這個方法也可以應用在其他想要在每個頁面上做的事情(像是紀錄IP、檢查是否已登入之類的)。
不過只是這樣子有時會有點風險,比方說如果資料庫不是自己設定的,但我們又必須指定編碼(目前的趨勢是使用UTF-8)的話,就得加上一句"SET NAMES 'UTF8'"的SQL,以防止一些亂碼的狀況發生,當然這個前提是你的網頁也是用UTF-8編碼。連線的設定可能就會變成: $db_server = 'db.mycom.com';
你可能會覺得先把帳號密碼寫在變數裡這件是有點多餘,不過實務面上我們很有可能還會把「帳號資料」和「連線」這兩個區塊分開--通常是做很大的站台的時候。比方說我可能某個頁面同時要跟Google、Yahoo!和FaceBook做連線,那麼我就會分開寫兩個檔:
$db_user = 'kong0107';
$db_password = '********';
$db_name = 'test';
mysql_connect($db_server, $db_user, $db_password);
mysql_select_db($db_name);
mysql_query("SET NAMES 'UTF8'"); /* 這個檔叫做config.php */
$db_server = 'db.mycom.com';
$db_user = 'kong0107';
$db_password = '********';
$db_name = 'test';
$google_user = 'kong0107';
$google_password = 'hahaha';
$yahoo_user = 'kong_crazykid';
$yahoo_password = 'oh my god';
$fb_user = 'kong0107@gmail.com';
$fb_password = 'this is longer'; /* 這個檔叫做service_connection.php */
看吧,只是連線而已就已經開始讓人頭昏眼花,而且我們根本還沒有開始真正操作什麼呢!所以還是把一些設定(諸如帳號、密碼)通通寫在同一區,這樣子之後要改才比較方便。(註:那些API的實際使用方法應該不是這樣子,我只是隨便舉個例子。但總之通常只會更複雜)
require 'config.php'; /*就會把上面那個檔案叫進來*/
mysql_connect($db_server, $db_user, $db_password);
mysql_select_db($db_name);
mysql_query("SET NAMES 'UTF8'");
require_once 'google_api.php'; /*把google的API(最重要的是連線function)叫進來*/
$google = new GoogleAPI();
$google->connect($google_user, $google_password);
require_once 'yahoo_api.php';
$yahoo = new yahooAPI();
$yahoo->connect($yahoo_user, $yahoo_password);
require_once 'facebook_api.php';
$fb = new facebookAPI();
$fb->connect($fb_user, $fb_password);
SELECT id, name FROM student
SELECT * FROM student
ORDER BY id ASC
其中"ASC"是表示遞增排序(遞減排序則是DESC)在這邊要注意幾點事情:
SELECT `id`, `name`
FROM `student`
WHERE `id` < 10
ORDER BY `id` DESC
SELECT * FROM student WHERE name = '高睿甫'
SELECT *
FROM message
WHERE content = '野村克也說\'要讓一個選手墮落很簡單啊,只要稱讚他就行了!\'他說的真是太忠肯了'
PHP執行SQL的指令是mysql_query()(注意:當然要先對資料庫連線,再執行mysql_query()才有意義),有時我們會把SQL直接寫在裡面:$res = mysql_query("SELECT * FROM student");
不過如果是像上面有比較長的SQL,我倒是比較建議先另外丟進變數裡:$sql = "SELECT `id`, `name`
也別忘了PHP的字串裡面是可以直接換行的(題外話:如果你有在寫JavaScript的話,請注意JavaScript並不能直接這樣做喔)
FROM `student`
WHERE `id` < 10
ORDER BY `id` DESC";
$res = mysql_query($sql);
有注意到我都把mysql_query()回傳的東西丟給$res變數嗎?那就是我們接下來要操作的東西囉
$res = mysql_query("SELECT * FROM student");
$row1 = mysql_fetch_assoc($res); /*第一列*/
$row2 = mysql_fetch_assoc($res); /*第二列*/
$row3 = mysql_fetch_assoc($res); /*第三列*/
注意我們其實是在執行同一個function,但是每次卻回傳不同的結果喔!當然你應該不會想這麼呆呆的把整張資料表取完,這種時候就得用上迴圈啦。但是面對不知道SQL回傳的結果有幾筆資料的時候,回圈應該要在什麼時候停止呢? $res = mysql_query('SELECT * FROM student');
while($row = mysql_fetch_assoc($res)) {
/* 這裡就看你想對這一筆資料幹嘛*/
echo $row['id']; /*像這樣就可以印出該學生的學號*/
}
$res = mysql_query('SELECT `id`, `name` FROM `student`');
echo '<table>';
while($student = mysql_fetch_assoc($res)) {
echo '<tr>';
echo '<td>';
echo $student['id'];
echo '</td>';
echo '<td>';
echo $student['name'];
echo '</td>';
echo '</tr>';
}
echo '</table>';
像是這樣,不過輸出的部份我自己比較喜歡另一個方式:<table>
<?php
while($student = mysql_fetch_assoc($res)) {
?>
<tr>
<td><?=$student['id']?></td>
<td><?=$student['name']?></td>
</tr>
<?php
}
?>
<table>
就是這樣囉,或是看你想怎麼顯示都可以。 $id = 9646515;
$res = mysql_query("SELECT * FROM student WHERE id = $id");
$kong = mysql_fetch_assoc($res);
$name = $kong['name'];
echo "學號$id 的學生,他的名字是$name";
$res = mysql_query("SELECT id FROM student");
$row1 = mysql_fetch_assoc($res);
echo $row1['id'];
$row2 = mysql_fetch_row($res);
echo $row2[0];
$row3 = mysql_fetch_array($res);
echo $row3['id'];
echo $row3[0];
$txt = $_GET['search'];
$sql = "SELECT * FROM message WHERE content = '$txt'";
// 還記得字串要加上單引號吧..
不過以這個例子來說,我們又必須小心使用者輸入的東西本身就有單引號。比方說使用者輸入了"我好傷心喔 T_T'",那麼整個SQL丟給MySQL的時候就會變成SELECT * FROM message WHERE content = '我好傷心喔 T_T''
然後就發生錯誤啦(因為MySQL看不懂那些引號是怎麼回事)$txt = str_replace("'", "\\'", $_GET['search']);
/* 如果你看不懂那個"\\'",就先照做吧....*/
$sql = "SELECT * FROM message WHERE content = '$txt'";
$id = $_GET['id'];
$sql = "SELECT * FROM message WHERE id = $id";
可是,如果使用者在表單中,根本不是打數字的話(比方說使用者什麼都沒打),SQL就會變成SELECT * FROM message WHERE id =
於是就產生錯誤了(因為等號後面不是數字)。$id = str_replace("'", "\\'", $_GET['id']);
$sql = "SELECT * FROM message WHERE id = '$id'";
$sql = "SELECT * FROM message WHERE id = %d";
$sql = sprintf($sql, $_GET['id']);
以上兩個方法都可以應付使用者亂打的狀況 SELECT * FROM car
WHERE brand = 'BMW'
AND oilCart > 2000
AND price < 700000
如果我們是使用sprintf()的話,就可以用比較容易懂得簡短程式碼來執行(簡潔易懂的程式碼可以幫助自己或他人後續的除錯和更新):$sql = "
SELECT * FROM car
WHERE brand = '%s'
AND oilCart > %d
AND price < %d
";
$sql = sprintf($sql, $_GET['brand'], $_GET['oilCart'], $_GET['price']);
這只是個比較簡單的例子,但如果是遇到像是需要報表、統計這一類需要跨多的資料表的SQL,使用sprintf()的替代方式可以讓你快速的編輯和除錯。
作者: cole945 (躂躂..) 看板: Ajax
標題: Re: [問題] 如何在ie下面debug
時間: Sun Aug 19 01:22:27 2007
在IE的 Intenet Options 的 Advanced 頁面設定裡有個
"Disable script debugging"
預設是勾起來的..
如果有勾的話, 就算有錯誤也不會顯示~ 請把他取消掉..
如果你還需要更進階的debug功能的話再往下看~
不然就這裡你就可以按 <- 離開了 囧"
IE還可以透過Microsoft Script Editor(簡稱MSE)或Visual Studio(簡稱VS)來偵錯
(包括Step by step執行 或是變數監看等等..)
如果有灌 VS 2002以上的版本會自動與 IE 整合,
遇到錯誤選 yes 進行除錯並選擇 Visual Studio就可以了~
可是VS有點肥:x 正常寫Javscript的人應該不會想用那個除錯..
MSC則是附在Office/Frontpage裡(好像XP的版本以上就會有了..)
(應該是要含Frontpage的office版本或單Frontpage也會有)
先確認你的電腦是否已安裝 MSE,
打開 IE 在功能表的 View->Script Debugger->Open
如果有 Misrosoft Script Editor 那就是有安裝了
若沒有的話拿出你的Office補安裝,
選擇 新增/移除功能 -> 選進階自訂 ->
在 Office Tools 的分類下面應該會有個 HTML Source Editing
全部都勾起來 (Frontpage其實可以不用灌, 有勾這個就夠了)
再重開IE就可以了~
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.139.142.115
在做清大科管所的clay0529學長的BuzzShare(可以自己選擇廣告的插入廣告服務,Mr.6有分享過喔:P)的時候用了這樣的方法,在此分享。簡言之就是在使用者要離開的時候引入一個檔案囉,麻煩的是要怎麼得知「下一頁」是什麼:P。
步驟一:當然要先紀錄進入頁面的時間,用now = new Date();
就可以了
start = now.getTime();
步驟二:寫一個要在離開頁面的時候執行的function。因為你不一定會想改(或說不一定能改)<body />的onunload標籤,而直接把window.onunload覆寫掉也不是個好辦法(因為可能已經有設定別的東西要執行了),所以最好是用attachEvent或是addEventListener,可以參考【Javascript: 附加 onload 事件】。function whenLeaving() {
var now = new Date();
var stayTime = now.getTime() - start;
addJavaScript('abc.php?stayTime=' + stayTime);
/*addJavaScript()是我之前寫的一個可以加入JavaScript的function(原本主要是拿來做XSS用的)
要注意的是不可以用document.write來生成<script />,否則會有想是換頁的情形發生
喜歡的話,用CSS(用我的addStyleShett)甚至是圖片也可以
至於如何不使用document.write來生成物件,可以查一下document.createElement()
另外,abc.php到底要output什麼出來就隨便囉
我自己是都留白(單純只把資料寫進資料庫,不做任何輸出)....*/
}
if(window.addEventListener)
window.addEventListener('load', whenLeaving, false);
else if (window.attachEvent)
window.attachEvent('onload', whenLeaving);
/*其實可以另外寫一個function來做這件事*/
function addEvent(obj, event, func) {
if(window.addEventListener)
obj.addEventListener(event, func, false);
else if (window.attachEvent)
obj.attachEvent('on'+event, func);
}
原則上到這裡就可以記錄使用者停留時間了。
步驟三:修改<a />的onclick,取出接下來要進入的頁面的連結
我原本以為下面這樣就可以了tagA = document.getElementsByTagName('a');
不過至少在IE下會發生i值變動的問題。幸好這個問題在我之前在無名的Homepage板問過之後,星周(starjou)學長有解答過(簡言之就是用區域變數來繞過全域變數的問題),所以迴圈的部份改成下面這樣:
for(i = 0; i < tagA.length; i++)
addEvent(tagA[i], 'click', function(){next = tagA[i].href;});for(i = 0; i < tagA.length; i++) {
function a() {
var j = i;
addEvent(tagA[j], 'click', function(){next = tagA[j].href;});
}
a();
}
步驟四:再修改一下步驟二的函數
把原本要引入的檔案多加上「下一頁」的參數囉addJavaScript('abc.php?stayTime='+stayTime+'&nextPage='+next);
這個方法原則上也可以用XSS的方法來做(事實上BuzzShare的部份我就是這樣子做)。另外就是我目前沒有處理表單送出的部份(頁面停留時間仍然可以記錄,但是「下一頁」就無法判斷了),當然表單還是可以用修改onsubmit的方式來修改,但是要注意的是有些表單(其實<a />也有可能)會被其他的JavaScript更改傳送頁面,所以實做上並不一定可以得知實際被傳送的頁面。(其實我是有想到解決辦法啦,但是有點難解釋,而且也沒有把握一定可行)
另外就是attachEvent()和addEventListener()的問題,由於前者會先執行最後被指定的function,所以有時後有點麻煩,此時可以用另一個方法解決這個問題(後來仔細想想,這個方法好像比較好...orz)var oldOnload = window.onload || function () {};
window.onload = function ()
{
oldOnload();
/* Do Something... */
}
後記:我真的希望我可以多花時間在音樂上面。......
... read more
昨天去苗130還願(當初我根本沒去,不過既然爸媽去拜過了,跟去一下也不錯),那瞭望台的風景不錯,發現自己雖然家住16樓但還是會怕高,想起高中坐大怒神時根本不敢張開眼睛的情況。
回來之後就在兩個網站之間徘徊,去Street Voice申請了帳號也把幾首歌傳了上去,整體而言比滾石可樂好多了(滾可的系統也10年了吧?? @.@),不過速度好像也沒有比Blogger快多少(我想是因為我放了Prototype.js才讓Blogger變慢的)。
另外就是做了一個AddrBalance(亂取的名字),主要是通訊錄和記帳功能,不確定是不是弄得夠安全(懶得做防呆),總之目前先po在無名的個板(P_LifeOMusic)和PHP板,如果沒有被Hack的話再po到PTT給大家用看看..cc......
... read more
我很喜歡用multi-dimensional array來傳送表單資料(印象中在ASP不能直接這樣用),可是這樣的東西在做分頁界面的時候很難還原成URL,所以就寫了一個array2url:function array2url($arr,$main='') {
$tmp = array();
foreach($arr as $key=>$val) {
$prefix = $main ? sprintf('%s[%s]', $main, $key) : $key;
$tmp[] = is_array($val) ? array2url($val, $prefix) : "$prefix=$val";
}
return implode('&',$tmp);
}
範例: $abc = array(
'ohmyhoney' => array(
'recede' => 941505,
'tbex' => array(
'school' => 'nctu',
'department' => 'cs'
)
),
'bango' => 'banco'
);
echo array2url( $abc );
結果:ohmyhoney[recede]=941505&ohmyhoney[tbex][school]=nctu&ohmyhoney[tbex][department]=cs&bango=banco
所以之後就可以: $arr = $_GET['arr'];
unset( $arr['page'] );
for( $page = 1; $page <= $amount / $records_per_page; $page++ )
printf(
'<a href="http://www.blogger.com/webpage.php?%s&page=%d">第 %d 頁</a>',
htmlentities( array2url( $arr ) ),
$page,
$page
);
比較討厭的是因為寫成recursive function,所以連結的部份要符合W3C標準的話,要自己再加上一個htmlentities()。
另外還有個狀況是如果是還原自$_GET的話仍可能和$_SERVER['REQUEST_URI']不一樣,如a[]=3會變成a[0]=3,不過好像就只是網址變長而已,並不影響PHP的運作(但是仍要小心網址因此而太長而超過HTTP的限制)
Update(2007-07-26 22:40):
不過之後darkhero直接踢破說PHP5之後其實有http_build_query()可以用(雖然因為RFC 1738的關係,空格的編碼方式不同)...orz......
... read more
http://oz.nthu.edu.tw/~u921510/siteTemplate20070724.7z
弄了一下午到現在
其實沒什麼新東西,就是把以往知道的東西湊一湊
以後要架新的網站的時候就從這邊開始吧
Smarty 2.6.18 和 Prototype.js 1.5.1.1 都包進去了
不過prototype.js目前是盜連的..cc
自己建了一個class MySQL,很陽春但夠我用
上次弄BuzzShare的XSS時寫的createElement和addStyleSheet也包進去了Element.addMethods(
{
createElement: function (tag,attr,append) {
var obj = document.createElement(tag);
if(typeof attr == 'object' &&amp; attr != null)
for(var i in attr) obj[i] = attr[i];
if(typeof append == 'string') append = document.getElementById(append);
if(typeof append == 'object' &&amp; append != null) append.appendChild(obj);
return obj;
},
addStyleSheet: function (css_url) {
this.createElement(
'link',
{
rel: 'stylesheet',
type: 'text/css',
href: css_url,
media: 'all'
},
document.lastChild.firstChild
);
},
addJavaScript: function (js_url) {
this.createElement(
'script',
{ type: 'text/javascript', src: js_url },
document.getElementsByTagName('head')[0]
);
}
}
);
不想設定include/config.php中資料庫連線設定的話
直接把MySQL的連線取消就可以用了
其實有點想就這麼經營起一個toolbox去弄個SourceForge或是OSSF之類的
不過寫文件實在是太麻煩了,而且我志不在此..cc......
... read more
「新版」係指2006年九月之後的Blogger
羊男實驗の咖啡館 * [ METAMUSE ]:
Blogger Beta 中 Read More 與 Archive 只顯示標題 作法
從 referral 中發現有人在搜尋 Blogger.com Beta 改版後 Read more 與 Archive 只顯示標題的作法,我是「遵循 Blogger 古法」的邏輯再配上新系統內建的語法後,自己摸出來感覺比較簡潔的作法 ,不過原來早有在 Blogger.com 架站的網友公開了其他的作法。
首先在 EDIT HTML 頁面中點選 Expand Widget Templates 後,在</b:skin>標籤後加入下列區段:..........略在語法中搜尋 <data:post.body/>,原本的樣子是:
]]></b:skin>
<b:if cond='data:blog.pageType == "item"'>
<style type='text/css'>
span.fullpost {display:inline;}
</style>
<b:else/>
<style type='text/css'>
span.fullpost {display:none;}
</style>
</b:if><p><data:post.body/><p>改成:<b:if cond='data:blog.pageType == "item"'>加<br/>是為了讓 read more 接本文時可以斷行,寫文章的時候,只要把想要隱藏的文章區段用<span class="fullpost">...</span>包起來即可:
<data:post.body/>
<b:else/>
<data:post.body/>
<br/><a expr:href='data:post.url'> read more... </a>
</b:if>本文.....<span class="fullpost">(本文要隱藏的部分)</span>收工。
<b:if cond='data:blog.pageType != "item"'>
<style type='text/css'>
span.fullpost { display: none; }
</style>
</b:if>
......
一直不知道學校到底有沒有把比較好處理的課程「總」表放在網路上,但是又不能去問(去年電商專題的EZCheat讓部分教授們對課務組和計中施壓,不會把那樣的資料給我們),最後只好自己從校務資訊系統的查詢網頁著手了,先跳過表單檢查步驟強制用空字串當關鍵字以一次查到所有課程,然後用PHP去做parsing和塞進資料庫。
雖然講起來沒什麼,但這東西花了我整個下午,(說起來還頗對不起英翔學長的....答應的BuzzShare的進度已經落後很多了)中途還冒出一些目前還不知道怎麼解決的問題,比方說因為我幾乎不會用正規表示法,只好改用投機的方式去把 <input> 改成 <input/>。(這件事告訴我們修過【正規語言】跟擅長使用正規表示法是兩回事)
總之,程式碼如下,已經改成只要把網頁給他就可以的function了:function nthuCourseParse( $webpage ) {
$data = file_get_contents( $webpage );
$data = mb_convert_encoding( $data, 'UTF-8', 'BIG-5' );
// Preserve only <table />
$tableStart = strpos( $data, '<table' );
$tableEnd = strpos( $data, '</table>' );
$data = substr( $data, $tableStart, $tableEnd - $tableStart + 8 );
/*
Make it to match XML format
The wierd ');"></td>"' is used for handling the button.
Note that is not allowed in XML until other DTD declaration.
*/
$replace = array(
'<BR>' => '<BR/>',
'<br>' => '<br/>',
' ' => ' ',
');"></td>' => ');" /></td>',
'&' => '&'
);
foreach( $replace as $from => $to )
$data = str_replace( $from, $to, $data );
$parser = xml_parser_create();
xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, 0 );
xml_parser_set_option( $parser, XML_OPTION_SKIP_WHITE, 1 );
if( !xml_parse_into_struct( $parser, $data, $values, $tags ) )
printf(
'Line %d, Col %d: %s',
xml_get_current_line_number( $parser ),
xml_get_current_column_number( $parser ),
xml_error_string( xml_get_error_code( $parser ) )
);
xml_parser_free( $parser );
/*$colName = array( '科號', '科目', '學分', '時間', '教室/容量',
'教師', '人限', '備註', '人數', '對象', '擋修', '大綱' );*/
/*
Parse into another structure in which each element is a course.
Note that empty string is also parsed.
The initial value 4 of the for-loop is based on the structure of <table />,
as the increasing-step 4 is to skip the other row of <table />.
*/
$tr = $tags['tr'];
for( $c = 0, $i = 4; $i+1 < count( $tr ); $i+=4, $c++ ) {
$tdi = 0; // index of td
for( $j = $tr[$i]+1; $j < $tr[$i+1]; $j++ ) { // Trace each <td /> for data
$re = $values[ $j ];
$arr[$c][$tdi][] .= trim( $re['value'] );
if( $re['tag'] == 'td' )
if( in_array( $re['type'], array( 'close', 'complete' ) ) )
$tdi++;
}
}
return $arr;
}
這樣就會回傳一個比較容易懂的結構了,至少比較方便直接呼叫到想要的東西,可以有如是的用法:foreach( $arr as $r => $course ) {
$db[$r]['sn'] = $course[0][1];
$db[$r]['chinese'] = $course[1][0];
$db[$r]['english'] = $course[1][2];
$db[$r]['credit'] = $course[2][1];
$db[$r]['period'] = $course[3][1];
list( $db[$r]['location'] ) = explode( '/', $course[4][1] );
$db[$r]['teacher']['chinese'] = $course[5][1];
$db[$r]['teacher']['english'] = $course[5][3];
}
其實也可以用數字當index直接呼叫所需的資料啦,不過先做過這件事的話就比較可以知道自己再寫什麼:foreach( $db as $i => $course ) {
......
$teacher = $db->getOne( sprintf( "SELECT sn FROM teacher WHERE name = '%s'", $course['teacher']['chinese'] ) );
$db->exec( "INSERT INTO course ( sn, name, teacher ) VALUES ( '%s', '%s', %d )", $course['sn'], $course['chinese'], $teacher ) );
}
... read more
Well, I'm in NCTU IMU and the computer I'm using doesn't have Chinese to type. (In fact, it may have, but I'm not willing to check...XD)
After Hans told me about Box.net, I wonder whether it is possible to put "files" on it and include the files somewhere else. And the following is my result for now:
....It's the song "Good guy" I cooperated with LazyBug during high school.
The embedded flash is found at http://catz.no-ip.com/blogs/eureka/?p=133, also told by Hans.
For now, the code is not neat enough for me and I'd like to write a JS function to construct the <object> element dynamically. Also, I'd like to put the JS function in a file and put the file in Box.net.......
... read more
如題..希望這篇不會再更新了
話說日前拿到一張從瑞典寄來的Google Adsense支票,雖然金額十分十分微薄,不過多少能夠貼補今年繳稅的支出,所以還是趁著中午時間拿去樓下的銀行落袋為安。......
不知道為啥,排外匯的櫃臺總是要等特別久,每個人處理的時間也都特別長。就這樣等啊等的,差不多快30分鐘我才有機會把那張沒有多少錢的Google Adsense支票交給行員。
原本以為排隊是整個過程中最麻煩的一段,結果才發現苦難從此開始,難怪這個櫃臺都要排這麼久。我的Google Adsense登記名字是 Richy Li,銀行行員說,這看不出來跟「李怡志」有什麼關係,擔心不是我本人,所以得拿出可以證明「Richy Li」就是「李怡志」或者「我本人」的證件。還好,公司名片、識別證上都是印Richy Li,否則還得重新跑一趟。那張Adsense支票的金額,大約還不足以吸引我多跑一趟。
說實在的,繁體中文環境下在Blog放Google Adsense實在賺不了「大錢」,而且放了之後就立刻變成以營業為目的的「商業網站」,所以小弟的Blog現在已經沒有放Adsense了。我看到許多人——不好意思說這些人利益薰心——寫一篇文章卻開了很多Blog分站,理由是因為分站雖然比較好用,但難用到必須照三餐罵的母站卻因為Adsense收入太多而不捨得關站時,就知道這些人的心已經完全被Adsense宰制了。寫Blog不就是要自由自在嗎?結果最後還要受到那一點點小錢約束,怎麼想都不值得,所以乾脆不放。
過了幾分鐘,行員拿著影印好的證明回來了,又拿一張單子給我填,哇,這可比兌現一般台幣支票要複雜太多了,不過就是幾千台幣,有必要這麼複雜嗎?申請單上有一個最神奇的欄位要註明支票屬於什麼樣的收入,我猜大概是要防堵金融犯罪順便讓稅務機關好查稅用的吧。說實在的,我真的不知道這算是什麼收入,也不知道填錯了會不會就要繳很重的稅。
台灣的稅捐機構公務員,特別是抽小老百姓稅的那一群,大概是最勤奮的公務員了。想想網路拍賣的前例吧,原本大家以為是自己的「額外收入」,但沒想到也是國稅局的「額外收入」,還訂定了《網路交易課徵營業稅及所得稅規範》。關鍵字廣告呢?我猜最遲明年,國稅局就會告訴我們這筆錢應該要怎麼讓國家分一杯羹了。
老實說我真的不知道這部分的收入該怎麼樣報稅或避稅,所以在銀行櫃臺尷尬了好久,左翻右翻都不知道應該是哪一項,弄得好像那是賣淫收入一樣難以啟齒。顯然行員很忙,也沒有在寫Blog,所以對Google Adsense不熟,否則不會一直「鼓勵」我填薪資收入。哇哩咧,這不是陷我於不仁不義嗎?抵死不從是也!後來填了什麼我也忘記了。不過這讓我一直耿耿於懷,所以想說乾脆在Yahoo!奇摩知識+問看看,希望有專家可以答覆。
全部都搞定之後,就拿到錢了嗎?還早。行員說要整整21個工作天之後才會入帳,差不多就是一個月或者還要更久了。
所以把自己的網站或Blog「租」給Google Adsense基本上還有一些看不到的成本:最近台灣想要跟Google Adsense競爭Blog廣告版位的台灣廠商也很多,如果能夠提供跟Adsense一樣的廣告費(當然更高更好),又能夠在次月月初就直接匯款到存款,相信會比Google更受歡迎的。
- 交易成本:每張若干元的手續費外加寶貴的時間。
- 稅務成本:還不知道要不要繳、要怎麼繳。如果要併入綜合所得稅,那也是一筆錢。
- 延遲成本:假設說你在1月把廣告版位租給Google放Adwords,差不多要4月中或者5月才能拿到錢,中間隔了3個月,感覺就跟在台灣做生意被開90天的票一樣。
新的OZ系統是外包的,目前垃圾信機制是會把被當作垃圾信的清單統整在一封信裡寄給使用者,在Gmail裡看的時候會像是右邊那樣。
附帶一提,裡面有個u920?26....不知道是真的是還是被冒充的?(e-mail寄出時並不會檢查寄信者欄位的真實性,就跟現實生活的郵政系統一樣。不過還是有IP可以查啦)總之,Gmail預設是會先擋下圖片,然後使用者在自己看要不要顯示那些圖片。但就在我按下「顯示以下圖片」的時候,就變成了左圖那個樣子了。
那封信裡唯一的圖片(大概是外包商的logo)的確顯示出來了,可是表格裡的東西卻不見了....不曉得是哪邊的問題(懶的查了,其實看一下原始碼應該不難查),不過我猜不是Outlook的收件軟體大概也可能出現類似的情況吧。
隨著越來越誇張的免費服務,真的很希望可以完全免費的在網路上呈現很多東西。目前已知檔案可以放在Box.net。
在開始看Prototype、PEAR之類的東西之後,深深地覺得應該要多找這些工具才能更快地開發東西。我一直很害怕會陷入如使用DreamWeaver的困境-不會改它不支援的東西(其實我不會用DreamWeaver),畢竟我(們)不會知道自己是不是真的已經了解了那些東西的「基礎」,而已知的是若是貿然硬要使用根本不懂得「工具」,那只會成為累贅而已。
就現況而言,我自認對JS和PHP的了解能夠支援我使用Prototype和PEAR,但是再接下來呢?在我對Prototype的了解只有$()的情況下,我又嘗試使用了PWC (Prototype Window Class,一個在Prototype的基礎上建構夭壽花俏窗格的JS應用),結果當然怎麼用都不順手,還為了一個它在IE上的Bug(其實也有可能是我使用的問題)煩惱了整整一天。
<script src='http://www.prototypejs.org/assets/2007/5/1/prototype.js' type='text/javascript'></script>
<script src='http://www.prototypejs.org/javascripts/code_highlighter.js' type='text/javascript'></script>
<script src='http://www.prototypejs.org/javascripts/javascript.js' type='text/javascript'></script>
<script src='http://www.prototypejs.org/javascripts/html.js' type='text/javascript'></script>
.html .tag { color:#34A; }
.html .attribute { color:#B71; }
.keywords { color: #f71; }
.comment { color: #6c9; }
.string { color: #392; }
.regex { background: #CEF; color: #27b; }
.doctype { color:red; }
.brackets { color: navy; }
.global { color: red; }
.selectors { color: blue; }
.properties { color: brown; }
.units { color: gray; }
.urls { color: green; }
code {
display: block; /*因為<code>預設是inline物件,如果不這樣設的話就只有字的後面有顏色,而不是整個區塊*/
white-space: pre; /*如果被自動換行的話可是會破壞程式碼縮排排版的唷,所以不允許自動換行,空白也都會留著。(IE無效,但我不想管了)*/
overflow: auto; /*承上,如果超過一行的寬度的話,會自動有捲軸(像現在這樣:P)*/
background: #eee;
}
<code class="html"> <span style="font-style: italic;">Hahaha</span>
<!-- 當然可以放註解 --></code>
昨天亂七八糟地測試了一下Blogger,這個範本除了之前發現的IE6下的 <li> 箭頭很大(如右圖,不過IE7就OK了)之外,寬度也不太適合BBS的文章。
原本是想把BBS的文章用Mail-to-Blogger的信箱直接寄過來的,不過因為我想要保留推文,所以色碼就變的很難處理了。查了一下Ptt的EZSoft板得知有RainbowEditor這個軟體可以處理,試用了一下,頗堪用的,不過仍有些沒處理好的部份(以Ptt的文為例,轉錄紀錄的轉錄者ID會爆掉)。
即使色碼抽掉了也仍有問題-BBS有80個字元的寬度,排版上不合於這個範本,所以我就再加上了<pre style="overflow: auto;">
這樣子就不會換行,被切掉的部份也可以用捲軸拉過去了。
<input type="checkbox"
onClick="
var s = document.getElementById('video20070501').style;
s.display = this.checked ? '' : 'none';
"
/>
顯示影片
<embed id="video20070501"></embed>
$('video20070501').toggle();
//連checkbox是否被勾選都不用判斷了
<span onClick="foo();">
<input type="checkbox" />
Some texts...
<!--
畢竟就一般GUI的OS而言,
後面的文字和前面的checkbox是綁在一起的嘛~~
-->
</span>
不過懶得再改了