概述

目录

元素与变量名

id属性

由于历史原因,HTML元素的id属性的名字,会自动成为全局变量,指向该HTML元素。

// HTML元素为
                // <div id="example"></div>

                example // [object HTMLDivElement]
            

上面代码中,有一个id属性等于examplediv元素,结果就自动生成了全局变量example,指向这个div元素。

如果已有同名全局变量,则id元素不会自动生成全局变量。

<script>
                var example = 1;
                </script>

                <div id="example"></div>

                <script>
                console.log(example) // 1
                </script>
            

上面代码中,已有全局变量example,这时id属性就不会自动变成全局变量。另一情况是,DOM生成以后,再对全局变量example赋值,这时也会覆盖example原来的值。

由于这种原因,默认的全局变量名(比如,historylocationnav01igator等),最好不要设为id属性的名字。

另外,由于原则上,网页之中不应该有同名id属性的HTML元素,所以,这种机制产生的全局变量不会重名。

name属性

由于历史原因,以下HTML元素的name属性,也会成为全局变量。

  • <applet>
  • <area>
  • <embed>
  • <form>
  • <frame>
  • <frameset>
  • <iframe>
  • <img>
  • <object>
// HTML代码为
                // <form name="myForm" />

                myForm // [object HTMLFormElement]
            

上面代码中,form元素的name属性名myForm,自动成为全局变量myForm

如果name属性同名的HTML元素不止一个,或者某个元素的id属性与另一个元素的name属性同名,这时全局变量会指向一个类似数组的对象。

// HTML代码为
                // <div id="myForm" />
                // <form name="myForm" />

                myForm[0] // [object HTMLDivElement]
                myForm[1] // [object HTMLFormElement]
            

上面代码中,全局变量myForm的第一个成员指向div元素,第二个成员指向form元素。

这些元素的name属性名,也会成为document对象的属性。

// HTML代码为<img name="xx" />
                document.xx === xx // true
            

上面代码中,name属性为xximg元素,自动生成了全局变量xxdocument对象的属性xx

如果有多个name属性相同的元素,那么document对象的该属性指向一个类似数组的对象(NodeList对象的实例)。

这样设计的原意是,通过引用document.elementName就可以获得该元素。但是,由于这些属性是自动生成的,既不规范,也不利于除错,所以建议不要使用它们。

另外,如果iframe元素有name属性或id属性,那么生成的全局变量,不是指向iframe元素节点,而是指向这个iframe代表的子页面window对象。

除了自动成为windowdocument的属性,带有idname属性的HTML元素,还会自动成为集合对象的属性。举例来说,如果有一个表单元素<form>

<form name="myform">
            

它会自动成为集合对象document.forms的属性。

document.forms.myforms;
            

Form 元素(表单)

表单主要用于收集用户的输入,送到服务器或者在前端处理。

选中表单元素

如果<form>元素带有name或者id属性,这个元素节点会自动成为windowdocument的属性,并且可以从document.forms上取到。<form name="myForm">节点用下面几种方法可以拿到。

window.myForm
    document.myForm
    document.forms.myForm
    document.forms[n]

document.forms返回一个类似数组的对象(HTMLCollection的实例),包含了当前页面中所有表单(<form>元素)。HTMLCollection的实例都可以使用某个节点的idname属性,取到该节点。

表单对象本身也是一个HTMLCollection对象的实例,它里面的各个子节点也可以用id属性、name属性或者索引值取到。举例来说,myForm表单的第一个子节点是<input type="text" name="address">,它可以用下面的方法取到。

document.forms.myForm[0]
                document.forms.myForm.address
                document.myForm.address // 只对name属性生效,对id属性不生效
            

表单节点都有一个elements属性,包含了当前表单的所有子元素,所以也可以用下面的方法取到address子节点。

document.forms.myForm.elements[0]
                document.forms.myForm.elements.address
            

表单之中,会有多个元素共用同一个name属性的情况。

<form name="myForm">
                <label><input type="radio" name="method" value="1">1</label>
                <label><input type="radio" name="method" value="2">2</label>
                <label><input type="radio" name="method" value="3">3</label>
                </form>
            

上面代码中,三个单选框元素共用同一个name属性,这时如果使用这个name属性去引用子节点,返回的将是一个类似数组的对象。

document.forms.myForm.elements.method.length // 3
            

如果想知道,用户到底选中了哪一个子节点,就必须遍历所有的同名节点。

var methods = document.forms.myForm.elements.method;
                var result;

                for (var i = 0; i < methods.length; i++) {
                if (methods[i].checked) value = methods[i].value;
                }
            

Form 对象

<form>元素对应的DOM节点是一个Form对象。这个对象除了上一小节提到的elements属性,还有以下属性,分别对应元素标签中的同名属性。

  • action
  • encoding
  • method
  • target

