JavaScript DOM 學習第二章 編輯文本

來源:互聯網
上載者:User

例子
這個頁面就是個例子。點擊一個段落,編輯,然後點Ready。你的修改就會呈現。

問題
遇到的第一個問題是:我想用文字框作為編輯地區。一開始我卻把內容放不進文字框去。讀者發現Mozilla的一個警告說是只有在文字框放置到文檔之後才能設定它的value。
另外,在Mozilla下面內容封裝的不是很好。我試了好幾種wrap參數,但是結果都不是很好。
最嚴重的問題就是把修改後的內容發回伺服器,這是幾乎所有的CMS系統都要做的。讀者給了我很多高明巧妙的建議。然而因為不能通過JavaScript完成,所以我也不能提供解決辦法。所以也請您不要發郵件告訴你找到了辦法:那也許可行,但是我只想要純JavaScript的不需要伺服器端代碼的方法。

指令碼 複製代碼 代碼如下:var editing = false;

if (document.getElementById && document.createElement) {
var butt = document.createElement('BUTTON');
var buttext = document.createTextNode('Ready!');
butt.appendChild(buttext);
butt.onclick = saveEdit;
}

function catchIt(e) {
if (editing) return;
if (!document.getElementById || !document.createElement) return;
if (!e) var obj = window.event.srcElement;
else var obj = e.target;
while (obj.nodeType != 1) {
obj = obj.parentNode;
}
if (obj.tagName == 'TEXTAREA' || obj.tagName == 'A') return;
while (obj.nodeName != 'P' && obj.nodeName != 'HTML') {
obj = obj.parentNode;
}
if (obj.nodeName == 'HTML') return;
var x = obj.innerHTML;
var y = document.createElement('TEXTAREA');
var z = obj.parentNode;
z.insertBefore(y,obj);
z.insertBefore(butt,obj);
z.removeChild(obj);
y.value = x;
y.focus();
editing = true;
}

function saveEdit() {
var area = document.getElementsByTagName('TEXTAREA')[0];
var y = document.createElement('P');
var z = area.parentNode;
y.innerHTML = area.value;
z.insertBefore(y,area);
z.removeChild(area);
z.removeChild(document.getElementsByTagName('button')[0]);
editing = false;
}

document.onclick = catchIt;

解釋
我們設定一個editing標誌為false。這用來顯示使用者是否正在編輯段落。當然初始是沒有。

var editing=false;

建立一個按鈕
然後我們建立一個Radey按鈕,後面會需要很多次。這需要一些進階指令碼技術,所以先做一些對象檢測:

複製代碼 代碼如下: if (document.getElementById && document.createElement) {

如果是現代瀏覽器,則建立按鈕:

複製代碼 代碼如下: var butt = document.createElement('BUTTON');

他的文本是:

複製代碼 代碼如下: var buttext = document.createTextNode('Ready!');

把這個文本添加到按鈕上:

複製代碼 代碼如下: butt.appendChild(buttext);

然後添加一個onclick事件處理常式:

複製代碼 代碼如下: butt.onclick = saveEdit; 2 }

現在按鈕就儲存在butt裡面,需要的時候我們就可以直接引用。

將P轉為文字框
稍後我們會為整個頁面定義一個onclick事件。所有的這些事件都會發送到catchIt()函數。

複製代碼 代碼如下: function catchIt(e){

首先檢測使用者是否正常編輯段落,如果是,結束函數:

複製代碼 代碼如下: if (editing) return;

然後是支援性檢測:

複製代碼 代碼如下: if (!document.getElementById || !document.createElement) return;

然後尋找事件的源:

複製代碼 代碼如下: if (!e) var obj = window.event.srcElement; 2 else var obj = e.target;

現在我們有了事件的源,但是有個問題是Mozilla會認為文本節點是源(而不是我們需要的P節點)。所以如果節點不是標籤(nodeType不是1),我們需要向上遍曆DOM樹:

複製代碼 代碼如下: while (obj.nodeType != 1) { 2 obj = obj.parentNode; 3 }

現在我們以一個標籤結束。如果這是一個文字框的標籤那麼使用者點擊之後就可以編輯了。如果是一個連結的標籤那麼使用者點擊之後應該還是作為一個連結來反映的。這兩種情況下我們就不需要這個函數了:

複製代碼 代碼如下: if (obj.tagName == 'TEXTAREA' || obj.tagName == 'A') return;

我們需要再一次的向上遍曆DOM樹直到找到P標籤或者HTML標籤:

複製代碼 代碼如下: while (obj.nodeName != 'P' && obj.nodeName != 'HTML') { 2 obj = obj.parentNode; 3 }

如果是HTML標籤那麼表示使用者在段落之外點擊的,就結束函數:

複製代碼 代碼如下: if (obj.nodeName == 'HTML') return;

經過這個檢測我們最終確定使用者點擊的是我們想要編輯的段落。然後儲存段落的innerHTML:

複製代碼 代碼如下: var x = obj.innerHTML;

建立一個新的TEXTAREA然後儲存:

複製代碼 代碼如下: var y = document.createElement('TEXTAREA');

然後找到段落的父節點:

複製代碼 代碼如下: var z = obj.parentNode;

現在就成了這樣:

            z            |  ---------------------------------------  |    |      |      |   | [more] y(TEXTAREA) butt(BUTTON) P  [more]

然後刪除段落。現在看起來就好像是文字框和按鈕代替了之前的段落。

直到現在,插入文字框之後,我們才能把段落的innerHTML放置在文字框內。Mozilla裡面不支援在插入之前給文字框內新增內容。

y.value = x;

為了使用者方便給文字框焦點:

y.focus();

然後設定editing為true。

editing = true;}

將文字框轉換為P
當使用者點擊Ready按鈕,就應該反過來了。這個由saveEdit()函數來完成。
function saveEdit() {得到TEXTAREA(這裡假設整個頁面只有一個TEXTAREA):
var area = document.getElementsByTagName('TEXTAREA')[0]建立一個新的段落並儲存: 複製代碼 代碼如下: var y = document.createElement('P');

找到文字框的父元素:新的段落需要添加到那去: 複製代碼 代碼如下: var z = area.parentNode;

將文字框的值儲存在新的段落裡: 複製代碼 代碼如下:y.innerHTML = area.value;

然後把新的段落插入在文字框之前: 複製代碼 代碼如下: z.insertBefore(y,area);

移除文字框: 複製代碼 代碼如下: z.removeChild(area);

移除Ready按鈕(同樣的,假設頁面只有一個按鈕): 複製代碼 代碼如下: z.removeChild(document.getElementsByTagName('button')[0]);

然後設定editing為false:使用者停止編輯: 複製代碼 代碼如下: editing = false; 2 }

事件
在函數之外,設定一個整個頁面的onclick事件: 複製代碼 代碼如下: document.onclick = catchIt;

翻譯地址:http://www.quirksmode.org/dom/cms.html
轉載請保留以下資訊
作者:北玉(tw:@rehawk)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.