首先推薦如下本身的輕量無依賴富文本編輯器:html
CCEditorhtml5
以爲不錯,給個star支持一下,謝謝node
JavaScript最初的一個應用,就是分擔服務器處理表單的責任,打破到處依賴服務器的局面。儘管目前的Web和JavaScript已經有了長足的發展,但Web表單的變化並不明顯。因爲Web表單沒有爲許多常見任務提供現成的解決手段,不少開發人員不只會在驗證表單時使用JavaScript,並且還加強了一些標準表單控件的默認行爲。git
在HTML中,表單是由<form>
元素來表示的,,而在JavaScript中,表單對應的則是HTMLFormElement類型。HTMLFormElement繼承了HTMLElement,於是與其餘HTML元素具備相同的默認屬性。不過,HTMLFormElement也有它本身獨有的屬性和方法。github
用戶單擊提交按鈕或圖像按鈕時,就會提交表單。使用<input>
或<button>
均可以定義提交按鈕,只要將其type特性的值設置爲submit
便可,而圖像按鈕則是經過將<input>
的type特性值設置爲「image」來定義的。正則表達式
只要表單中存在上面列出的任何一種按鈕,那麼在相應表單控件擁有焦點的狀況,數組
在用戶單擊重置按鈕時,表單會被重置。使用type特性值爲"reset"的<input>
或<button>
均可以建立重置按鈕。瀏覽器
<input type='reset' value='Reset Form'>
<button type='reset'>Reset Form</button>
複製代碼
這兩個按鈕均可以用來重置表單。在重置表單時,全部表單字段都會恢復到頁面剛加載完畢時的初始值。若是某個字段的初始值爲空,就會恢復爲空;而帶有默認值的字段,也會恢復爲默認值。bash
與提交表單同樣,也能夠經過JavaScript來重置表單。服務器
能夠像訪問頁面中的其餘元素同樣,使用原生DOM方法訪問表單元素。
此外,每一個表單都有elements屬性,該屬性是表單中全部元素的集合。這個elements集合是一個有序列表,其中包含着表單中的全部字段
除了<fieldset>
元素以外,全部表單字段都擁有相同的一組屬性。因爲<input>
類型能夠表示多種表單字段,所以有些屬性只適用於某些字段,但還有一些屬性是全部字段所共有的。表單字段共有的屬性和方法以下。
可使用JavaScript動態修改其餘任何屬性。
// 避免屢次提交表單
form.addEventListener('submit', function (e) {
var target = e.target;
// 取得提交按鈕
var btn = target.elements['submit-btn'];
//禁用它
btn.disabled = true;
})
複製代碼
以上代碼爲表單的submit事件添加了一個事件處理程序。事件觸發後,代碼取得了提交按鈕並將其disabled屬性設置爲true。
注意,不能經過onclick事件處理程序來實現這個功能,緣由是不一樣瀏覽器之間存在「時差」:有的瀏覽器會在觸發表單的submit事件以前觸發click事件,有的瀏覽器則相反。對於先觸發click事件的瀏覽器,意味着會在提交發生以前禁用按鈕,結果永遠都不會提交表單。所以,最好是經過submit事件來禁用提交按鈕。不過,這種方式不適合表單中不包含提交按鈕的狀況;如前所述,只有在包含提交按鈕的狀況下,纔有可能觸發表單的submit事件。
每一個表單字段都有兩個方法:focus()和blur()。其中,focus()方法用於將瀏覽器的焦點設置到表單字段,即激活表單字段,使其能夠響應鍵盤事件。例如,接收到焦點的文本框會顯示插入符號,隨時能夠接收輸入。
默認狀況下,只有表單字段能夠得到焦點。對於其餘元素而言,若是現將其tabIndex屬性設置爲-1,而後再調用focus()方法,也可讓這些元素得到焦點。
強調: tabindex設置爲-1可讓不能被focus的元素變的能夠focus。可是設置好後,只能經過js的focus()方法來選中,沒法經過鍵盤的tab選中。
除了支持鼠標、鍵盤、更改和HTML事件以外,全部表單字段都支持下列3個事件。
<input>和<textarea>
元素,在它們失去焦點且value值改變時觸發;對於<select>
,在其選項改變時觸發。在HTML中,有兩種方式來表現文本框:一種是使用<input>
元素的單行文本框,另外一種是使用<textarea>
的多行文本框。這兩個控件很是類似,並且多數時候的行爲也差很少。不過,它們之間仍然存在一些重要的區別。
若是要建立一個文本框,讓它可以顯示25個字符,但輸入不能超過50個字符,可使用如下代碼:
<input type='text' size='25' maxlength='50' value='initial value'>
複製代碼
相對而言,<textarea>
元素則始終會呈現爲一個多行文本框。要指定文本框的大小,可使用rows和cols特性。其中,rows特性指定的是文本框的字符行數,而cols特性指定的是文本框的字符列數。與<input>
元素不一樣,<textarea>
的初始值必需要放在<textarea>
和</textarea>
之間。
另外一個與<input>
的區別在於,不能在HTML中給<textarea>
指定最大字數。
建議經過使用value屬性讀取或設置文本框的值,不建議使用標準的DOM方法。 緣由很簡單:對value屬性所做的修改,不必定會反映在DOM中。所以,在處理文本框的值時,最好不要使用DOM方法。
上述兩種文本框都支持select()方法,這個方法用於選擇文本框中的全部文本。在調用select() 方法時,大多數瀏覽器都會將焦點設置到文本框中。這個方法不接受參數,能夠在任什麼時候候被調用。
在文本框得到焦點時選擇其全部文本,這是一種很是常見的作法,特別是在文本框包含默認值的時候。由於這樣作可讓用戶沒必要一個一個地刪除文本。
與select()方法對應的,是一個select事件。在選擇了文本框中的文本時,就會觸發select事件。 另外,在調用select()方法時也會觸發select事件。
雖然經過select事件咱們能夠直到用戶何時選擇了文本,但仍然不知道用戶選擇了什麼文本。 HTML5經過一些擴展方案解決了這個問題,以便更順利地取得選擇的文本。
該規範採起的辦法是添加兩個屬性:selectionStart和selectionEnd。
這兩個屬性中保存的是基於0的數值,表示所選擇文本的範圍(即文本選區開頭和結尾的偏移量)。
HTML5也爲選擇文本框中的部分文本提供瞭解決方案,即最先由firefox引入的setSelectionRange() 方法。如今除Select()方法以外,全部文本框都有一個setSelectionRange()方法。這個方法接收兩個參數:要選擇的第一個字符的索引和要選擇的最後一個字符以後的字符的索引。
要看到選擇的文本,必須在調用setSelectionRange()以前或以後當即將焦點設置到文本框。
咱們常常會要求用戶在文本框中輸入特定的數據,或者輸入特定格式的數據。因爲文本框在默認狀況下沒有提供多少驗證數據的手段,所以必須使用JavaScript來完成此類過濾輸入的操做。而綜合運用事件的DOM手段,就能夠將普通的文本框轉換成可以理解用戶輸入數據的功能型控件。
響應向文本框中插入字符操做的是keypress事件。所以,能夠經過阻止這個事件的默認行爲 來屏蔽此類字符。
若是隻想屏蔽特定的字符,則須要檢測keypress事件對應的字符編碼,而後再決定如何響應。
雖然理論上只應該在用戶按下只應該在用戶按下字符鍵時才觸發keypress事件,但有些瀏覽器也會其餘鍵觸發此事件。
除此以外,還有一個問題須要處理:複製、粘貼及其餘操做還要用到Ctrl鍵。在除IE以外的全部瀏覽器中,前面的代碼也會屏蔽ctrl+C、ctrl+V,以及其餘使用Ctrl組合件。所以,最後還要添加一個檢測條件,以確保用戶沒有按下Ctrl鍵。
HTML5後來也把剪貼板事件歸入了規範。下列就是6個剪貼板事件。
要訪問剪貼板中的數據,可使用clipboardData對象:在IE中,這個對象是window對象的屬性; 而在Firefox、Safari和Chrome中,這個對象是相應event對象的屬性。
爲了確保跨瀏覽器兼容性,最好只在發生剪貼板事件期間使用這個對象。
這個clipboardData對象有三個方法:getData(format)、setData(format, value)和clearData()。
使用JavaScript能夠從多個方面加強表單字段的易用性。其中,最多見的一種方式就是在用戶填寫完當前字段時,自動將焦點切換到下一個字段。一般,在自動切換焦點以前,必須知道用戶已經輸入了既定長度的數據。
input有一個問題初始值長度超過maxlength不會被截斷。
爲了在將表單提交到服務器以前驗證數據,HTML5新增了一些功能。有了這些功能,即使JavaScript被禁用或者用於種種緣由未能加載,也能夠確保基本的驗證。
換句話說,瀏覽器本身會根據標記中的規則執行驗證,而後本身顯示適當的錯誤消息(徹底不用JavaScript插手)。固然,這個功能只有在支持HTML5這部份內容的瀏覽器中才有效。
第一種狀況是在表單字段中指定了required屬性:
<input type='text' name='username' required>
複製代碼
任何標註有required的字段,在提交表單時都不能空着。
這個屬性適用於<input>、<textarea>、<select>
字段。在JavaScript中,經過對應的required 屬性,能夠檢查某個表單字段是否爲必填字段。
var isUsernameRequired = document.forms[0].elements['username'].required;
複製代碼
另外,使用下面這行代碼能夠測試瀏覽器是否支持required屬性。
var isRequiredSupported = 'required' in document.createElement('input');
複製代碼
HTML5爲<input>
元素的type屬性又增長了幾個值。這些新的類型不只能反映數據類型的信息,並且還能提供一些默認的驗證功能。其中「email」和「url」是兩個獲得支持最多的類型,各瀏覽器也都爲它們增長了定製的驗證機制。
要檢測瀏覽器是否支持這些新類型,能夠在JavaScript建立一個<input>
元素,而後將type屬性設置爲「email」和「url」,最後再檢測這個屬性的值。不支持它們的舊版本瀏覽器會自動將未知的值設置爲「text」,而支持的瀏覽器則會返回正確的值。
除了「email」和「url」,HTML5還定義了另外幾個輸入元素。這幾個元素都要求填寫某種基於數字的值:「number」、「range」、「datetime」、「datetime-local」、「date」、「month」、「week」還有「time」。
HTML5爲文本字段新增了pattern屬性。這個屬性的值是一個正則表達式,用於匹配文本框中的值。
注意,模式的開頭和末尾不用加^和$符號(假定已經有了)。這兩個符號表示輸入的值必須從頭至尾都與模式匹配。
與其餘輸入類型類似,指定pattern也不能阻止用戶輸入無效的文本。這個模式應用給值,瀏覽器來判斷值是否有效。在JavaScript中能夠經過pattern屬性訪問模式。
var isPatternSupported = 'pattern' in document.createElement('input')
複製代碼
使用checkValidity()方法。
與checkValidity()方法簡單地告訴你字段是否有效相比,validity屬性則會告訴你爲何字段有效或無效。這個對象中包含一系列屬性,每一個屬性會返回一個布爾值。
經過設置novalidate屬性,能夠告訴表單不進行驗證。
在JavaScript中使用noValidate屬性能夠取得或設置這個值,若是這個屬性存在,值爲true,若是不存在,值爲false。
document.forms[0].noValidate = true; //禁用驗證
複製代碼
選擇框是經過<select>和<option>
元素建立的。爲了方便與這個控件交互,除了全部表單字段共有的屬性和方法外,HTMLSelectElement類型還提供了下列屬性和方法。
<option>
元素,其位置在相關項(relOption)以前。<option>
元素的HTMLCollection。選擇框的type屬性不是‘select-one’,就是‘select-multiple’,這取決於HTML代碼中有沒有multiple特性。選擇框的value屬性由當前選中項決定,相應規則以下:
在DOM中,每一個<option>
元素都有一個HTMLOptionElement對象表示。爲便於訪問數據,HTMLOptionElement對象添加了下列屬性:
其中大部分屬性的目的,都是爲了方便對選項數據的訪問。
var $selectbox = document.forms[0].elements['location'];
//不推薦
var text = selectbox.options[0].firstChild.nodeValue;
var value = selectbox.options[0].getAttribute('value');
//推薦
var text = selectbox.options[0].text; //選項的文本
var value = selectbox.options[0].value; //選項的值
複製代碼
在操做選項時,咱們建議最好是使用特定於選項的屬性,由於全部瀏覽器都支持這些屬性。在將表單控件做爲DOM節點的狀況下,實際的交互方式則會因瀏覽器而異。咱們不推薦使用標準DOM技術修改<option>
元素的文本或者值。
提醒:選擇框的change事件與其餘表單字段的change事件觸發的條件不同。其餘表單字段的change事件是在值被修改且焦點離開當前字段時觸發,而選擇框的change事件只要選中了選項就會觸發。
對於只容許選擇一項的選擇框,訪問選中項的最簡單方式,就是使用選擇框的selectedIndex屬性:
var selectedOption = selectbox.options[selectbox.selectedIndex];
var selectedIndex = selectbox.selectedIndex;
var selectedOption = selectbox.options[selectedIndex];
alert("Selected index: " + selectedIndex + '\nSelected text: ' +
selectedOption.text + '\nSelected value: ' + selectedOption.value);
複製代碼
對於能夠多選的選擇框,selectedIndex會致使取消之前的全部選項並選擇指定的那一項,而讀取selectedIndex則只會返回選中項中第一項的索引值。
另外一種選擇選項的方式,就是取得對某一項的引用,而後將其selected屬性設置爲true。例如,下面的代碼會選中選擇框中的第一項:
selectbox.options[0].selected = true;
複製代碼
實際上,selected屬性的做用主要是肯定用戶選擇了選擇框中的哪一項。要取得全部選中的項,能夠循環遍歷選項集合,而後測試每一個選項的selected屬性。
複製代碼
使用DOM的方法:
var $newOption = document.createElement('option');
$newOption.appendChild(document.createTextNode('Option text'));
newOption.setAttribute(newOption);
複製代碼
第二種方式是使用Option構造函數來建立選項,這個構造函數是DOM出現以前就有的。
第三種添加新選項的方式是使用選擇框的add()方法。DOM規定這個方法接受兩個參數:要添加的新選項和將位於新選項以後的選項。
與添加選項類型,移除選項的方式也有不少種。首先,可使用DOM的removeChild()方法,爲其傳入要移除的選項:
selectbox.removeChild(selectbox.options[0]); //移除第一個選項
複製代碼
其次,可使用選擇框的remove()方法。這個方法接受一個參數,即要移除選項的索引。
selectbox.remove(0)
複製代碼
最後一種方式,就是將相應選項設置爲null。這種方式也是DOM出現以前瀏覽器的遺留機制。
selectbox.options[0] = null; //移除第一個選項
複製代碼
咱們知道,若是爲appendChild()方法傳入一個文檔中已有的元素,那麼就會先從該元素的父節點中移除它,再把它添加到指定的位置。
移動選項與移除選項有一個共同之處,即會重置每個選項的index屬性。
重排選項次序的過程也十分相似,最好的方式仍然是使用DOM方法。要將選擇框中的某一項移動到特定位置,最合適的DOM方法就是insertBefore();appendChild()方法只適用於將選項添加到選擇框的最後。
var $lastOption = $selectDom.options[$selectDom.options.length - 1];
$selectDom.insertBefore($lastOption, $selectDom.options[0]);
複製代碼
隨着Ajax的出現,表單序列化已經成爲一種常見需求。在JavaScript中,能夠利用表單字段的type屬性,連同name和value屬性一塊兒實現對錶單的序列化。
在編寫代碼以前,有必須先搞清楚在表單提交期間,瀏覽器是怎樣將數據發送給服務器的:
這一技術的本質,就是在頁面中嵌入一個包含空HTML頁面的iframe。經過設置designMode屬性,這個空白的HTML頁面能夠被編輯,而編輯對象則是該頁面<body>
元素的HTML代碼。designMode屬性有兩個可能的值:「off」和「on」。在設置爲「on」時,整個文檔都會變得能夠編輯,而後就能夠像使用字處理軟件同樣。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>WYSIWYG</title>
</head>
<body>
<iframe name='richedit' src="blank.htm" frameborder="1" style='width:500px;height:500px;'></iframe>
<script>
window.onload = function () {
window.frames['richedit'].document.designMode = 'on';
}
</script>
</body>
</html>
複製代碼
要讓iframe內部能夠編輯,必需要將designMode設置爲「on」,但只有在頁面徹底加載以後才能設置這個屬性。所以,在包含頁面中,須要使用onload事件處理程序來在恰當的時刻設置designMode。
等到以上代碼執行以後,你就會在頁面中看到一個相似文本框的可編輯區字段。這個區字段具備與其餘網頁相同的默認樣式;不過,經過爲空白頁面應用CSS樣式,能夠修改可編輯區字段的外觀。
另外一種編輯富文本內容的方式是使用名爲contentieditable的特殊屬性,這個屬性也是由IE最先實現的。
Tips: difference between boolean attribute and enumerated attribute.
contenteditable屬性有三個可能的值:「true」表示打開、「false」表示關閉,「inherit」表示從副元素那裏繼承。
與富文本編輯器交互的主要方式,就是使用document.execCommand()。
在富文本編輯器中,使用框架(iframe)的getSelection()方法,能夠肯定實際選擇的文本。這個方法是window對象和document對象的屬性,調用它會返回一個表示當前文本的Selection對象。每一個Selection對象都有下列屬性。
Selection對象的這些屬性並無包含多少有用的信息。好在,該對象的下列方法提供了更多信息,而且支持對選區的操做。
Selection對象的這些方法都極爲實用,它們利用了DOM範圍來管理選區。因爲能夠直接操做選擇文本的DOM表現,所以訪問DOM範圍與實用execCommand()相比,可以對富文本編輯器進行更加細化的控制。
因爲富文本編輯是使用iframe而非表單控件實現的,所以從技術上說,富文本編輯並不屬於表單。因此提交編輯器內容的方法是:添加一個隱藏的表單字段,讓它的值等於從iframe中提取出的HTML。
雖然HTML和Web應用自誕生以來已經發生了天翻地覆的變化,但Web表單相對卻沒有什麼改變。使用Javascript能夠加強已有的表單字段,從而創造新的功能,或者提高表單的易用性。