6.1

6.1.1

在研究受事件驱动的程序时,倾向于关注四个机制

  • 因为许多事件都与人们可以看到的用户界面元素(按钮、文本字段、滑动块)相关联,所以事件驱动计算的一个关键要素就是用于定义用户界面元素的机制

  • 由于检测到的事件经常会引用或修改一个脚本内的其他用户界面元素,所以应当提供一种一编程方式访问用户界面元素的机制。

  • 因为用户界面元素要响应事件——包括但不限于单击鼠标、鼠标移动、击键、语音与手势检测、键盘焦点改变、时间流逝、网络数据到达,所以事件驱动的系统提供一种用于指定代码的机制,再出发特定事件时执行此代码。

  • 许多事件都伴有补充信息。例如鼠标事件涉及鼠标坐标、一个或多个鼠标按钮;键盘事件涉及一个特定键,还可能有一个或多个修改键。因此事件驱动的系统提供一种用于读取事件专属信息的机制。


6.2定义用户界面元素

之前曾提到,JavaScript的设计就是要内嵌在托管系统中,比如Web服务器、图像编辑器、字处理器和类似系统。当这些系统的用户界面元素产生某些事件时,会运行特定的JavaScript代码以作响应。尽管JavaScript并没有自己定义这些元素,但它却提供了一种非常好的功能,可以将函数用作对象的属性,与这些用户界面元素完全对应。

例如,在一个Web环境中,这些元素是通过以HTML编写的结构化文档来提供的,这些文档或者由Web服务器通过互联网提供,或者作为.html文件存储在本地计算机上,然后由Web渲染器为我们熟悉的可视形式。没有JavaScript,这些页面就是静态的,也就是说,一旦加载,它们的内容就不能改变。改变显示内容的唯一方法就是单击一个链接,为一个新页面重新启动"链接——渲染"周期。利用JavaScript,web页面获得了触发自我修改的能力,从而可以根据用户与页面内容的互动变为动态的。

6.2.1 Web页面是结构化文档

<!DOCTYPE HTML>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>     
    <body>
        <h1>Temperature Conversion</h1>
        <p>
            <input type="text" id="temperature" />
            <input type="button" id="f_to_c" value="F to C" />
            <input type="button" id="c_to_f" value="C to F" />
        </p>
        <!-- Computation result will go here-->
        <p id="result"></p>
        <script src="img/js/js_test.js"></script>
    </body>
</html>

如上面这段"温度转换器"的Web页面的节点结构。

图片描述

HTML定义了一组可供使用的节点和属性,还有用于构建正确结构的规则。创建HTML文档的通常形式是:编写一系列用标签表示元素的字符,这些标签或者为开始标签、结束标签或者为空标签。
定义HTML语法的全套规则非常复杂,但我们可以由以下规则入门。

  • 文档的开头应当是一个文档类型声明,告诉浏览器希望使用哪种HTML版本,目前一般都是HTML5.

  • Web页面应当仅包含一个html元素,它恰好由两部分组成,其顺序为:head元素后面跟有一个body元素。

  • 头元素中包含文档的相关信息,其中有一些子元素,用于表示页面标题(title)、到其他web资源的链接(link)、样式信息(style)、脚本(script)、一般信息(meta)及其他。强烈建议提供一个meta元素,作为head的第一个子元素,告诉浏览器,你的文档存储时采用了哪种字符编码。

  • 主体中包含文本元素和块元素。文本可以用行内元素标记,这些元素可用于以下目的:表示强调(em)、着重强调(strong)、匿名(abbrev)、引用(q)、引文(cite)、上标(sup)、下标(sub)、到其他文档的链接(a)、一般内置跨区(span)等等。

  • 有几个用于表示多媒体内容的元素,其行为方式也与行内元素相同:img、audio、video、object、embed。audio和video是HTML5新增元素;object和embed用于浏览器插件的百宝囊元素。

  • 一些元素设计上需要子组件:有序、无序列表li;定义列表dt和dd;表格表头thead、主体tbody、页脚tfoot、每一个都有行tr,单元格可以是标题th,也可以是正常表格数据td。

  • 经典的用户界面元素:input(button、text)、select、textarea、单选radio、复选checkbox等等。
    HTML5引入了outpt、keygen、progress、meter、command,还有其他一些input类型,如number、date、email。

  • 一些元素既可以出现在标题中,也可以出现在主体中,一些元素既可以充当块元素,也可以充当行内元素。


