使用者介面(User Interface,UI)事件負責響應使用者與頁面元素的互動。
焦點處理
焦點處理主要包括獲取焦點(focus)和失去焦點(blur)事件型別。所謂焦點,就是啟用表單欄位,使其可以相應鍵盤事件。
focus
當單擊或使用 Tab 鍵切換到某個表單元素或超連結物件時,會觸發該事件。focus 事件是確定頁面內滑鼠當前定位的一種方式。在預設情況下,整個文件處於焦點狀態,但是單擊或使用 Tab 鍵可以改變焦點的位置。
blur
blur 事件型別表示在元素失去焦點時響應,它與 focus 事件型別是相對的,主要作用於表單元素和超連結物件。
【範例1】在下面範例中為所有輸入表單元素系結了 focus 和 blur 事件處理常式,設定當元素獲取焦點時呈凸起顯示,失去焦點時則顯示為預設的凹陷效果。
<input type="text" />
<input type="text" />
<script>
var o = document.getElementsByTagName("input"); //獲取表單元素集合
for (var i = 0; i < o.length; i ++ ) { //遍歷所有表單元素
o[i].onfocus = function () { //註冊focus事件處理常式
this.style.borderStyle = "outset";
}
o[i].blur = function () { //註冊focus事件處理常式
this.style.borderStyle = "inset";
}
}
</script>
每個表單欄位都有兩個方法:focus() 和 blur(),其中 focus() 方法用於設定表單欄位為焦點。
【範例2】在下面範例中設計在頁面載入完畢後將焦點轉移到表單中的第 1 個文字方塊欄位中,讓其準備接收使用者輸入。
<form id="myform" method="post" action="#">
姓名<input type="text" name="name" /><br />
密碼<input type="password" name="pass" /><br />
</form>
<script>
var form = document.getElementById("myform");
var field = form.elements["name"];
window.onload = function () {
field.focus();
}
</script>
如果是隱藏欄位(<input type="hidden">)或者使用 CSS 的 display 和 visibility 隱藏欄位顯示,設定其獲取焦點將引發異常。
blur() 方法的作用時從元素中移走焦點。在呼叫 blur() 方法時,並不會把焦點轉移到某個特定的元素上,僅僅時將焦點移走。早期開發中有使用者使用 blur() 方法代替 readonly 屬性,建立唯讀欄位。
選擇文字
當在文字方塊或文字區域內選擇文字時,將觸發 select 事件。通過該事件可以設計使用者選擇操作的互動行為。
在 IE 9+、Opera、Firefox、Chrome 和 Safari 中,只有使用者選擇了文字且釋放滑鼠,才會觸發 select 事件;但是在 IE8 及更早版本中,只要使用者選擇了一個字母,不必釋放滑鼠,就會觸發 select 事件。另外,在呼叫 select() 方法時也會觸發 select 事件。
【範例】在下面的範例中,當選擇第 1 個文字方塊中的文字時,則在第 2 個文字方塊中會動態顯示使用者所選擇的文字。
<input type="text" id="a" value="請隨意選擇字串" />
<input type="text" id="b" />
<script>
var a = document.getElementsByTagName("input")[0];
// 獲取第一個文字方塊的參照指標
var b = document.getElementsByTagName("input")[1];
// 獲取第二個文字方塊的參照指標
a.onselect = function(){ // 為第一個文字方塊系結select事件處理常式
if (document.selection){ // 相容IE
o = document.selection.createRange(); // 建立一個選擇區域
if(o.text.length > 0) // 如果選擇區域記憶體在文字
b.value = o.text; // 則把該區域內的文字賦值給第二個文字方塊
}else{ // 相容DOM
p1 = a.selectionStart; // 獲取文字方塊中選擇的初始位置
p2 = a.selectionEnd; // 獲取文字方塊中選擇的結束位置
b.value = a.value.substring(p1, p2);
// 擷取文字方塊中被選取的文字字串,然後賦值給第二個文字方塊
}
}
</script>
欄位值變化監測
change 事件型別時在表單元素的值發生變化時觸發,它主要用於 input、select 和 textarea 元素。對於 input 和 textarea 元素來說,當它們失去焦點且 value 值改變時觸發;對於 select 元素,在其選項改變時觸發,也就是不是去焦點,也會觸發 change 事件。
範例1
在下面範例中,當在第 1 個文字方塊中輸入或修改值時,則第 2 個文字方塊內會立即顯示第 1 個文字方塊中的當前值。
<input type="text" id="a" />
<input type="text" id="b" />
<script>
var a = document.getElementsByTagName("input")[0];
var b = document.getElementsByTagName("input")[1];
a.onchange = function(){ // 為第一個文字方塊系結change事件處理常式
b.value = this.value; // 把第一個文字方塊中的值傳遞給第二個文字方塊
}
</script>
範例2
下面範例演示了當在下拉選單框中選擇不同的網站時,會自動開啟該網站的首頁。
<select>
<option value="http://www.baidu.com/">百度</option>
<option value="http://www.google.cn/">Google</option>
</select>
<script>
var a = document.getElementsByTagName("select")[0];
a.onchange = function(){
window.open(this.value,""); // 根據下拉選單框的當前值開啟指定的網址
}
</script>
範例3
在其他表單元素中也可以應用 change 事件型別。下面範例演示了如何在無線電鈕選項組中動態顯示變化的值。
<input type="radio" name="r" value="1" checked="checked" /> 1
<input type="radio" name="r" value="2" /> 2
<input type="radio" name="r" value="3" /> 3
<script>
var r = document.getElementsByTagName("input");
for(var i = 0; i < r.length; i ++ ){
r[i].onchange = function(){
alert(this.value);
}
}
</script>
對於 input 元素來說,由於 change 事件型別僅在使用者已經離開了元素且失去焦點時觸發,所以當執行上面 3 個範例時會明顯感覺延遲響應現象。為了更好地提升使用者體驗,很多時候會根據需要定義在按鍵鬆開或滑鼠單擊時執行響應,這樣速度會快很多。
focus、blur 和 change 事件經常配合使用。一般可以使用 focus 和 blur 事件來以某種方式改變使用者介面,要麼是向使用者給出視覺提示,要麼是向介面中新增額外的功能。例如,為文字方塊顯示一個下拉選項選單。而 change 事件則經常用於驗證使用者在欄位中輸入的資料。
範例4
下面範例設計一個文字方塊,只允許使用者輸入數值。此時,可以利用 focus 事件修改文字方塊的背景顏色,以便更清楚的表明這個欄位獲得了焦點。可以利用 blur 事件恢復文字方塊的背景顏色,利用 change 事件在使用者輸入了非數位字元時再次修改背景顏色。
<form id="myform" method="post" action="javascript:alert('表單提交啦!')">
<p>
<label for="comments">請輸入數位:</label>
<br />
<input type="text" id="txtNumbers" name="numbers" />
</p>
<p>
<input type="submit" value="提交表單" id="submit-btn" />
</p>
</form>
<script>
var form = document.getElementById("myform");
var numbers = form.elements["numbers"];
numbers.onfocus = function(event){
event = event || window.event;
var target = event.target || event.srcElement;
target.style.backgroundColor = "yellow";
}
numbers.onblur = function(event){
event = event || window.event;
var target = event.target || event.srcElement;
if (/[^d]/.test(target.value)){
target.style.backgroundColor = "red";
} else {
target.style.backgroundColor = "";
}
}
numbers.onchange = function(event){
event = event || window.event;
var target = event.target || event.srcElement;
if (/[^d]/.test(target.value)){
target.style.backgroundColor = "red";
} else {
target.style.backgroundColor = "";
}
}
numbers.focus();
</script>
在上面程式碼中,onfocus 事件處理程式將文字方塊的背景顏色修改為黃色,以清楚地表示當前欄位已經啟用。onblur 和 onchange 事件處理程式則會在發現非數值字元時,將文字方塊背景色修改為紅色。為了測試使用者輸入的是不是非數值,這裡針對文字方塊的 value 屬性使用了簡單的正規表示式。而且,為確保無論文字方塊的值如何變化,驗證規則始終如一,onblur 和 onchange 事件處理程式中使用了相同的正規表示式。
關於 blur 和 change 事件發生順序並沒有嚴格的規定,不同的瀏覽器沒有統一規定。因此,不能假定這兩個事件總會以某種順序一次觸發。
剪貼簿資料
HTML 5 規範了剪貼簿資料操作,主要包括以下 6 個剪貼簿事件:
-
beforecopy:在發生複製操作前觸發。
-
copy:在發生複製操作時發生。
-
beforecut:在發生剪下操作前觸發。
-
cut:在發生剪下操作時觸發。
-
beforepaset:在發生貼上操作前觸發。
-
paset:在發生貼上操作時觸發。
瀏覽器支援狀態:IE、Safari 2+、Chrome 和 Firefox 3+,Opera 不支援存取剪貼簿資料。
在 Safari、Chrome 和 Firefox 中,beforecopy、beforecut 和 beforepaste 事件只會顯示針對文字方塊的上下文選單的情況下觸發。IE 則會在觸發 copy、cut 和 paste 事件之前先行觸發這些事件。
至於 copy、cut 和 paste 事件,只要是在上下文選單中選擇了響應選項,或者使用了相應的鍵盤組合鍵,所有瀏覽器都會觸發它們。在實際的事件發生之前,通過 beforecopy、beforecut 和 beforepaste 事件可以在向剪貼簿傳送資料,或者從剪貼簿取得資料之前修改資料。
使用 clipboardData 物件可以存取剪貼簿中的資料。在 IE 中,可以任何狀態下使用 window.clipboardData 存取剪貼簿;在 Fiirefox 4+、Safari 和 Chrome 中,通過事件物件的 clipboardData 屬性存取剪貼簿,且只有在處理剪貼簿事件期間,clipboardData 物件才有效。
clipboardData 物件定義了兩個方法:
-
getData():從剪貼簿中讀取資料。包含 1 個 引數,設定取得的資料的格式。IE 提供兩種資料格式:“text”和“URL”;Firefox、Safari 和 Chrome 中定義引數為 MIME 型別,可以用“text”代表“text/plain”。
-
setData():設定剪貼簿資料。包含兩個引數,其中第 1 個引數設定資料型別,第 2 個引數是要放在剪貼簿中的文字。對於第 1 個引數,IE 支援“text”和“URL”,而 Safari 和 Chrome 仍然只支援 MIME 型別,但不再識別“text”型別。在成功將文字放到剪貼簿中後,都會返回 true;否則,返回 false。
範例1
可以使用下面兩個函數相容 IE 和非 IE 的剪貼簿資料操作。
var getClipboardText = function(event){
var clipboardData = (event.clipboardData || window.clipboardData);
return clipboardData.getData("text");
}
var setClipboardText = function(event, value){
if (event.clipboardData){
event.clipboardData.setData("text/plain", value);
} else if (window.clipboardData){
window.clipboardData.setData("text", value);
}
}
在上面程式碼中,getClipboardText() 方法比較簡單,它只要存取 clipboardData 物件,然後以 text 型別呼叫 getData() 方法;setClipboardText() 方法相對複雜,它在取得 clipboardData 物件之後需要根據不同的瀏覽器實現為 setData() 傳入不同的型別。
範例2
下面範例利用剪貼簿事件,當使用者向文字方塊貼上文字時,先檢測剪貼簿中的資料是否都為數位,如果不是數位,取消預設的行為,則禁止貼上操作,這樣可以確保文字方塊只能接收數位字元。
<script>
var form = document.getElementById("myform");
var field1 = form.elements[0];
var getClipboardText = function(event){
var clipboardData = (event.clipboardData || window.clipboardData);
return clipboardData.getData("text");
}
var setClipboardText = function(event, value){
if (event.clipboardData){
event.clipboardData.setData("text/plain", value);
} else if (window.clipboardData){
window.clipboardData.setData("text", value);
}
}
var addHandler = function(element, type, handler){
if (element.addEventListener){
element.addEventListener(type, handler, false);
} else if (element.attachEvent){
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
}
addHandler(field1, "paste", function(event){
event = event || window.event;
var text = getClipboardText(event);
if (!/^d*$/.test(text)){
if (event.preventDefault){
event.preventDefault();
} else {
event.returnValue = false;
}
}
})
</script>