jquery

2007-05-15 jquery 在Drupal 的使用(三) -嵌入jquery

可供擺放javascript 和jquery 的地方有好幾個
要視乎javascript 的性質,
放到適當的位置
雖然放錯位置都不會影響效能
但為了維護的方便,
必需保持 顯示-控制分離

其實使用jquery 的情況好很多
從優化視覺效果到幫助使用者
到流行的ajax, 偏門點的繁簡轉換等等
都會用上jquery
jquery 可能會放到一個獨立的js 檔內
或inline 放到相關的html, php 檔都有

先從開發模組的角度看
取tabbed block 為例,
要讓unordered list 化成 tabbed block
便要用jquery 隱藏一部分內容
按下tab 的時候便顯示另一塊
加減某些class 等等, 都用上jquery
因此, 沒有了jquery, tabbed block 可算不上是tabbed block
所以, jquery 的部分一定要嵌入到模組之內
而且因為jquery 行數超過十,
順理成章放到一個獨立的 tabbed_block.js 之內
也是加jquery 最簡單的方法

<?php
drupal_add_js
("tabbed_block.js");
?>

之後, drupal 會在html 的header tags 之內
加上這個js 檔
令unordered list 化成tabbed block

而一般界面的優化
通常都會放到theme 之內
例如這站的淡入效果, 便將joe.js 放到其中一個theme 之內
page.tpl.php:

//包含js 文件:
<script src="<?php print base_path() . path_to_theme() ?>/joe.js" ></script>
//直接inline
<script>
$(document).ready(function(){
  //....
});
</script>

要留意的只是路徑問題
要指定這個theme 的路徑, 如上例:
<?php
base_path
().parth_to_theme()
?>

最後, 大家可能發覺我寫的文字很多
但例子少一點
實際使用時可能還要自己查一下API
這裡算不上什麼好地方
但個人覺得,
是因為"使用概念"比"使用方法"更重要
Drupal 發展真的一日千里
即將零七年六月一日, Drupal 6.0 就code freeze 了
也即基本寫好6.0 會加入的功能
只餘下測試, 除蟲的工作
當中一代接一代的代碼改變
API 改變等等都會令"使用方法"落伍, 不適用
但"使用概念"卻不會因為升級而改變
都會循一定的大方向而提升
所以有很多的篇幅描述這樣做那樣做的原因
而解決的思路又如何一步一步的推進
希望可以令大家有能力自己嘗試解決
而這裡只作一個穿針引線的作用

2007-05-12 jquery 在Drupal 的使用(二) -jquery recursive

續jquery

先說明一下callback
用fadeIn() 說明一下

fadeIn(speed, callback)

fadeIn() 有兩個參數
第一個speed
用作指定淡入的速度, 可以為字符串"slow" "normal" "fast"
也可以為數字, 指定毫秒(千分一秒)

第二個callback
參數可以是一個函數名, 也可以定義一個新函數(inline 的方式)
而這個函數會在fadeIn() 完成,
也即是效果完結的時候被呼叫.
例如

$("#joe").fadeIn( "normal" , "joe_example" )

function joe_example(){
    alert( "Element with id " + $(this).attr("id") + " fade in finished." );
}

這樣fadeIn 元成的時候便會呼叫 joe_example()
函數內可以用 $(this) 來指定"自己"
來獲得這個元素的相關資料
如果配合next(), sibling(), parent() 也可以得到附近的元素
再作其他處理

至於inline的方式, 語法為:

$("#joe").fadeIn( "normal" , function(){
  $(this).next().fadeIn();
});

例子中, id 是joe 的元素先淡入
淡入完成之後,
joe 元素的下一個元素淡入
完成一次兩個為一組的連還淡入效果
注意, 這個例子只會淡入joe 元素和joe 元素的下一個元素
共兩個元素
並不會連鎖的淡入第三個元素

如果要發生無限的連鎖,
像這站的menu 的效果
便要使用遍歷(recursive) 結構了
首先介紹一下遍歷結構,
簡單的遍歷一般是指一個函數會自己呼叫自己
一直到符合某一個條件才停下
所以一個完整的遍歷結構一定有兩個條件
一個是呼叫自己的呼叫
另一個是一個停止呼叫的條件
用一個簡單的例子說明

function recursive(count){
  //完結條件
  if ( count>5 ){
    return;
  }
  alert( count++ );
  //呼叫自己
  recursive( count );
}

上面展示了一個遍歷函數
但這個函數不會開始, 直到代碼第一次呼叫 recursive(0)
一但被第一次呼叫(initialize)
便不會停, 直到count>5

同樣的原理可以放到menu 的連鎖反應之中
javascript 的代碼都分為兩個部份
一個遍歷的函數,
一次呼叫(initialize)

//initialize
$(document).ready(function(){
  $("ul.primary-links").children().eq(0).fadeIn("slow",function(){nextFadeIn(this)});
});
//遍歷函數
function nextFadeIn(obj){
  $(obj).next().fadeIn("slow",function(){nextFadeIn(this)});
}

下一次介紹drupal 加入javascript 的方法和總結一下jquery 的用法, 思考方向等

2007-05-08 樣版微調(二) - jquery

今天努力的在localhost 改一下theme
right sidebar 的blocks 都用上漸變
以突顯效果
之後的改變都會以視覺沖擊為主
要吸引顧客啊....

有位過客留了言, 要講一講jquery
就在此淺談一下jquery
(原本打算link 一個jquery 官網的教學, 但jquery.com 近日被攻擊了, 訪問不了)

