文檔和元素的幾何形狀和滾動
當瀏覽器在窗口中渲染文檔時,它創建文檔的一個視覺表現層,在那里每個元素有自己的位置和尺寸。
文檔坐標 & 視口坐標
元素的位置是以像素來度量的,向右代表X坐標的增加,向下代表Y坐標的增加。
- 有兩個不同的坐標系:文檔坐標和視口坐標。文檔坐標就是指整個文檔,坐標原點為文檔的左上角;視口坐標則是實際顯示文檔內容的瀏覽器的一部分(不包括菜單、工具條和標簽),坐標原點為顯示部分的左上角。
- 如果文檔比視口要小,或者說它未出現滾動,則文檔的左上角就是視口的左上角,文檔和視口坐標系統是同一個。但是,一般來說,要在兩種坐標系之間進行轉換,必須加上或減去滾動的偏移量。
- 文檔坐標比視口坐標更加基礎,并且在用戶滾動時它們也不會發生變化。不過,在客戶端編程中,使用視口坐標是非常常見的。如,鼠標注冊事件處理程序報告的坐標就是視口坐標。
// 查詢滾動條的偏移量
function getScrollOffset(w) {
// 使用指定的窗口,如果不帶參數則使用當前窗口
w = w || window;
// 除了IE8及更早的版本之外,其他瀏覽器都能用
if(w.pageXOffset != null) return { x: w.pageXOffset, y:w.pageYOffset };
// 對標準模式下的IE(或任何瀏覽器)
var d = w.document;
if(document.compatMode == "CSS1Compat")
return { x: d.documentElement.scrollLeft, y: d.documentElement.scrollTop };
// 對怪異模式下的瀏覽器
return { x: d.body.scrollLeft, y: d.body.scrollTop };
}
查詢元素的尺寸
判定一個元素的尺寸和位置簡單的方法是調用它的getBoundingClientRect()方法。返回一個有left、right、top和bottom屬性的對象。
- 此方法返回的是視口坐標的位置(方法中的"Client"也是間接指代視口)。
- 此返回的坐標包含元素的內邊距和邊框,但不包含元素的外邊距。
- 對于內聯元素(如span,code,b等),可能跨了多行的,返回包含多行的"邊界矩形"。
- 如果想查詢內聯元素每個獨立的矩形,則可以調用getClientRects()方法,返回一個只讀的類數組對象。
- getBoundingClientRect()和getClientRects()所返回的矩形對象都不是實時的。它們只是調用方法時文檔視覺狀態的靜態快照,在用戶改變瀏覽器窗口大小時不會更新它們。
獲取指定點的元素
可以使用elementFromPoint()來獲取指定坐標點的一個元素,坐標點變量為視口坐標。如果指定的坐標點在視口之外,則函數返回null。
窗口滾動
- window對象的scrollTo()方法接受一個文檔坐標,并將它作為視口的左上角。
- window對象的scrollBy()方法和scrollTo()類似,但它的參數是相對的,并在當前滾動條的偏移量上增加的。
- HTMLElement對象的scrollIntoView()可以強制將元素在視口中可見。
元素的其他尺寸屬性
offset相關屬性
- offsetWidth和offsetHeight返回的尺寸包含元素的內邊距和邊框,但不包含外邊距(同getBoundingClientRect())。
- offsetLeft和offsetTop屬性,這些屬性返回的坐標是相對于父元素的(對于文檔內的一級子元素則直接是文檔坐標)。
- offsetParent屬性指代這些元素所相對的父元素。
// 通過offset屬性獲取文檔坐標
function getElementPosition(e) {
var x = 0, y = 0;
while(e != null) {
x += e.offsetLeft;
y += e.offsetTop;
// 獲取所有的父元素
e = e.offsetParent;
}
return { x: x, y: y };
}
client相關屬性
- clientWidth和clientHeight返回的尺寸包含元素的內邊距,但不包含邊框和外邊距。對于內聯元素,返回值總是0。
- clientLeft和clientTop分別返回內邊距的外邊緣和它的邊框的外邊緣之間的水平距離和垂直距離(是距離值,而不是坐標值!)。如果元素有滾動條,并且放置在左側和頂部,則clientLeft和clientTop也會包含滾動條的寬度。對于內聯元素,返回值總是0。
scroll相關屬性
- scrollWidth和scrollHeight返回的尺寸包含內邊距和溢出內容的尺寸,當內容沒有溢出時,同client屬性。
- scrollLeft和scrollTop分別返回水平滾動條和垂直滾動條的偏移量(以像素為單位)。
HTML表單
表單和表單元素的選取
一般來說,用id屬性指定文檔元素比用name屬性更佳,但是name屬性在表單中較為常用。
表單的選取
- name="address"的form表單可以用以下方法來選取:
document.address // 僅當表單有name屬性時可用
document.forms.address // 顯式訪問表單
document.forms[n] // n表示表單的序號
表單元素的選擇
- 如果名"address"的表單的第一個元素的name是"street",則可以通過以下方法來選?。?/li>
document.address.street
document.forms.address.street
document.forms.address[0]
document.forms.address.elements[0] // 使用表單的elements屬性
document.forms.address.elements.street
注意:當有多個元素共享name時,將返回一個類數組對象。
表單和表單元素的屬性
在事件處理程序中,關鍵字this是觸發該事件的文檔元素的一個引用。
表單的屬性
上面已經使用到了elements屬性,其他的屬性還有action、encoding、method、target等。
表單元素的屬性
表單元素的屬性包括type、form、name、value等。其中value值就是當提交表單時發送到web服務器的字符串。
表單和表單元素的事件處理程序
表單的事件處理
- 表單提交前會調用onsubmit程序,可以通過返回false取消提交。
注意:onsubmit只能通過單擊"提交"按鈕來觸發。直接調用表單的submit()方法并不觸發obsubmit事件處理程序。
- 表單在重置之前會調用onreset()程序,可以通過返回false阻止表單元素被重置。
注意:onreset只能通過單擊"重置"按鈕來觸發。直接調用表單的reset()方法并不觸發onreset事件處理程序。
表單元素的事件處理
當用戶與表單交互時它們往往會觸發click或change事件。
一般來說,當按鈕表單激活(甚至通過鍵盤激活而不是鼠標)時會觸發click事件。
在一個文本域中不是每次用戶輸入都會觸發change事件,而僅當用戶改變了元素的值然后將焦點移到其他元素上時才會觸發。表單元素獲得焦點時觸發focus事件,失去焦點時觸發blur事件。獲取焦點的方式有3種:(1)鼠標點擊 (2)tab按鍵 (3)focus()調用
按鈕
以input元素定義的按鈕會將value屬性值以純文本顯示。以button元素定義的按鈕會將元素的一切內容顯示出來。
注意:超級鏈接與按鈕一樣提供了onclick事件處理程序。當onclick事件所觸發的動作可以概念化為"跟隨此鏈接"時就用一個鏈接;否則,使用按鈕。
開關按鈕
- 單選和復選框元素都定義了checked屬性,該屬性是可讀可寫的布爾值。
- 單選和復選框本身不顯示任何文本,value屬性值只改變發送到web服務器的字符串。
- 當用戶單擊單選或復選開關按鈕,單選或復選元素觸發onclick事件。如果由于單擊開關按鈕改變了它的狀態,也會觸發onchange事件。
注意:用戶單擊其他單選按鈕而導致這個單選按鈕狀態的改變,后者不觸發onchange事件。
文本域
-
<text>
標簽定義單行的文本輸入框,<textarea>
定義多行的文本輸入框。 -
<input type="password">
標簽定義用于輸入密碼的文本框。注意使用安全的https進行提交數據。 -
<input type="file">
標簽定義用于上傳文件的輸入框,value屬性是只讀的,防止惡意上傳任意文件。 - 不同的文本輸入元素定義onkeypress、onkeydown和onkeyup事件處理程序。可以直接返回false,防止記錄用戶的按鍵。
選擇框
-
<select>
元素有2種不同的動作方式,可單選和多選,取決于multiple屬性值,默認為單選。 - 針對單選情況,屬性selectedIndex指定了哪個選項被選中;但對于多選的情況,必須遍歷options[]數組的元素,并檢測每個option對象的selected屬性值。
// 在已存在的select元素上添加一個選項
// 創建一個新的選項
var zaire = new Option("Zaire", // text屬性
"zaire", // value屬性
false, // defaultSelected屬性
false); // selected屬性
// 得到select對象
var countries = document.address.country;
countries.options[countries.options.length] = zaire;