我们将注意力放在程序设计上,特别是放在事件驱动的程序设计上,所以重点还在JavaScript。


6.3 以编程方式访问用户界面元素

下面将说明JavaScript如何使用一种称为文档对象模型(Document Object Model,DOM)的“桥接技术”来读写这一用户界面,并进行处理。

6.3.1 document对象

document就是一种宿主对象,可以在任何时间、任何位置供Web浏览器中运行的任何JavaScript代码使用。

        alert(document)

至少,它向你证明了:JavaScript不用费什么力气就能看到document,只需用名字调用它即可。现在再简单看看document的一些属性。

        var i = 0;
        for (var prototy in document) {
            console.log(prototy);
            i++;
            if (i>4) {
                break;
            }
        };

[Web浏览器] "vlinkColor" /javascript/test.html (11)
[Web浏览器] "linkColor" /javascript/test.html (11)
[Web浏览器] "alinkColor" /javascript/test.html (11)
[Web浏览器] "fgColor" /javascript/test.html (11)
[Web浏览器] "bgColor" /javascript/test.html (11)
看到了控制台内的输出,每个都有一个属性名,比如bgColor、width或getElementById。这里无法给出一个确定不变的列表,因为不同浏览器可能会按不同的顺序列出document的属性,甚至包含一些其他浏览器不被支持的属性。
i计数器将console.log的属性名称限制为仅有五个,有一种更方便的方式查看document的所有属性名称。

        for (var property in document) {
            document.write("<div>"+property+"</div>");
        }

注意上面代码如何改变了web窗口中的实际内容。这是document的关键属性之一,它被直接“连线”到一个web页面。document中的write函数将给定字符串直接发送个页面;我们用这个函数逐字写出其内容。如果在处理页面的同时调用write,它的行为更像是一个打字员,向当前页面注入HTML,但是如果在加载页面之后在调用write,将会创建一个新的空白web页面,并向其添加文本。
不难想象一个函数可以怎样修改web浏览器的内容。毕竟是一个函数,可以轻松的包含代码,用于修改显示内容。

        var footer = document.getElementById("footer");
        footer.innerHTML = "<h3>document properties:</h3>";
        var properties = [];
        for (var property in document) {
            properties.push(property+" ");
        }
        footer.innerHTML = "<p>"+properties.join("<br/>")+"</p>"

这个脚本中,document.getElementById("footer")返回运行期页面的一些元素,但这并不是什么非同寻常的事情。注意,其中只有一次赋值操作,就是为这个对象的innerHTML属性指定了一个字符串,而这一赋值操作改变了web页面,其效果马上就显示了出来。这样就使JavaScript与相关文档之间的互动显得非常自然,富有凝聚力:设定一个值,马上就能看到结果。


6.3.4 操控用户界面空间

Web页面决定着JavaScript的生存周期,当Web页面被关闭、刷新、替换,由下一页面上的DOM脚本/变量接管时,对象、变量、函数和所有其他一切都将被抛弃。这就是"JavaScript"的生命轮回。

6.3.6 遍历DOM

document宿主对象再做一点深入剖析。我们已经看到,document是JavaScript代码借以修改或更新Web页面的渠道这个宿主对象表示的就是文档树顶部的文档节点,事实上,这些树中的所有节点都是用JavaScript宿主对象表示的;和所有对象一样,它们拥有属性。DOM对象,包括document自身,具有以下一个或多个属性。

  • nodeType:1~12范围内的一个整数,用来描述节点的类型。例如:1表示元素,3表示文本,8表示注释,9表示文档节点本身

  • nodeValue:节点的内容,如文本节点中的文本。

  • childNodes:一个与数组类似的对象,其中childNodes[0]引用了该对象的第一个子节点,childNodes[1]引用第二个,以此类推。每个子节点又可以拥有自己的childNodes属性。


有一些DOM对象就是元素(nodeType===1),它们有两个很有用的属性。

  • tagName:元素的名字

  • attributes:一个类似于数组的对象,其中包含"名称-值对"形式的属性。


Queen
139 声望20 粉丝