兩大javascript 庫, prototype 和jquery 我都有用過
各有千秋, 但因為Drupal 內建jquery,
用jquery 都多了, 但他們功能大都差無幾

用jquery, 先要熟用$(), 一個jquery 的selector
# 開頭代表id $("#wrapper")
. 開頭代表class
> 指子類
等等

其實menu 的漸變效果
由一個recursive 的函數做中心
自己(this) fadeIn() 完成了, callback 自己
然後找下一個siblings(兄弟元素), 用fadeIn(), callback 自己...
沒完沒了
然後用一個$(document).ready() 初始化就可以了

<?php
$(document).ready(function(){
  $(
"ul.primary-links").children().eq(0).fadeIn("slow",function(){
   
nextFadeIn(this)
  });
});
function
nextFadeIn(obj){
  $(
obj).next().fadeIn("slow",function(){nextFadeIn(this)});
}
?>

最後給一個link, 非常好的jquery reference:
http://visualjquery.com

2007-05-07 Drupal樣版微調

這站已經差不多滿月了
日常的營運都開始順暢, 上手了
所以連日將會對樣式作些微調
令用戶和我都能更方便, 美觀

今日除了顯而易見的寛度改變之外
對flash 下的menu 用了jquery 作修飾
順便也秀一下jquery 的功力
一個漸變的效果, 使用jquery 裡的 fadeIn()
簡單的代碼做到好的效果

來日會一直在樣式上微調,
以活用tabbed block 等自家產品

2007-04-09-drupal-module-develop-with-tabs-and-ajax

blog 數正幾何級的減少中...

主要是專注於放復活節假...
和drupal 的一個模?開發有關

這一次的模?是一個recent comment 和 recent blog post 的二合一模?
用了jquery library 和 tabs plugin
成就一個tab 和ajax 模?
當然沿用drupal 內建使用ajax 的方式
但講起來容易
官網都不多這類的drupal 5.1+ ajax 的描述
唯有向已經內建ajax 的現有module 偷師
open source 吧...
明白了當中的機制之後
有寫過ajax 的朋友應該會立即上手
如果還沒有寫過, 到jquery 的官網先參考一下ajax 的用法會容易點
反正都有中文說明

以下假設你已經會做一個模?
所以只提重點部份

先講tabs 的組成
tabs 有一個指定的格式

<div>

<ul>

<li>tab title1</li>
<li>tab title2</li>

</ul>
<div>tab content1</div>
<div>tab content2</div>

</div>

換成recent comment, recent blog post:(非php code, 只為一個算法結構)
hook_block()內:

<div id=''joe_container''>

<ul>

<li>t(''Recent comments'')</li>
<li>t(''Recent blog posts'')</li>

</ul>
<div>theme(''comment_block'')</div>
<div>joe_recent_blog()</div>//self defined function

</div>

其中, theme(''comment block'')為comment module 內建的function 輸出recent comment
joe_recent_blog() 為一個模?內定義的function, prototype類似:

if (user_access(''access content'')) {
$result = db_query_range(db_rewrite_sql("SELECT
n.nid, n.title, n.created FROM {node} n WHERE n.type = ''blog'' AND n.status = 1
ORDER BY n.created DESC"), 0, 10);
if (db_num_rows($result)) {
$block[''content''] .= "<div
id=''fragment-2''>".node_title_list($result);
$block[''content''] .= ''<div
class="more-link">''. l(t(''more''), ''blog'', array(''title'' => t(''Read the
latest blog entries.''))) .''</div>'';
}
}

先完成非ajax block 的部份, 可降解ajax, 可降解block

此時已經可以在drupal 內enable block, 測試一下
為插入ajax 做準備

因為ajax 的javascript code 為數十多二十行,
分開一個.js file 處理
joe.js:

$(document).ready( function(){dojo_ajax_auto_attach();} )

function dojo_ajax_auto_attach(){
//init tabs
$("#joe_container").tabs();

///////////////////////////////略

留意, drupal 5.1 內建的drupal/misc/jquery.js
並不可以使用tabs plugin...(應該為版本問題)
故要使用tabs plugin 包內的jquery.js 或官網的jquery.js, 覆蓋
接著又可以試一下tabs 的效果

戲玉...終於到了...ajax 的部分
ajax request 有一個url 的para 注(i)
用作找出php handler 的php file
但drupal 內卻用一個module file作handler
故要告訴(register) 到drupal core, 某一path 會用作handler
傳相關parameter 到module file
要在hook_menu() 內:

$items = array();
$items[] = array(
''path'' => ''dojo/menu'', //注(i)
''title'' => t(''dojo''),
''access'' => user_access(''access content''),
''type'' => MENU_CALLBACK,
''callback'' => ''dojo_js'' //真正的php handler
function
);

$items = array_merge($items, module_invoke_all(''dojo_menu'', $may_cache));
return $items;

到此, ajax 的php 部份其實只有一個register function hook_menu()
和dojo_js(), 一個真正的handler

javascript 卻反而可以細分為兩個部份
caller 和handler
caller 為一個buttom, 按了就發出一個要求到注(i) 的path

$(".dojo-ajax").click(function(){
$.ajax({
type: "POST",
url: "/drupal/dojo/menu",
data: "path=" + "dojo/menu",

/////////////////////略, 待續
handler 為php 返回的json object parser
通常為插入返回的json object 的javascript code
////續

success: function (data) {
data = Drupal.parseJson(data);
$("#block-dojo-0 .content").html(
data.content );

細心看source code 就可以了

歡迎回應~