JavaScript DOM 學習第二章 編輯文本
更新時間:2010年02月19日 13:15:13 作者:
在這一章我會給出一個在CMS里非常有用的更新頁面的代碼。在任一段落點擊鼠標你就可以修改了。完成以后點擊按鈕,修改的文本就顯示了。
例子
這個頁面就是個例子。點擊一個段落,編輯,然后點Ready。你的修改就會呈現(xiàn)。
問題
遇到的第一個問題是:我想用文本框作為編輯區(qū)域。一開始我卻把內容放不進文本框去。讀者發(fā)現(xiàn)Mozilla的一個警告說是只有在文本框放置到文檔之后才能設置它的value。
另外,在Mozilla下面內容包裝的不是很好。我試了好幾種wrap參數(shù),但是結果都不是很好。
最嚴重的問題就是把修改后的內容發(fā)回服務器,這是幾乎所有的CMS系統(tǒng)都要做的。讀者給了我很多高明巧妙的建議。然而因為不能通過JavaScript完成,所以我也不能提供解決辦法。所以也請您不要發(fā)郵件告訴你找到了辦法:那也許可行,但是我只想要純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;
創(chuàng)建一個按鈕
然后我們創(chuàng)建一個Radey按鈕,后面會需要很多次。這需要一些高級腳本技術,所以先做一些對象檢測:
如果是現(xiàn)代瀏覽器,則創(chuàng)建按鈕:
他的文本是:
把這個文本添加到按鈕上:
然后添加一個onclick事件處理程序:
現(xiàn)在按鈕就存儲在butt里面,需要的時候我們就可以直接引用。
將P轉為文本框
稍后我們會為整個頁面定義一個onclick事件。所有的這些事件都會發(fā)送到catchIt()函數(shù)。
首先檢測用戶是否正常編輯段落,如果是,結束函數(shù):
然后是支持性檢測:
然后尋找事件的源:
現(xiàn)在我們有了事件的源,但是有個問題是Mozilla會認為文本節(jié)點是源(而不是我們需要的P節(jié)點)。所以如果節(jié)點不是標簽(nodeType不是1),我們需要向上遍歷DOM樹:
現(xiàn)在我們以一個標簽結束。如果這是一個文本框的標簽那么用戶點擊之后就可以編輯了。如果是一個鏈接的標簽那么用戶點擊之后應該還是作為一個鏈接來反映的。這兩種情況下我們就不需要這個函數(shù)了:
我們需要再一次的向上遍歷DOM樹直到找到P標簽或者HTML標簽:
如果是HTML標簽那么表示用戶在段落之外點擊的,就結束函數(shù):
經(jīng)過這個檢測我們最終確定用戶點擊的是我們想要編輯的段落。然后保存段落的innerHTML:
創(chuàng)建一個新的TEXTAREA然后保存:
然后找到段落的父節(jié)點:
當用戶點擊Ready按鈕,就應該反過來了。這個由saveEdit()函數(shù)來完成。
function saveEdit() {得到TEXTAREA(這里假設整個頁面只有一個TEXTAREA):
var area = document.getElementsByTagName('TEXTAREA')[0]創(chuàng)建一個新的段落并保存:
找到文本框的父元素:新的段落需要添加到那去:
將文本框的值存儲在新的段落里:
然后把新的段落插入在文本框之前:
移除文本框:
移除Ready按鈕(同樣的,假設頁面只有一個按鈕):
然后設置editing為false:用戶停止編輯:
事件
在函數(shù)之外,設置一個整個頁面的onclick事件:
翻譯地址:http://www.quirksmode.org/dom/cms.html
轉載請保留以下信息
作者:北玉(tw:@rehawk)
這個頁面就是個例子。點擊一個段落,編輯,然后點Ready。你的修改就會呈現(xiàn)。
問題
遇到的第一個問題是:我想用文本框作為編輯區(qū)域。一開始我卻把內容放不進文本框去。讀者發(fā)現(xiàn)Mozilla的一個警告說是只有在文本框放置到文檔之后才能設置它的value。
另外,在Mozilla下面內容包裝的不是很好。我試了好幾種wrap參數(shù),但是結果都不是很好。
最嚴重的問題就是把修改后的內容發(fā)回服務器,這是幾乎所有的CMS系統(tǒng)都要做的。讀者給了我很多高明巧妙的建議。然而因為不能通過JavaScript完成,所以我也不能提供解決辦法。所以也請您不要發(fā)郵件告訴你找到了辦法:那也許可行,但是我只想要純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;
創(chuàng)建一個按鈕
然后我們創(chuàng)建一個Radey按鈕,后面會需要很多次。這需要一些高級腳本技術,所以先做一些對象檢測:
復制代碼 代碼如下:
if (document.getElementById && document.createElement) {
如果是現(xiàn)代瀏覽器,則創(chuàng)建按鈕:
復制代碼 代碼如下:
var butt = document.createElement('BUTTON');
他的文本是:
復制代碼 代碼如下:
var buttext = document.createTextNode('Ready!');
把這個文本添加到按鈕上:
復制代碼 代碼如下:
butt.appendChild(buttext);
然后添加一個onclick事件處理程序:
復制代碼 代碼如下:
butt.onclick = saveEdit; 2 }
現(xiàn)在按鈕就存儲在butt里面,需要的時候我們就可以直接引用。
將P轉為文本框
稍后我們會為整個頁面定義一個onclick事件。所有的這些事件都會發(fā)送到catchIt()函數(shù)。
復制代碼 代碼如下:
function catchIt(e){
首先檢測用戶是否正常編輯段落,如果是,結束函數(shù):
復制代碼 代碼如下:
if (editing) return;
然后是支持性檢測:
復制代碼 代碼如下:
if (!document.getElementById || !document.createElement) return;
然后尋找事件的源:
復制代碼 代碼如下:
if (!e) var obj = window.event.srcElement; 2 else var obj = e.target;
現(xiàn)在我們有了事件的源,但是有個問題是Mozilla會認為文本節(jié)點是源(而不是我們需要的P節(jié)點)。所以如果節(jié)點不是標簽(nodeType不是1),我們需要向上遍歷DOM樹:
復制代碼 代碼如下:
while (obj.nodeType != 1) { 2 obj = obj.parentNode; 3 }
現(xiàn)在我們以一個標簽結束。如果這是一個文本框的標簽那么用戶點擊之后就可以編輯了。如果是一個鏈接的標簽那么用戶點擊之后應該還是作為一個鏈接來反映的。這兩種情況下我們就不需要這個函數(shù)了:
復制代碼 代碼如下:
if (obj.tagName == 'TEXTAREA' || obj.tagName == 'A') return;
我們需要再一次的向上遍歷DOM樹直到找到P標簽或者HTML標簽:
復制代碼 代碼如下:
while (obj.nodeName != 'P' && obj.nodeName != 'HTML') { 2 obj = obj.parentNode; 3 }
如果是HTML標簽那么表示用戶在段落之外點擊的,就結束函數(shù):
復制代碼 代碼如下:
if (obj.nodeName == 'HTML') return;
經(jīng)過這個檢測我們最終確定用戶點擊的是我們想要編輯的段落。然后保存段落的innerHTML:
復制代碼 代碼如下:
var x = obj.innerHTML;
創(chuàng)建一個新的TEXTAREA然后保存:
復制代碼 代碼如下:
var y = document.createElement('TEXTAREA');
然后找到段落的父節(jié)點:
復制代碼 代碼如下:
var z = obj.parentNode;
現(xiàn)在就成了這樣:
z | --------------------------------------- | | | | | [more] y(TEXTAREA) butt(BUTTON) P [more]
然后刪除段落?,F(xiàn)在看起來就好像是文本框和按鈕代替了之前的段落。
直到現(xiàn)在,插入文本框之后,我們才能把段落的innerHTML放置在文本框內。Mozilla里面不支持在插入之前給文本框內添加內容。
y.value = x;
為了用戶方便給文本框焦點:
y.focus();
然后設置editing為true。
editing = true; }將文本框轉換為P
當用戶點擊Ready按鈕,就應該反過來了。這個由saveEdit()函數(shù)來完成。
function saveEdit() {得到TEXTAREA(這里假設整個頁面只有一個TEXTAREA):
var area = document.getElementsByTagName('TEXTAREA')[0]創(chuàng)建一個新的段落并保存:
復制代碼 代碼如下:
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 }
事件
在函數(shù)之外,設置一個整個頁面的onclick事件:
復制代碼 代碼如下:
document.onclick = catchIt;
翻譯地址:http://www.quirksmode.org/dom/cms.html
轉載請保留以下信息
作者:北玉(tw:@rehawk)
相關文章
document.getElementById獲取控件對象為空的解決方法
今天寫個網(wǎng)頁,想在頁面加載onLoad時,動態(tài)顯示由后臺其他程序傳來的數(shù)據(jù)時,用document.getElementById獲取控件對象總是為空。但是檢查了這個id確實是存在的??聪挛牡氖纠徒鉀Q方法2013-11-11詳解微信小程序中var、let、const用法與區(qū)別
微信小程序是可以使用最新ES6標準規(guī)范的Javascript來開發(fā)的,所有ES6中的新特性微信小程序也是支持的,下面我們來總結下信小程序中var、let、const用法與區(qū)別2020-01-01JavaScript中的toUTCString()方法使用詳解
這篇文章主要介紹了JavaScript中的toUTCString()方法使用詳解,是JS入門學習中的基礎知識,需要的朋友可以參考下2015-06-06javascript使用window.open提示“已經(jīng)計劃系統(tǒng)關機”的原因
這篇文章主要介紹了javascript使用window.open提示“已經(jīng)計劃系統(tǒng)關機”的原因,本文得出結論是安裝了系統(tǒng)更新或其它原因,要把系統(tǒng)重啟時才會提示這個問題,所以,遇到這個問題,重啟你的電腦吧2014-08-08javascript基礎第一章 JavaScript與用戶端
javascript基礎第一章 JavaScript與用戶端2010-07-07