自動儲存功能常見於線上編輯器,能有效防止使用者輸入內容意外遺失。本文示範如何結合 jQuery AJAX 與 PHP,實現 input 與 textarea 在 blur(失去焦點)事件觸發時,自動將資料送往後端儲存。特別針對中文編碼問題提供解決方案,並附上類 Excel 列表頁的完整範例碼。
blur 事件,透過 $.ajax() 發送 POST 請求。true,前端將輸入框邊框設為白色;失敗則彈出警示。以下程式碼模擬一個可編輯的資料表格,每列包含標題與描述兩個輸入欄位,並帶有預覽與編輯連結:
<table width="100%" align="left" border="0" cellspacing="0" bgcolor="#CCCCCC">
<tr onmouseover="this.className='on';" onmouseout="this.className='';" align="center" id="{$id}" bgcolor="#FFFFFF">
<td>{$id}</td>
<td><input type="text" id="title_{$id}" value="{$title}" onblur="ajaxEdit('{$id}','title');" ></td>
<td><textarea id="description_{$id}" rows="4" onblur="ajaxEdit('{$id}','description');">{$description}</textarea></td>
<td><a href="view.php?aid={$id}" target="_blank">預覽</a><a href="edit.php?aid={$id}">編輯</a></td>
</tr>
</table>
<script type="text/javascript">
function Dd(i) { return document.getElementById(i); }
function ajaxEdit(aid, field) {
var value = decodeURI(Dd(field + '_' + aid).value);
$.ajax({
type: 'POST',
url: 'edit.php',
data: { dopost: 'ajaxSave', aid: aid, field: field, value: value },
success: function(data) {
if (data == 'true') {
Dd(field + '_' + aid).style.border = '#fff';
} else {
alert('更新失敗,可能是網速太慢');
}
}
});
}
</script>
關鍵點:使用 decodeURI() 先解碼,確保中文內容在傳輸過程不會亂碼。
if ($dopost == 'ajaxSave') {
$value = urldecode(AutoCharset($value, 'UTF-8', 'GB2312'));
$inQuery = "UPDATE `dede_archives` SET $field='$value' WHERE id='$aid'";
if ($dsql->ExecuteNoneQuery($inQuery)) {
echo 'true';
exit;
} else {
echo 'false';
exit;
}
}
此處呼叫 DedeCMS 內建的 AutoCharset() 將 UTF-8 轉為 GB2312,若專案採用 UTF-8 資料庫可直接移除轉碼步驟。
針對富文本編輯器(如百度 UEditor),可利用瀏覽器 localStorage 實現離線草稿備份,每 25 秒檢查一次編輯器內容,若長度超過 20 字且包含中文標點則自動儲存。
<script type="text/plain" id="content" name="content" style="width:800px;height:400px;"></script>
<script type="text/javascript">
var editor = new UE.ui.Editor();
editor.render('content');
</script>
<!-- 自動保存功能 防止數據意外丟失 -->
<script type="text/javascript" src="localStorag.js"></script>
/* 注意: 本js腳本請在網頁源代碼最後的地方放置 */
if (!window.localStorage) {
alert('您的瀏覽器不支持 localStorage 技術!');
} else {
var spanObj = document.getElementById('s1');
var saveTimer = setInterval(function() {
var str = '';
if (document.all) { /* IE */
str = document.frames[1].document.body.innerHTML;
} else { /* Chrome, Firefox */
str = document.getElementById('ueditor_0').contentDocument.body.innerHTML;
}
if (str.length > 20 && (str.indexOf('。') > -1 || str.indexOf(',') > -1)) {
localStorage.setItem('ctValue', str);
var d = new Date();
var YMDHMS = d.getFullYear() + '-' + (d.getMonth()+1) + '-' + d.getDate() + ' ' + d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds();
spanObj.innerText = '(數據保存於: ' + YMDHMS + ')';
setTimeout(function() { spanObj.innerText = ''; }, 5000);
}
}, 25000); // 每隔 25 秒保存一次
function stoplocs() {
clearInterval(saveTimer);
// localStorage.removeItem('ctValue'); // 如需清空可取消註解
}
function showlocs() {
var html = localStorage.getItem('ctValue');
editor.setContent(html);
}
}
<a href="javascript:void(0)" onclick="javascript:stoplocs()">停止保存</a>
<a href="javascript:void(0)" onclick="javascript:showlocs()">立即恢復</a>
相容性:支援 IE8+、Chrome、Firefox 等主流瀏覽器。IE6 已淘汰,不再納入考量。