Form对象还有两个属性,可以指定事件的回调函数。

  • onsubmit:提交表单前调用,只要返回false,就会取消提交。可以在这个函数里面,校验用户的输入。该函数只会在用户提交表单时调用,脚本调用submit()方法是不会触发这个函数的。
  • onreset:重置表单前调用,只要返回false,就会取消表单重置。该函数只能由真实的reset按钮触发,脚本调用reset()方法并不会触发这个函数。
<form onreset="return confirm('你要重置表单吗?')">
                <!-- ... -->
                <button type="reset">重置</button>
</form>

Form对象的方法主要是下面两个。

  • submit():将表单数据提交到服务器
  • reset():重置表单数据

表单控件对象

表单包含了各种控件,每个控件都是一个对象。它们都包含了以下四个属性。

  • type:表示控件的类型,对于<input>元素、<button>元素等于这些标签的type属性,对于其他控件,<select>select-one<select multiple>select-multiple<textarea>textarea。该属性只读。
  • form:指向包含该控件的表单对象,如果该控件不包含在表单之中,则返回null。该属性只读。
  • name:返回控件标签的name属性。该属性只读。
  • value:返回或设置该控件的值,这个值会被表单提交到服务器。该属性可读写。 才会 form属性有一个特别的应用,就是在控件的事件回调函数里面,this指向事件所在的控件对象,所以this.form就指向控件所在的表单,this.form.x就指向其他控件元素,里面的x就是该控件的name属性或id属性的值。

表单控件之中,只要是按钮,都有onclick属性,用来指定用户点击按钮时的回调函数;其他的控件一般都有onchange属性,控件值发生变化,并且该控件失去焦点时调用。单选框(Radio控件)和多选框(Checkbox控件)可以同时设置onchangeonclick属性。

表单控件还有以下两个事件。

  • focus:得到焦点时触发
  • blur:失去焦点时触发

Select元素

<select>元素用来生成下拉列表。默认情况下,浏览器只显示一条选项,其他选项需要点击下拉按钮才会显示。size选项如果大于1,那么浏览器就会默认显示多个选项。

<select size="3">
            

上面代码指定默认显示三个选项,更多的选项需要点击下拉按钮才会显示。

<select>元素默认只能选中一个选项,如果想选中多个选项,必须指定multiple属性。

<select multiple>
            

用户选中或者取消一个下拉选项时,会触发Select对象的change事件,从而自动执行onchange监听函数。

<select>元素有一个options属性,返回一个类似数组的对象,包含了所有的<option>元素。

// HTML 代码为
                // <select id="example">
                //   <option>1</option>
                //   <option>2</option>
                //   <option>3</option>
                // </select>

                var element = document.querySelector('#example');
                element.options.length
                // 3
            

上面代码中,<select>元素的options属性包含了三个<option>元素。

options属性可读写,可以通过设置options.length,控制向用户显示的下拉选项的值。将options.length设为0,可以不再显示任何下拉属性。将options里面某个位置的Option对象设为null,将等于移除这个选项,后面的Option对象会自动递补这个位置。

Select对象的selectedIndex属性,返回用户选中的第一个下拉选项的位置(从0开始)。如果返回-1,则表示用户没有选中任何选项。该属性可读写。对于单选的下拉列表,这个属性就可以得知用户的选择;对于多选的下拉列表,这个属性还不够,必须逐个轮询options属性,判断每个Option对象的selected属性是否为true

Option元素

<option>元素用于在下拉列表(<select>)中生成下拉选项。每个下拉选项就是一个Option对象,它有以下属性。

  • selected:返回一个布尔值,表示用户是否选中该选项。
  • text:返回该下拉选项的显示的文本。该属性可读写,可用来显示向用户显示的文本。
  • value:返回该下拉选项的值,即向服务器发送的那个值。该属性可读写。
  • defaultSelected:返回一个布尔值,表示这个下拉选项是否默认选中。

浏览器提供Option构造函数,用来生成下拉列表的选项对象。利用这个函数,可以用脚本生成下拉选项,然后放入Select.options对象里面,从而自动生成下拉列表。

var item = new Option(
                'Hello World',  // 显示的文本,即 text 属性
                'myValue',  // 向服务器发送的值,即 value 属性
                false,    // 是否为默认选项,即 defaultSelected 属性
                false   // 是否已经选中,即 selected 属性
                );

                // 获取 Selector 对象
                var mySelector = document.forms.myForm.mySelector;
                mySelector.options[mySelector.options.length] = item;
            

上面代码在下拉列表的末尾添加了一个选项。从中可以看到,Option构造函数可以接受四个选项,对应<Option>对象的四个属性。

注意,用脚本插入下拉选项完全可以用标准的DOM操作方法实现,比如Document.create Element()Node.insertBefore()Node.removeChild()等等。

image元素

alt属性,src属性

alt属性返回image元素的HTML标签的alt属性值,src属性返回image元素的HTML标签的src属性值。

