文档和元素的几何形状和滚动
当浏览器在窗口中渲染文档时,它创建文档的一个视觉表现层,在那里每个元素有自己的位置和尺寸。
文档坐标 & 视口坐标
元素的位置是以像素来度量的,向右代表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",则可以通过以下方法来选取:
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;