==== 15天學會jQuery (0-5) ====
* <html><div style="font-size:16px;color:red;font-weight:bold;">15 Days of jQuery(Day 0)---JQuery - What, Why, When, Where, Who</div></html>
**__what__**
jQuery是一個了不起的javascript庫,它可以是我們用很少的幾句代碼就可以創建出漂亮的頁面效果。從網站的方面說,這使得javascript更加有趣。
如果你這樣想:“孩子,我需要另外一個javascript庫,就好比我I need another hole in my head”那么加入這個俱樂部吧。這正是我第一次遇到的時候所想的。
我已經用過了Moo.fx, Scriptaculous, TW-SACK, 和 Prototype. 我曾參與了RICO, Yahoo YUI和其他一些庫的開發。
沒有了PHPjavascript和我一點也不親近了。但是我還是盡全力保持頭腦清醒,并盡量保持用AJAX去思考。
所以當我遇到jQuery的時候我想:"還需要另外一個javascript庫嗎?不了,謝謝..."
**__why__**
為什么我改變我我對jQuery的看法,以及為什么你要考慮去使用它?
很簡單,只要你看一眼過使用jQuery的頁面你就會發現它是如此的簡單易用.只用很少的幾行,就能表現出很優雅的效果.
有一天當我突然看到一些用jQuery寫的代碼時我一下子豁然開朗了. 早茶的過程中,我例行公務的去翻閱我的訂閱,去看每日必看的設計博客的時候我看到了一個用jQuery寫的javascript的例子.事實證明,這些代碼還是有些和瀏覽器關聯的bug,不過這些概念還是我以前從來沒有見過的.
還有那些代碼...
代碼看起來很簡單看起來不像我以前見過的.但也不無道理.
我開始通讀文檔,并且驚奇的發現用一點點代碼竟然能做這么多事情.
**__when__**
你應當在你需要的時候使用jQuery.
給你一個小型的庫文件
DOM強大的控制能力
不費吹灰之力的工作,和少許的努力.
或者
快速的通過AJAX
沒有大量無用的代碼
和一些基本的動畫效果
但是
如果你需要超級花式效果,動畫,拖放,和超級平穩動畫,那么你可能想使用Prototype.他是一個有大量動畫效果的類庫.
**__where__**
你可以jQuery的官方網站下載到他的源代碼(10K).
**__who__**
jQuery was created by [[http://ejohn.org/|John Resig]].
----
* <html><div style="font-size:16px;color:red;font-weight:bold;">15 Days of jQuery(Day 1)---比window.onload更快一些的載入</div></html>
window.onload()是傳統javascript里一個能吃苦耐勞的家伙。它長久以來一直被程序員們作為盡快解決客戶端頁面載入問題的捷徑。
但有時候等待頁面載入還是不夠快。
只有少數大型的圖片文件會被快速的載入,而大部分大型的圖片文件會使window.onload()載入的很慢。所以當我為最近的網絡營銷創建一個web應用程序的時候我不得希望更快一點。有一些圍繞window.onload()的新研究(比如brother cake)的代碼是一種快速的方式。如果你需要,可以試試。
但是如果你要做一些DOM(文檔對象模型)javascript的編程,那么你為什么不試試jQuery,它就像你自己親自制作一個蛋糕,并品嘗它。(雙關Brother Cake,俏皮話)。
jQuery有一個用來作為DOM快速載入javascript的得心應手的小函數,那就是ready... 他在頁面加載完成之后執行。
<code java>
$(document).ready(function(){
// Your code here...
});
</code>
你可以用他來載入任何你想要載入的javascript,并不一定要保留jQuery的編碼風格。讓jQuery同時去執行多個函數也是可以的。
你以前可能見過類似于init()之類的函數,你會發現jQuery會快很多。
在以后的教程里我們會一遍又一遍的用到這個函數。
OK你現在可以嘗試一下代碼:(記得把jQuery引用進你的頁面哦,不記得的話看看上篇。)
<code java>
$(document).ready(function(){
alert("Congratluations!");
});
</code>
很Easy,不是嗎? 用幾分鐘時間做的雙色表格。
----
* <html><div style="font-size:16px;color:red;font-weight:bold;">15 Days of jQuery(Day 2)---很容易的制作雙色表格
</div></html>
這節本身沒有太多的價值,重點在它提供的這個例子上。我將代碼帖出來然后對重點部分注釋一下:我們先來看看Thewatchmakerproject傳統的做法:預覽地址(你可以查看一下源代碼)。再來看看jQuery是如何用5行代碼來搞定的:
<code java>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>StripingTable</title>
<script src="jquery-latest.pack.js" type="text/javascript"></script>
<!--將jQuery引用進來-->
<script type="text/javascript">
$(document).ready(function(){ //這個就是傳說的ready
$(".stripe tr").mouseover(function(){
//如果鼠標移到class為stripe的表格的tr上時,執行函數
$(this).addClass("over");}).mouseout(function(){
//給這行添加class值為over,并且當鼠標一出該行時執行函數
$(this).removeClass("over");}) //移除該行的class
$(".stripe tr:even").addClass("alt");
//給class為stripe的表格的偶數行添加class值為alt
});
</script>
<style>
th {
background:#0066FF;
color:#FFFFFF;
line-height:20px;
height:30px;
}
td {
padding:6px 11px;
border-bottom:1px solid #95bce2;
vertical-align:top;
text-align:center;
}
td * {
padding:6px 11px;
}
tr.alt td {
background:#ecf6fc; /*這行將給所有的tr加上背景色*/
}
tr.over td {
background:#bcd4ec; /*這個將是鼠標高亮行的背景色*/
}
</style>
</head>
<body>
<table class="stripe" width="50%" border="0" cellspacing="0" cellpadding="0">
<!--用class="stripe"來標識需要使用該效果的表格-->
<thead>
<tr>
<th>姓名</th>
<th>年齡</th>
<th>QQ</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>鄧國梁</td>
<td>23</td>
<td>31540205</td>
<td>gl.deng@gmail.com</td>
</tr>
<tr>
<td>鄧國梁</td>
<td>23</td>
<td>31540205</td>
<td>gl.deng@gmail.com</td>
</tr>
<tr>
<td>鄧國梁</td>
<td>23</td>
<td>31540205</td>
<td>gl.deng@gmail.com</td>
</tr>
<tr>
<td>鄧國梁</td>
<td>23</td>
<td>31540205</td>
<td>gl.deng@gmail.com</td>
</tr>
<tr>
<td>鄧國梁</td>
<td>23</td>
<td>31540205</td>
<td>gl.deng@gmail.com</td>
</tr>
<tr>
<td>鄧國梁</td>
<td>23</td>
<td>31540205</td>
<td>gl.deng@gmail.com</td>
</tr>
</tbody>
</table>
<p>PS: 飄飄說我的table沒有<thead>,我知錯了...</p>
</body>
</html>
</code>
[[http://rlog.cn/lab/StripingTable/|預覽地址]]
這里有一個jQuery的技巧不得不提一下:jQuery的鏈式操作,什么是鏈式操作呢? 我們來看看,本來應該寫成這樣子的:
<code java>
$(".stripe tr").mouseover(function(){
$(this).addClass("over");})
$(".stripe tr").mouseout(function(){
$(this).removeClass("over"); })
</code>
但是我們寫成了:
<code java>
$(".stripe tr").mouseover(function(){
$(this).addClass("over");}).mouseout(function(){
$(this).removeClass("over");})
</code>
因為鼠標移入移除都是發生在同一個對象上的,所以我們可以將發生在同一個對象上的動作連起來寫,這樣子如果有很多對象并且在他們身上發生了很多動作那么就會節省很多代碼。(我暫時是這樣理解的,也不知道對不對希望高手能夠斧正。)
----
* <html><div style="font-size:16px;color:red;font-weight:bold;">15 Days of jQuery(Day 3)---巧妙的偽裝鏈接</div></html>
今天的教程是草草完成的.我想把一些東西放在這15天的前面簡單的講講,這樣以來就可以使一些js新手不至于被一堆代碼搞的暈頭轉向.事實上我是在即將結尾的時候才做出的這個決定.
**__目標__**
我們要使用jQuery去創建一小段代碼,這段代碼會把一個頁面所有的超鏈接轉換并且偽裝起來.
**__為什么?__**
一些下屬經銷商認為,一部分用戶有足夠的悟性發現會員鏈接,并能盡量避免通過點擊URL鏈接直接進入瀏覽器,從而“欺騙”下屬經銷商脫離代理(假設購買行為已經發生)
**__"老"辦法__**
有很多下屬經銷商千方百計的掩飾他們的鏈接,避免人們通過鏈接找到他們.這些伎倆涉及到.htaccess和服務器端的代碼.
但對于本教程,我會將重點放到"老學校"的javascript上:
<code java>
<a onMouseOver='window.status="http://www.merchant-url-here.com";
return true;' onMouseOut='window.status="Done"; return true;'
target="_blank">Link Text Here</a>
</code>
這段代碼被用來在瀏覽器狀態欄顯示用戶鼠標指向的鏈接地址.比如實際鏈接是www.website.com?aff=123,則可以在狀態欄顯示www.website.com.
**__問題__**
你是一個很活躍的下級經銷商,你可能會以瘋狂的速度給很多個頁面添加鏈接.并且還要給每個鏈接添加這種效果那么你肯定會厭倦的.加入有一天你要修改任務欄里顯示的鏈接的時候估計你會瘋掉的.
**__jQuery的解決辦法__**
首先,我們想讓javascript盡快的掩飾我們的鏈接所以我們應該先從這里開始:
<code java>
<script src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
//code goes here
});
</script>
</code>
當DOM準備好的時候我們放在ready里的代碼就開始執行了.
接下來
要給所有我們想偽裝的鏈接添加一個class,class有助于jQuery幫我們找到需要偽裝的鏈接而撇開其它不需要偽裝的鏈接.title有兩個作用:當鼠標劃過鏈接的時候會有一個小小的盒狀提示顯示URL:www.affsite.com并且同樣的信息會顯示在瀏覽器的狀態欄(IE Only).
<code java>
<p><a title="http://www.affsite.com"
class="affLink">Super Duper Product</a></p>
</code>
告訴jQuery找到有class="affLink"的鏈接
<code java>
$('a.affLink')
</code>
添加一個鼠標劃過事件
<code java>
$('a.affLink').mouseover(function(){window.status=this.title;return true;})
</code>
簡單的說:找到class="affLink"的所有鏈接,當鼠標劃過它們的時候改變瀏覽器狀態欄信息為該鏈接title的內容.這個在FireFox并不能正常的工作,只是在IE里起作用.在FireFox的狀態欄只是顯示一個"Done",或者更準確的說,鼠標劃過超鏈接對狀態欄并沒有任何影響.我沒有更多的瀏覽器測試.
繼續-mouseout
jQuery可以讓我們用"鏈"的方式,像這樣:
<code java>
$('a.affLink').mouseover(function(){window.status=this.title;return true;})
.mouseout(function(){window.status='Done';return true;});
</code>
這點代碼告訴jQuery改變瀏覽器狀態欄信息,或者當鼠標不再停留在鏈接上時返回"Done".
如果你不適應jQuery的這種鏈的工作方式,那么你完全可以這樣寫:
<code java>
$('a.affLink').mouseover(function(){window.status=this.title;return true;});
$('a.affLink').mouseout(function(){window.status='Done';return true;});
</code>
這就看你了.
把這些代碼放到一起:
<code java>
<script src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('a.affLink').mouseover(function(){window.status=this.title;return true;})
.mouseout(function(){window.status='Done';return true;});
});
</script>
</code>
最后的想法
你們當中可能覺得今天的課程太簡單了,有些還可能還是有點不太明白,因為你們不是二級經銷商.
In “Days” to come you’ll see me tackle issues that get more involved and apply to almost anyone with a website - whether you monetize your traffic or not.
----
* <html><div style="font-size:16px;color:red;font-weight:bold;">15 Days of jQuery(Day 4)---安全郵件列表</div></html>
規則提到如何防止垃圾郵件:不要把你的郵件地址放到任何一個mailto:鏈接中.
在與垃圾郵件惡魔做斗爭的過程中我們的網頁設計師和程序員總結出了一些有創意的解決辦法,讓我們快速的看一些這些常見方法的缺點(或多或少有一些).
**__name [at-no-spam] website.com__**
問題:鏈接式的更方便,而且把郵件地址敲入收件人欄還有可能會出錯.
**__聯系方式__**
問題:你冒著這么大的風險就是因為有一個垃圾郵件借用你的帳戶發送大量的垃圾郵件(除非你使用真正的安全郵件腳本).而這樣就扼殺了那些只想給你發個簡單郵件的用戶.
**__javascript加密__**
問題:你的郵件仍然暴露在光天化日之下,即使你使用了復雜的密碼技術給它帶上面具.還有誰希望為了發送一封郵件而啟用第三方的解密網站,反正我是不會.
**__藏在一種簡單的形式后面__**
(有一個例子,但是打不開了.)http://simon.incutio.com/contact/我能想到的沒有人…但是讓我們看看是否我們能改進觀念。
**__可能的解決辦法:AJAX__**
我提供的解決方案將比目前設計師們使用的方法有如下優勢:
* 易于實施
* 易于修改
* 還有一些小小的花哨的效果
* 不用第三方工具來加密郵件地址
* 沒有郵件地址暴露在光天化日之下
最后我想說明一點,我認為電子郵件靠這種閃爍其詞的加密手段來躲避垃圾郵件還是非常不明智的.在實踐中,我認為電子郵件加密是相對安全的,但是客觀事實是,電子郵件還是在html原代碼里.
**__概念__**
- 1.用jQuery從服務器上把html文件內容抓下來.
- 2.把包含郵件鏈接的html文件放到好的容器中是一種簡單的保護機制.
**__示例__**
我要示范一些例子來顯示郵件鏈接地址,當訪客點擊一個按鈕或者一個鏈接的時候,頁面就會跳轉到對應的那個例子里.
[[http://15daysofjquery.com/examples/mailto/demo1.php|按鈕點擊--立即顯示]]
[[http://15daysofjquery.com/examples/mailto/demo2.php|鏈接點擊--淡出]]
[[http://15daysofjquery.com/examples/mailto/demo3.php|頁面載入--淡出]]
[[http://15daysofjquery.com/examples/mailto/demo4.php|頁面載入--立即顯示]]
(說明:所謂的立即顯示,我的意思是說"沒有花哨的效果而盡快的顯示電子郵件地址")
**__代碼__**
這里發表非商業共創使用許可,如果你希望將代碼使用在你的商業產品中時,請聯系我.我正在一個新的CMS for web designers中使用它.
**__為什么這種方式比普通的mailto鏈接安全?__**
真正的問題是垃圾郵件制造者會使用自動化軟件從html源文件中尋找電子郵件鏈接,這種做法和google一樣:使用相關鏈接.
他么就和我們大部分人一樣懶惰.所以很難所他們不會拿個本子放在鍵盤旁邊記下你的電子郵件地址.
請查看我提供的示例的源代碼,你將不會在html里找到任何的郵件地址.
這幾堅實的保證了你絕對不會收到垃圾郵件,只會從朋友或者瀏覽者那里收到郵件.
但是從頁面中移除郵件地址,.....................
**__最后一點說明__**
先仔細看看前面三個例子,你會看到我使用了AJAX回調函數來觸發slideDown() 和 show() 效果.
換句話說,我希望AJAX調用收到信息(html)時jQuery才開始slideDown() 效果.把秘密粘貼到我們簡單的服務段腳本并且等待服務器返回信息.
**__正確的方法:__**
<code java>
$(document).ready(function(){
$.post('mailtoInfo.php',{
pass: "secret"
},function(txt){
$('div.email').html(txt);
$('div.email').slideDown("slow");
});
});
</code>
**__錯誤的方法:__**
<code java>
$(document).ready(function(){
$.post('mailtoInfo.php',{
pass: "secret"
},function(txt){
$('div.email').html(txt);
});
$('div.email').slideDown("slow");
});
</code>
----
* <html><div style="font-size:16px;color:red;font-weight:bold;">15 Days of jQuery(Day 5)---包起來--懶人用Jquery生成的HTML</div></html>
這個讓我們輕松的紀念日已經到來--我恨我在計算機前已經花了48個小時,我希望能夠有另外一個jQuery來結束我的噩夢,并且讓我上網更快。
當我一邊“在用Jquery方法編寫”和一邊“進行復雜的文件上傳”,我已經筋疲力盡。然而這兩種操作的代碼是一種較淺的,它只不過是你才剛剛開始解決的一些簡單問題。
所以下來我開始介紹:
盡管我在我的網站用所有的CSS樣式表去進行表格設計(也許這要花費兩年半的時間或者更多),我已經用了很多我能找到的在這方面的信息。回到2004年5月(古代史)A list a part有一篇[[http://www.alistapart.com/articles/onionskin/|《關于創建陰影的偉大教程(洋蔥皮投影)》]]可以應用到任何圖片,無論尺寸多大.
那片文章的應經不能再評論了,但還是有些人希望能夠再出篇教程.
**__問題__**
一些css工程師用一些"不相干"的標記,就是為了使背景圖片能夠應用到每一個元素上.例如:
這里是A list a part用到的代碼:
<code java>
<div class="wrap1">
<div class="wrap2">
<div class="wrap3">
<img src="object.gif" alt="The object casting a shadow" />
</div>
</div>
</div>
</code>
所有這些divs充當一個給圖片添加投影效果的"鉤子".這不見得好,我們可以把源代碼精簡成這樣:
<code java>
<img src="object.gif" class="dropshadow" alt="The object casting a shadow" />
</code>
按著這個思路...
**__目標__**
在這里,我要想你展示如何用jQuery輕而易舉的將多于的標記從你的源代碼中剔除.運用這個方法,讓你的代碼更加干凈(更重要的是)將使以后變換布局容易的多.
**__解__**
這里,看看jQuery是如何擊退這個問題的.
<code java>
$(document).ready(function(){
$("img.dropshadow")
.wrap("<div class='wrap1'><div class='wrap2'>" +
"<div class='wrap3'></div></div></div>");
});
</code>
圖片就可以保持這樣了:
<code java>
<img src="object.gif" class="dropshadow" alt="The object casting a shadow" />
</code>
**__仔細看看__**
$(document).ready() 是jQuery版的window.onload()
$("img.dropshadow") 告訴jQuery找到帶有class="dropshadow"的圖片,如果你想用一個id你可以這樣: $("img#dropshadow")wrap() (wrap() tells jQuery to use the DOM (Document Object Method Model) to wrap the images with the class=”dropshadow” in the html inside the parenthesis. )
**__最后的結果__**
傻乎乎的圖片,但是和original Onion Skinned Drop Shadows用的是一樣的.
<code java>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Onion Skin DropShadwo with jQuery</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style>
.wrap0, .wrap1, .wrap2, .wrap3 {
display:inline-table;
/* \*/display:block;/**/
}
.wrap0 {
float:left;
background:url(shadow.gif) right bottom no-repeat;
}
.wrap1 {
background:url(shadow180.gif) no-repeat;
}
.wrap2 {
background:url(corner_bl.gif) -18px 100% no-repeat;
}
.wrap3 {
padding:10px 14px 14px 10px;
background:url(corner_tr.gif) 100% -18px no-repeat;
}
body { background: #fff;}
</style>
<script src="jquery.js" type="text/javascript"></script>
<script>
$(document).ready(function(){
$("img.dropshadow")
.wrap("<div class='wrap0'><div class='wrap1'><div class='wrap2'>" +
"<div class='wrap3'></div></div></div></div>");
});
</script>
</head>
<body>
<h1>Onion Skinned - With jQuery</h1>
<p>First, the old-school, multiple divs hard coded into the html as seen on the <a >orignial article</a>:</p>
<div class="wrap0">
<div class="wrap1">
<div class="wrap2">
<div class="wrap3">
<img src="ball.jpg" alt="The object casting a shadow" />
</div>
</div>
</div>
</div>
<p style="clear:both;">And now, the jQuery method, which uses javascript to wrap the image at runtime:</p>
<img src="ball.jpg" class = "dropshadow" alt="The object casting a shadow" />
<p>View the source of this page and you'll see the huge difference in markup!</p>
</body>
</html>
</code>
(這里只是代碼,沒有圖片.要看效果去[[http://15daysofjquery.com/examples/osds/|這里]])
**__jQuery和其它解決方法的比較__**
jQuery的網站上有一個到Ajaxian網站的鏈接,那里有用另外一個javascrip庫創建的Onion Skin Drop Shadow ,我相信他的代碼復雜程度和代碼量現在看來自不待言.我寧愿使用jQuery.(怎么?你猜到了..)
平心而論,沒有一個庫是對于每一個工作或每一段代碼都是合適的.本教程不是為了證明jQuery是一切javascrip類庫中的老大.
試試Prototype, Scriptaculous, YUI, Rico, Behaviour, Moo.fx 和 the dozens 或者其它的.如果你找到了一個你用起來比較順手的,那就去用它吧.
jQuery對于我來說只是一個工具.我只是希望這個教程能夠提供給你更多使用它的方法.
**__有關jQuery的工具__**
jQuery用難以置信的簡單來操作DOM. [[http://jquery.com/docs/BaseDOM/|你應該花些時間看看jQuery能用來做什么]],用下append(), prepend(), before(), after(), html(), and remove().
來自jQuery Docs
wrap(String html)
把所有匹配的元素用其他元素的結構化標記包裝起來。這種包裝對于在文檔中插入額外的結構化標記最有用,而且它不會破壞原始文檔的語義品質。
這個函數的原理是檢查提供的第一個元素(它是由所提供的HTML標記代碼動態生成的),并在它的代碼結構中找到最上層的祖先元素--這個祖先元素就是包裝元素。
當HTML標記代碼中的元素包含文本時無法使用這個函數。因此,如果要添加文本應該在包裝完成之后再行添加。
示例:
<code java>
$("p").wrap("<div class='wrap'></div>");
</code>
HTML
<code java>
<p>Test Paragraph.</p>
</code>
結果
<code java>
<div class='wrap'><p>Test Paragraph.</p></div>
</code>
15 Days of jQuery(Day 6) --- 更安全的Contact Forms,不帶CAPTCHA
這次的教程內容貼近我擅長的技術方向:安全的contact forms。
就像我在前一篇教程中提到的那樣,一個最普通的contact forms可以幫助訪客同你進行通信來往而不需要暴露你的電子郵件地址給那些可惡的垃圾郵件制造者們。
但如果spammer們已經盯上你,沒有什么比一個不安全的contact foms更糟糕的了。想象一下你的網絡空間提供商發給你一封措辭強烈的電子郵件,通知說:他們發現你的網站發送了大批量的性藥廣告以及其他垃圾郵件,另外,直到你停止這種行為之前,你的網站都將處于離線狀態–謝謝!
那么,今天我要在這篇教程里告訴大家的是一種在任何contact forms上添加一個額外安全層的簡單方法-即使你沒有使用我提供的超級安全、超級靈活的Ultimate Form Mail。
當前狀況
你意識到spammer們已經通過遠程探測技術發現了你的contact forms的弱點,而你希望他們走開。
難點
你不想使用CAPTCHA(Completely Automated Public Turing Test to Tell Computers and Humans Apart),因為你明白,讓你的訪客先去閱讀那些歪七扭八的字母數字才能發送消息只能抑制他們想要互動的欲望,而不是促進它。(數字驗證的缺陷)
關鍵點:你希望那些壞家伙們堵車到天黑,同時希望那些好孩子們一條大道通羅馬。
解決方案
你將學會在頁面加載的時候使用jQuery來給你的contact forms添加一些隱藏的標簽信息。當窗體信息被提交到服務器端的時候,你可以用一些簡單的php代碼實現如下的步驟:
隱藏的標簽被識別出來 隱藏標簽的信息與你的網站訪客下載到瀏覽器上的cookie里的某項標志相一致 隱藏標簽的有效時間還未過期 換句話說,你的訪客們只有在一段有限的時間內才可以填寫窗體并進行發送。如果一個spammer嘗試通過遠程調用來提交窗體信息到你的服務器,他們將會發現自己踢到了一塊又厚又硬的鐵板,不付出點代價休想通過。
我將要告訴你的這種方法是從一位非常聰明的同事Chris Shiflett提供的藍本基礎上修改而成的。他是位專業的安全專家,對php程序員經常遇到的安全問題了如指掌(我怎么感覺他又要忍不住提到他的Ultimate Form Mail 了~~汗)。
教程
基于上次那篇《斑馬線表格輕松制作》的反響良好,我決定再次制作一次類似的“手把手圖文教程”。雖然要花費些時間,但很值得這么做。
手把手教程
DEMO
源代碼
銀彈?1)
銀彈是軟件領域的說法,意為解決一切問題的方法。這個來源于歐洲的傳說,說是只有銀彈可以消滅狼人。
“那么,現在我的窗體就是100%安全的,可以假設任何免費的cntact forms程序,然后高枕無憂了?”
呃。。。非也。
這種安全模式基于一個關鍵的假定:Spammer們總是會拿軟柿子捏,浪費時間去解決一個狡猾的對手對他們來說就是浪費金錢。
現在, 好好聽著,我的朋友們:
這個技術,盡管相當健壯,但仍然不是解決目前脆弱的窗體處理程序問題的靈丹妙藥。
我的這些安全建議的目的是為了讓spammer們知難而退。小偷們入室盜竊之前總會進行仔細踩點,他們只對那些可以用最小代價獲取最大利益的房間感興趣。
換句話說,如果在他們動手之前有99%的機會擋住他們的試探,而且實現起來相當容易,為什么不試一試呢?這才是此項技術要實現的目標。
但這還是治標不治本,不能解決所有問題。
15 Days of jQuery(Day 7) --- 樣式表切換
我第一次看到樣式表切換器是在A List Apart或者Simple Bits,那是兩個設計師最應該去的網站。
從那以后,我找到了很多可以讓訪客通過鼠標點擊某個地方切換樣式表的方法。但最近我要寫一篇如何 使用jQuery編寫簡單代碼實現它的教程。
我將向你們逐步解說整個的過程,不僅僅因為要展示jQuery代碼的簡介,同時也要揭示jQuery庫中的若干高級特性。
首先,代碼
$(document).ready(function()
{
$('.styleswitch').click(function()
{
switchStylestyle(this.getAttribute("rel"))?
return false?
})?
var c = readCookie('style')?
if (c) switchStylestyle(c)?
})?
function switchStylestyle(styleName)
{
$('link[@rel*=style]').each(function(i)
{
this.disabled = true?
if (this.getAttribute('title') == styleName) this.disabled = false?
})?
createCookie('style', styleName, 365)?
}
其他這里沒有提到的部分是你將在后面看到的創建和讀取cookie的函數。
熟悉的開篇
$(document).ready(function()
{
$('.styleswitch').click(function()
告訴jQuery“以最快的速度查找所有包含對象名‘styleswitch’的元素,并在他們被鼠標點擊時執行一個函數”。
看起來不錯。當鼠標點擊預先指定的元素時,switchStylestyle函數將被調用。從現在開始是重點。
這句話什么意思?
第一次看到這句代碼的時候我的腦子有些卡殼:
$('link[@rel*=style]').each(function(i) {
在互聯網上搜索了一下后我空手而歸。最后不得不找到了jQuery的作者John Resig,向他咨詢。
他直接給了我一個jQuery網站的頁面地址,里面講解了若干jQuery提供的高級特性(xpath),可以用來查找并操作頁面中的若干元素。
如果你看過這些東西你就能明白上面那句神秘的代碼的含義是告訴jQuery“查找所有帶rel屬性并且屬性值字符串中包含‘style’的link鏈接元素”。
嗯?
讓我們看看如何編寫包含一個主樣式表,兩個備用樣式表的頁面:
<link rel="stylesheet" type="text/css" href="styles1.css" title="styles1" media="screen" />
<link rel="alternate stylesheet" type="text/css" href="styles2.css" title="styles2" media="screen" />
<link rel="alternate stylesheet" type="text/css" href="styles3.css" title="styles3" media="screen" />
我們可以看到所有樣式表都含有一個包含‘style’字串的rel屬性。
所以結果一目了然,jQuery輕松定位了頁面中的樣式表鏈接。
下一步?
each()函數將遍歷所有這些樣式表鏈接,并執行下一行中的代碼:
this.disabled = true?
if (this.getAttribute('title') == styleName) this.disabled = false?
“首先禁用所有的樣式表鏈接,然后開啟任何title屬性值與switchStylestyle函數傳遞過來的字串相同的樣式表”
一把抓啊,不過很有效。
現在我們需要保證的是那些樣式表存在并且有效。
完整代碼和演示
既然 Kelvin Luck已經編寫了這些代碼,我就不在這里重復了。
DEMO
我相信Kelvin的靈感是從 這個網站那里得到的,我們正好可以看看使用其他工具實現這個功能是否要比jQuery更加復雜冗長。
15 Days of jQuery(Day 8) --- 使用Javascript(jQuery)實現圓角邊框
當我看到這些實現圓角邊框的HTML源代碼的時候,我發現這很適合用來寫一篇jQuery教程–使用wrap()、prepend()、append() 函數。
這里是原先的HTML代碼,我們將從這里開始:
<div class="dialog">
<div class="hd">
<div class="c"></div>
</div>
<div class="bd">
<div class="c">
<div class="s">
<main
content goes here >
</div>
</div>
</div>
<div class="ft">
<div class="c"></div>
</div>
</div>
現在我們怎么使用jQuery來精簡這段代碼呢?
首先,我們需要一個“鉤子”,一個特殊的HTML元素,或者一個id,或者一個對象名–來告訴jQuery處理的目標。
現在我們改成了這個樣子:
<div class=“roundbox”> <main content goes here > </div> 下一步,我們使用jQuery來將剩下的代碼添加進去:
$(document).ready(function(){ $("div.roundbox") .wrap('<div
class="dialog">'+
'<div class="bd">'+
'<div class="c">'+
'<div class="s">'+
'</div>'+
'</div>'+
'</div>'+
'</div>');
});
其他Div標記去哪里了?
仔細觀察代碼,你就會發現它們都跑到了js代碼里面,在wrap函數執行時它們將嵌套在“鉤子Div”的內部。
細心的觀眾會發現我漏掉了部分代碼。這是因為jQuery中的wrap()函數要求div標簽必須嚴格對稱嵌套才能工作。
具體的,我去掉了下面兩個部分:
<div class="hd"><div class="c"></div></div>
<div class="ft"><div class="c"></div></div>
添加和預置一體化
下一步我們將會通過prepend和append函數將這兩段代碼添加進帶有dialog對象名的div標記內部,并且使用“連鎖”方法。
$('div.dialog').prepend('<div class="hd">'+
'<div class="c"></div>'+
'</div>')
.append('<div class="ft">'+
'<div class="c"></div>'+
'</div>');
示例及代碼
我已經在網上放置了一個演示頁面供大家查看。建議你看一下頁面的源代碼,體會jQuery給頁面代碼帶來的清爽和便捷。
這些代碼來自 Schillmania的一篇文章,個人推薦大家下載包含點綴圖片的zip打包,非常精美。
不使用圖片的圓角邊框
有很多方法可以實現圓角邊框–有些方法甚至不需要圖片。
在jQuery的網站上有一個用來制作無圖圓角邊框的插件。雖然不是適合所有人(或者說所有程序),但也值得學習。
看看它的漂亮代碼吧(使用時):
$(document).bind("load", function(){
$("#box1").corner()
});
15 Days of jQuery(Day 9) --- 快速和略顯粗劣的AJAX視頻教程
今天我的想法有點改變。近段時間以來我一直考慮注冊一個YouTube帳號來上傳一些教程錄像,現在我終于做出了決定并上傳了一個。在這里我將手把手的向大家演示為你的網站添加一些AJAX基本應用的方法。
錄像很短,因為YouTube對上傳影片的長度有限制(10分鐘以內)。當然由于制作倉促,錯誤在所難免。比如在某個地方我稱CGI為“服務器端腳本”,而更準確的說法應該是“服務器端語言”。
這是AJAX,還是AHAH,抑或AXAH?
你將看到的東西其實更接近AHAH而不是純粹的AJAX。
有什么區別么?AJAX中的“X”代表著XML。但更多時候人們喜歡使用簡單的文本或者javascript代碼或者單獨文件而不是那種復雜冗長的XML。對此有篇文章有詳細論述:AJAX vs. AHAH。
至于AXAH。。。 Cody Lindley的文章可以解釋一切。對AJAX的一些工作理念有興趣的讀者可以看一下。
教程錄像
這個頁面上有我提供的演示。
15 Days of jQuery(Day 10) --- 使用jQuery Javascript 庫實現“即點即改”的AJAX化
以前我在Quirksmode網站見過這種代碼,后來又在24 Ways網站看到了一個更具Web 2.0風格的方案。這次我將為大家展示兩種使用jQuery實現相同功能(甚至更好)的方法。
目標
一個用AJAX(或AHAH)技術設計的頁面,訪問者無需離開就可以在看到的(x)HTML 頁面上編輯內容。
方案
點擊需要編輯的文本,變幻出一個帶有保存和取消按鈕的textarea。修改的部分將通過AHAH傳送至服務器端的一個PHP腳本文件,用來更新數據庫(MySQL或普通文件)。
演示
AJAX式即點即改演示一
在這第一個演示中,我使用了一個id為“editinplace”的div元素。當鼠標劃過這里時,背景顏色將變成淺黃色。點擊文本將啟動一些DOM操作,div元素被一個textarea元素取代–內中包含原先的文本。
點擊保存按鈕將向服務器端的PHP腳本文件發送新的HTML內容,并重新輸出收到的新文本內容(通過 $_POST)。
在真實應用環境下,你還應當添加一個安全性檢測,然后才能更新數據庫并返回更新后的頁面內容,同事告知jQuery執行成功的信息。
但在這個例子中,所有的修改都是成功的,發送給PHP腳本的信息將原封不動的返回到jQuery代碼,顯示到一個普通的警告窗口里。
解釋
開頭部分說了很多次了,如果你不想使用jQuery提供的document.ready函數,盡可以選擇你自己中意的init()函數。
$(document).ready(function(){
setClickable()?
})?
頁面上第一個被執行的就是這個setClickable()函數。它的任務就是做以下內容:
查找包含id為“editinplace”的div元素,然后告訴jQuery在這些div被點擊時執行某些操作。
function setClickable() {
$('#editInPlace').click(function() {
讀取div內部的HTML代碼的任務將交給jQuery的html()函數來完成。這些HTML將會額外添加若干代碼以組成textarea里的保存和取消按鈕。
var textarea = '<div><textarea rows="10" cols="60">'+$(this).html()+'</textarea>'?
var button = '<div><input type="button" value="SAVE"
class="saveButton" /> OR <input type="button" value="CANCEL"
class="cancelButton" /></div></div>'?
var revert = $(this).html()?
同樣還是這些在div內部找到的HTML代碼將會賦值給一個叫做“revert”的變量。這個變量將用來在取消按鈕被按下的事件中輸出原始文本。
var revert = $(this).html()?
jQuery的DOM函數“after”用來將新生的textarea HTML代碼放置在我們指定的div元素后。我在后面緊跟著連鎖上了一個remove()方法 來移除div元素以節省代碼。
$(this).after(textarea+button).remove()?
在使用jQuery的時候,我通過對象名來定位保存和取消按鈕對象。我指示jQuery在任一按鈕按下時觸發最后一個函數“saveChanges”。我告訴了jQuery在div元素被點擊時做什么事情,但我沒有在最后加上分號因為我希望在這個div操作語句后面連鎖其他方法。
$('.saveButton').click(function(){saveChanges(this, false)?})?
$('.cancelButton').click(function(){saveChanges(this, revert)?})?
})
我再連鎖了一個簡單的mouseover和mouseout事件,告訴jQuery在鼠標指針掠過我們指定的div元素(id=editInPlace)的時候添加和移除一個對象。
.mouseover(function() {
$(this).addClass("editable")?
})
.mouseout(function() {
$(this).removeClass("editable")?
})?
}?//end of function setClickable
函數“saveChanges”將以按鈕對象做為第一個參數,而cancel參數則取兩種值,false或者保存在revert變量中的html代碼內容。
function saveChanges(obj, cancel) {
如果cancel為假,則函數將保存更改并使用html格式發送給服務器端的php腳本。我在這里使用了jQuery內置的一個DOM函數實現對textarea內容的提取操作:parent()和siblings()。
if(!cancel) {
var t = $(obj).parent().siblings(0).val()?
DOM基礎超出了本系列教程的范圍,但在這個應用中我只是告訴了jQuery“對象(保存按鈕)有一個父元素(div)。。。去找到它。那個元素擁有一個或多個DOM樹同級對象。。。我只想找到其中的第一個。然后提取那個對象的所有內容。”
(稍等。。。如果你對DOM風格的代碼不是很熟悉的話,前面我的注釋可能并不好理解。我還是建議你之前google一下“DOM javascript”或者其他相關的信息。)
這些html賦值給了t變量,現在要通過POST方法把它發送給test2.php。
$.post("test2.php",{
content: t
},function(txt){
alert( txt)?
})?
}
如果cancel有一個值,那么必然是保存在revert變量中的原始html內容。所以,在這個時候我希望變量t變為原始html內容。
else {
var t = cancel?
}
下一步是通過jQuery提供的DOM函數放置一個新的div元素,id為“editInPlace”,在這之后包含了textarea元素。。。然后刪除掉這個div元素。
$(obj).parent().parent().after('<div id="editInPlace">'+t+'</div>').remove()
在果殼中,這將告訴jQuery“在DOM樹中上躍兩次。將HTML代碼附在到達位置的對象之后,然后移除那個對象。”
最后,我們再次調用setClickable函數并關閉saveChange()函數。重調setClickable()函數的含義是重新設置onMouseover,onMouseout,和onClick事件到初始狀態。
setClickable()?
}
第二個示例
第二個方法非常類似但也有點復雜。
示例二
沒有用到龐大的單獨div元素,這個示例將每個段落p標簽變換成單獨的可編輯區域。
這里的難度在于你如何在向服務器端腳本發送數據時指定正確的段落p標簽。
在這里我通過為每個p標簽編號并將這個編號一同發送給服務器端的php腳本的方式解決了問題。你會在alert窗口中看到php腳本是如何“知道”哪個p標簽里的內容被修改的。
已知的問題
現實的應用中,你在使用類似的功能時首先需要驗證更改的內容的合法性,然后才能將數據發送到服務器端。顯然在這里我們刻意把這些內容忽略掉了。
15 Days of jQuery(Day 11) --- 使用不苛刻的javascript代碼實現多文件上傳
好幾個月以前,當我在追逐互聯網上AJAX熱潮的時候,我在 FiftyFourEleven網站上發現了一篇使用創新的javascript代碼實現當時正在困擾我的“ 單文件元素實現多文件上傳”的文章。
所以當我想寫作《15天漫游jQuery》的時候,我第一個想到的就是用jQuery實現這個功能。
接觸易用性狂熱愛好者
幾天前當我檢查網站記錄的時候,發現了一條遺漏的文章trackback。跟過去看的時候我發現我的兩篇jQuery文章被作者引用來證明他為什么討厭javascript。
根據這個人的說法,任何工具或技術如果沒有將易用性放在第一位都將成為垃圾。
盡管我很不同意這位仁兄一桿子打死的態度,但他還是讓我對這篇詳細教程有所留意。當我在編寫一個簡單網頁效果的時候,我會盡量小心謹慎的處理。這樣如果網站訪客們決定關閉javascript代碼執行功能的時候,他們仍然可以正常使用網站的功能。
關于第一價值的兩個教程
演示
演示一地址
演示二地址(這個演示有bug導致無法使用,作者修正了bug,使用這個后面鏈接查看演示演示二地址(no bug))
解釋
單文件輸入框
jQuery的$(document).ready() 函數的工作有兩個:
創建一個用來顯示最大允許上傳文件數的div元素。 查找文件上傳框(假設這里只有一個),然后給它附上一個onChange事件。
$("input[@type=file]").change(function(){
doIt(this, fileMax)?
})?
doit()函數(簡單又好記,呵呵~)檢查是否達到了最大文件數量限制,如果不是,它會隱藏當前文件輸入框,在父div里添加一個新的文件輸入框,將輸入框內的文件名使用id “files_list”作為標記,在最后添加一個“刪除”按鈕。
在DOM樹中導航,我使用jQuery的parent()函數,然后用remove()函數移除元素。我還使用了append()和prepend()函數分別添加文件名和新的輸入框。
兩個關鍵點
- 最大文件上傳數量設定:
var fileMax = 3?
- 輸入框必須有適當的定位措施:
<input type="file" class="upload" name="fileX[]"/>
這樣弄以后輸入框可疑由訪問者決定添加還是刪除,沒有任何關于id或名稱的操作。當這個窗體代碼發送給服務器端腳本的時候,相關信息就已經被存放在了一個數組中了。
多文件輸入框
首先,文件允許上傳的數量由頁面中的文件輸入框的數量決定。其次,你仍然需要通過某種方法為每個輸入框接收到的內容用一個數組存放。
<input type="file" class="upload" name="fileX[]"/>
第二個演示跟前面的比起來最大的不同在于,我遍歷了每個文件輸入框并在其內容有改動時執行doit()函數。通過遍歷每一個輸入框,我可以為我的代碼添加有用的額外信息:輸入框內容在“堆棧”中的順序。
換句話說,當這段代碼執行時,它會特別指定第一個輸入框,或者第二個,抑或第三個。
代碼見下:
$("input[@type=file]:nthoftype("+
n+")")
jQuery的靈活性允許我們使用CSS和XPath描述語句定位指定的元素位置。
你會發現當一個文件被選中時,文件輸入框都會被文件名稱覆蓋。點擊文件名就可以選擇其他不同的文件。
15 Days of jQuery(Day 12) --- jQuery Lightbox (插件)
Cody Lindley 移植的第一版“ Thickbox”讓我第一次感受到了jQuery的魅力。后來他又做了一些 代碼升級以修復若干跨瀏覽器的兼容性問題。
一些需要注意的地方
$(document).ready 取代了TB_init() 函數,作用是在每個包含對象名“thickbox”的鏈接上附加一個onClick事件。
function TB_init(){
$("a.thickbox").click(function(){
var t = this.title || this.innerHTML || this.href?
TB_show(t,this.href)?
this.blur()?
return false?
})?
當這些鏈接被點擊時,TB_show()函數就將執行。
$("body")
.append("<div id='TB_overlay'></div><div id='TB_window'></div>")?
$("#TB_overlay").click(TB_remove)?
$(window).resize(TB_position)?
$(window).scroll(TB_position)?
$("#TB_overlay").show()?
$("body").append("<div id='TB_load'><div id='TB_loadContent'><img
src='images/circle_animation.gif' /></div></div>")?
如你所見,在文檔body元素前添加了兩個div元素。換句話說,這兩個div元素將被添加在頁面html代碼的body關閉元素前。
覆蓋的div將使用一個特定的包含不透明外表的CSS文件指定表現。TB_window的代碼用來通過AHAH在頁面中放置一張圖片或者加入另一個頁面。$(window).resize 和$(window).scroll 告訴jQuery在用戶重新調整窗口大小或者拖動頁面翻頁的時候執行TB_position函數。這是保證Thickbox始終保持在窗口中心部位的手段。
接下來,Cody查詢url的后綴。
var urlString = /.jpg|.jpeg|.png|.gif|.html|.htm|.php|.cfm|.asp|.aspx|.jsp|.jst|.rb|.txt/g?
var urlType = url.match(urlString)?
if(urlType == '.jpg' || urlType == '.jpeg' || urlType == '.png' || urlType == '.gif'){//code to show images
如果這是一個圖片文件,則jQuery的append函數會添加html代碼到適當位置。
$("#TB_window").append("<a href='' id='TB_ImageOff' title='Close'><img
id='TB_Image' src='"+url+"' width='"+imageWidth+"' height='"+imageHeight+"'
alt='"+caption+"'/></a>"
+ "<div id='TB_caption'>"+caption+"</div><div
id='TB_closeWindow'><a href='#' id='TB_closeWindowButton'>close</a></div>")?
$("#TB_closeWindowButton").click(TB_remove)?
另外,遠程文件將使用jQuery的load()函數導入。
$("#TB_ajaxContent").load(url, function(){
15 Days of jQuery(Day 13) --- jQuery 表格
一位叫Klaus的朋友編寫了一個小插件, 用jQuery實現可用性極佳的javascript表格。
設置好正確的(x)HTML 和CSS后,你可以像下面那樣創建表格:
$.tabs(”container”)? first tab on by default 如果你像在默認位置“上方”再添加一個表格: $.tabs(”container”, 2)? second tab on
Klaus這里 示例,你可以看看最終效果。
我的改版
我稍微修改了Klaus的代碼,添加了一個簡單的表單用來生成表格的表頭。
用法:
非常簡單。只需要輸入每個表格的表頭(最多5個),然后點擊表單下方的按鈕。下一個頁面將生成結果HTML代碼,你可以復制然后粘貼到文件中。
你還需要 下載Klaus網站的CSS文件,做些你自己的修改,當然還要上傳jQuery框架庫到你的服務器上。
這里是表格生成器的地址。
15 Days of jQuery(Day 14) --- Javascript 工具提示
Cody Lindley ,Thickbox的作者,日前發布了 jTip - jQuery 工具提示。
我對其中很多想法和思路拍案叫絕。我知道你已經看過很多類似的工具提示代碼了。但是,Cody 的方法已經在我的工作中顯露出了閃光點。
當我檢查HTML代碼時,我發現了一個大問題,可訪問性。鏈接在javascript關閉的時候無法工作。我并不是傾向于一定要實現全面的可訪問性,只是在這里我認為可以有其他更具親和力的方式實現相同的功能。
尤其是,我個人不喜歡那種為了可訪問性而去犧牲可用性來實現在提示框上鏈接另一個頁面鏈接的方法。我喜歡這個提示框 - 不是對Cody不尊重,只是在我這里我“需要”它能夠在各種情況下工作。
今天我要提供給大家的是Cody的工具提示代碼的小小修改。如果你不是Cody工具提示的愛好者的話,我的改版對你來說也許不是很在意。但如果你喜歡他的作品同時希望它可以在javascript關閉的時候照常工作,這個也許是你需要的。
我的改動
讓我產生修改想法的,是他的代碼在Yahoo上的應用。我不喜歡他使用的代碼:
<a href="yahoo.htm?width=175&?link=http://www.yahoo.com"
name="Before You Click..."
id="yahooCopy"
class="jTip">Go To Yahoo</a>
所以我重寫了他的部分代碼,成了現在這個樣子:
<a href="http://www.yahoo.com"
rel="yahoo.htm?width=175&link=yahoo&name=Before%20
%20You%20Click..."
id="yahooCopy"
class="jTip">
Go To Yahoo</a>
我的示例
改進:HTML標準校驗
我的代碼可以通過w3.org的測試
改進:命名
在我修改Cody的代碼的時候我發現他使用了一個用來存儲鏈接名稱的叫做“title”的變量名,這會導致一些混淆。
我標出了這個命名問題,即使我認為這不過是個小小的失誤。
改進:可用性
使用我的代碼,你可以讓每個提示框都含有真實鏈接地址到另一個文檔,不管內部的還是外部的。或者你只是想要那個提示框,不想關心可用性,你同樣可以讓鏈接部分留空。
選擇權在你。
感謝
Cody提供了偉大的代碼,幫助我節省了大量的時間和精力。我的修改只是對原有代碼的輕微“調整”,希望朋友們喜歡。
15 Days of jQuery(Day 15) --- 拖拽效果和選擇器