// 方法一:HTML5构造函数Image
                var img1 = new Image();
                img1.src = 'image1.png';
                img1.alt = 'alt';
                document.body.appendChild(img1);

                // 方法二:DOM HTMLImageElement
                var img2 = document.createElement('img');
                img2.src = 'image2.jpg';
                img2.alt = 'alt text';
                document.body.appendChild(img2);

                document.images[0].src
                // image1.png
            

complete属性

complete属性返回一个布尔值,true表示当前图像属于浏览器支持的图形类型,并且加载完成,解码过程没有出错,否则就返回false。

height属性,width属性

这两个属性返回image元素被浏览器渲染后的高度和宽度。

naturalWidth属性,naturalHeight属性

这两个属性只读,表示image对象真实的宽度和高度。


                myImage.addEventListener('onload', function() {
                console.log('My width is: ', this.naturalWidth);
                console.log('My height is: ', this.naturalHeight);
                });

            

table元素

表格有一些特殊的DOM操作方法。

  • insertRow():在指定位置插入一个新行(tr)。
  • deleteRow():在指定位置删除一行(tr)。
  • insertCell():在指定位置插入一个单元格(td)。
  • deleteCell():在指定位置删除一个单元格(td)。
  • createCaption():插入标题。
  • deleteCaption():删除标题。
  • createTHead():插入表头。
  • deleteTHead():删除表头。

下面是使用JavaScript生成表格的一个例子。

var table = document.createElement('table');
                var tbody = document.createElement('tbody');
                table.appendChild(tbody);

                for (var i = 0; i <= 9; i++) {
                var rowcount = i + 1;
                tbody.insertRow(i);
                tbody.rows[i].insertCell(0);
                tbody.rows[i].insertCell(1);
                tbody.rows[i].insertCell(2);
                tbody.rows[i].cells[0].appendChild(document.createTextNode('Row ' + rowcount + ', Cell 1'));
                tbody.rows[i].cells[1].appendChild(document.createTextNode('Row ' + rowcount + ', Cell 2'));
                tbody.rows[i].cells[2].appendChild(document.createTextNode('Row ' + rowcount + ', Cell 3'));
                }

                table.createCaption();
                table.caption.appendChild(document.createTextNode('A DOM-Generated Table'));

                document.body.appendChild(table);
            

这些代码相当易读,其中需要注意的就是insertRowinsertCell方法,接受一个表示位置的参数(从0开始的整数)。

table元素有以下属性:

  • caption:标题。
  • tHead:表头。
  • tFoot:表尾。
  • rows:行元素对象,该属性只读。
  • rows.cells:每一行的单元格对象,该属性只读。
  • tBodies:表体,该属性只读。

audio元素,video元素

audio元素和video元素加载音频和视频时,以下事件按次序发生。

  • loadstart:开始加载音频和视频。
  • durationchange:音频和视频的duration属性(时长)发生变化时触发,即已经知道媒体文件的长度。如果没有指定音频和视频文件,duration属性等于NaN。如果播放流媒体文件,没有明确的结束时间,duration属性等于Inf(Infinity)。
  • loadedmetadata:媒体文件的元数据加载完毕时触发,元数据包括duration(时长)、dimensions(大小,视频独有)和文字轨。
  • loadeddata:媒体文件的第一帧加载完毕时触发,此时整个文件还没有加载完。
  • progress:浏览器正在下载媒体文件,周期性触发。下载信息保存在元素的buffered属性中。
  • canplay:浏览器准备好播放,即使只有几帧,readyState属性变为CAN_PLAY。
  • canplaythrough:浏览器认为可以不缓冲(buffering)播放时触发,即当前下载速度保持不低于播放速度,readyState属性变为CAN_PLAY_THROUGH。

除了上面这些事件,audio元素和video元素还支持以下事件。

事件 触发条件
abort 播放中断
emptied 媒体文件加载后又被清空,比如加载后又调用load方法重新加载。
ended 播放结束
error 发生错误。该元素的error属性包含更多信息。
pause 播放暂停
play 暂停后重新开始播放
playing 开始播放,包括第一次播放、暂停后播放、结束后重新播放。
ratechange 播放速率改变
seeked 搜索操作结束
seeking 搜索操作开始
stalled 浏览器开始尝试读取媒体文件,但是没有如预期那样获取数据
suspend 加载文件停止,有可能是播放结束,也有可能是其他原因的暂停
timeupdate 网页元素的currentTime属性改变时触发。
volumechange 音量改变时触发(包括静音)。
waiting 由于另一个操作(比如搜索)还没有结束,导致当前操作(比如播放)不得不等待。

tabindex属性

tabindex属性用来指定,当前HTML元素节点是否被tab键遍历,以及遍历的优先级。

var b1 = document.getElementById("button1");

                b1.tabIndex = 1;
            

如果tabindex = -1,tab键跳过当前元素。

如果tabindex = 0,表示tab键将遍历当前元素。如果一个元素没有设置tabindex,默认值就是0。

如果tabindex > 0,表示tab键优先遍历。值越大,就表示优先级越大。

留言

comments powered by Disqus
Top