我在這個主題上做了一個博客JS with AJAX and PHP並粘貼在下面。
JS使用AJAX和PHP
Drupal有作爲它的標準形式一部分JS和AJAX的廣泛支持,並有解釋它是如何工作的教程。但是,我無法找到一個很好的教程來解釋Javascript如何以特定的方式與Drupal模塊進行通信。例如,我希望能夠根據PHP中可用的狀態信息修改任意的html。下面介紹這種技術。
您會在此頁面的頂部看到標籤,默認情況下此主題非常簡單。我想修改它們,使當前選定的選項卡更加突出。當然,這可以用CSS來完成,但我希望開發這種技術,僅僅用CSS就不夠。
下面是可以直接添加到前面描述的JS文件的JS。每次頁面加載並準備就緒時,都會有一個jQuery函數對id爲'main-menu-links'的元素進行操作。我得到innerHTML並使用encodeURIComponent將其轉換爲可作爲URL參數傳遞的安全字符串。我必須這樣做,因爲其中一個選項卡引用了傳遞參數的URL。
var xmlhttp;
var childnodes;
// Send post to specified url
function loadXMLDoc(url,cfunc)
{
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=cfunc;
// alert("loadXMLDoc: " + url);
xmlhttp.open("POST",url,true);
xmlhttp.send();
}
// AJAX redirect to camr_custom/getvisits with callback function to replace the href
// with something to disable the link for nodes that have not been visited.
function getMenuTabs(str)
{
loadXMLDoc("?q=flashum_status/get_menu_tabs&block="+str,function()
{
// alert("getMenuTabs status: " + xmlhttp.status + " readyState: " + xmlhttp.readyState);
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
// alert("getMenuTabs: " + xmlhttp.responseText);
data= jQuery.parseJSON('['+xmlhttp.responseText+']')
$.each(data,function(){
// alert(this['block']);
document.getElementById("main-menu-links").innerHTML = this['block'];
});
}
});
}
// Locate book navigation block and send innerHTML to PHP module
$('#main-menu-links').ready(function() {
lis = document.getElementById("main-menu-links").innerHTML;
// alert("main-menu-links: " + lis);
// safe encode this block so that it can contain arbitrary urls in the href links
lis = encodeURIComponent(lis);
getMenuTabs(lis);
});
jQuery函數結束調用loadXMLDoc其是其中AJAX後發生指定由Drupal的模塊中的hook_menu捕獲的URL。它還使用在參數cfunc中傳遞的回調函數。返回時,解析JSON響應將其轉換爲HTML,並將其直接存儲回原始的innerHTML。因此,無論PHP模塊對HTML取代原始HTML。
在PHP端有第一hook_menu的數組元素:
$items['flashum_status/get_menu_tabs'] = array(
'page callback' => 'get_menu_tabs',
'access arguments' => array('access flashum status'),
'type' => MENU_CALLBACK,
);
回調函數然後如下所示。它首先抽出block參數並將其加載到DOM對象中,以便可以對其進行分析。 simple_html_dom對象由simplehtmldom模塊提供,您將需要安裝並啓用它。不要忘記安裝相關的庫。這應該最終在/all/libraries/simplehtmldom/simple_html_dom.php。
function get_menu_tabs() {
// drupal_set_message(t("get_menu_tabs: @code", array('@code' => print_r(null, TRUE))));
if (array_key_exists ('block', $_GET)) {
$block = $_GET['block'];
// drupal_set_message(t("get_menu_tabs block: @code", array('@code' => print_r($block, TRUE))));
// Create a DOM object.
$html_obj = new simple_html_dom();
// Load HTML from a string.
$html_obj->load($block);
// remove href for nodes not yet visited
$index = 0;
foreach ($html_obj->find('li') as $li) {
$start = strpos($li->innertext, 'href');
$end = strpos($li->innertext, '>', $start);
$start_html = substr($li->innertext, 0, $end);
$end_html = substr($li->innertext, $end);
if (strpos($li->innertext, 'active')) {
$li->innertext = $start_html.' style="color:red;border: solid red;margin-left:5px;margin-right:5px;"'.$end_html;
// drupal_set_message(t("get_menu_tabs html_obj: @code", array('@code' => print_r($li->innertext, TRUE))));
}
else
$li->innertext = $start_html.' style="color:black;border: solid #777;"'.$end_html;
$index++;
}
$str = $html_obj->save();
// drupal_set_message(t("get_menu_tabs str: @code", array('@code' => print_r($str, TRUE))));
// Release resources to avoid memory leak in some versions.
$html_obj->clear();
unset($html_obj);
return drupal_json_output(array('block'=>$str));
}
}
最後,它通過li項目循環添加一個內聯CSS樣式,該樣式根據選項卡是否處於活動狀態而變化。然後它只是從DOM對象創建一個字符串,並通過drupal_json_output將其轉換爲json格式。這當然是在JS回調函數中收到的。