《JavaScript 权威指南》读书笔记 12 - Web 浏览器中的 JavaScript

客户端的 JavaScript

Window 对象是所有客户端 JavaScript 特性和 API 的主要接入点。它表示 Web 浏览器的一个窗口或者窗体,并且可以用标识符 window 来引用它。Window 对象定义了一些属性,比如:

// 页面跳转
window.location = 'http://www.oreilly.com/';
// 页面圣诞框
alert('Hello World')
setTimeout(function () { alert('Hello later World') }, 1000)

window 对象也是全局对象。可以省略「window.」来调用上面的方法。这意味着 windows 对象牌作用域链的顶部,它的属性和方法实际上是全局变量和全局函数。window 对象有一个引用自己的属性,叫做 window。如果需要引用窗口对象本身可以用这个属性,但是如果只想要引用全局窗口对象的属性,通常并不需要用 window

windows 对象还定义了很多其他重要的属性、方法和构造函数。其中最重要的一个属性是 document,它引用 Document 对象,后者表示显示在窗口中的文档。document 对象有一些重要方法,比如 getElementById() 获取一个 DOM 元素,它返回一个 Element 对象也有其他重要属性和方法,比如,给元素绑定点击事件 onclick

在 HTML 里嵌入 JavaScript

在 HTML 里嵌入 客户端 JavaScript 有 4 种方法:

  • 内联,放置在 <script> 和 </script> 标签之间
  • 外链,放置在由 script 标签的 src 属性指定的外部文件中
  • 放置在 HTML 事件处理程序中,该事件处理程序由 onclick 或 on[eventType] 这样的 HTML 属性指定
  • 放在一个 URL 里,这个 URL 使用特殊的「javascript:」协议
<!--html 中的事件处理程序-->
<input type="checkbox" onchange="any_javascript_statement" />
<!--url 中的javascript-->
<a href="javascript: new Date().toLocaleTimeString();">What time is it?</a>

使用外链 src 文件方式有一些优点:

  • 可以把 JavaScript 代码从 HTML 文件中删除,这有助于保持内容和行为的分离,从而简化 HTML 文件
  • 如果多个 Web 页面共用相同的 JavaScript 代码,用 src 属性可以让你只管理一份代码,而不用在代码变更时每个页面都更新
  • 如果一个 JavaScript 文件由多个页面共享,就只需要下载一次,以后的页面只要引用过就可以使用缓存检索它
  • src 属性值可以是任意的 URL,因此来自一个 Web 服务器的 JavaScript 程序或 Web 页面可以使用由 另外一个 Web 服务器输出的代码,很多广告依赖与些
  • 从其它网站载入脚本的能力,可以让我们更好地利用缓存,使用 CDN

脚本的类型

script 标签默认的类型「type」是「text/javascript」,如果要使用不标准的脚本语言,如 Microsoft 的 VBScript(只有 IE 支持),就必须用 type 属性指定脚本的 MIME 类型:

<script type="text/vbscript">
// 这里是 VBScript 代码
</script>

另外很多老的浏览器还支持 language 属性,作用和 type 一样,不过已经废弃了,不应该再使用了

当 Web 浏览器遇到 <script> 元素,并且这个元素包含其值不之前能点浏览器识别的 type 属性时,它会解析这个元素但不会尝试显示或执行它的内容。这意味着可以使用 <script> 来嵌入任意的文件数据到文档里,比如 handlebars 模板引擎,通常把模板放在自定义 type 的 script 标签中:

<script id="entry-template" type="text/x-handlebars-template">
    <div class="entry">
        <h1>{{title}}</h1>
        <div class="body">
            {{body}}
        </div>
    </div>
</script>

同步、异步和延迟的脚本

JavaScript 第一次添加到 Web 浏览器时,还没有 API 可以用来遍历和操作文档的结构和内容。当文档还在载入时,JavaScript 影响文档内容的唯一方法是使用 document.write() 方法

<h1>Table of Factorials</h1>
<script>
function factorial(n) {
    if ( n <= 1 ) return n;
    else return n * factorial(n - 1);
}
document.write('<table>');
document.write('<tr><th>n</th><th>n!</th></tr>');
for (var i = 1; i <= 10; i++) {
    document.write('<tr><td>'+ i +'</td><td>'+ factorial(i) +'</td></tr>')
}
document.write('</table>');
document.write('Generated ad ' + new Date());
</script>

当脚本把文本传递给 document.write() 时,这个文本被添加到文档输入流中,HTML 解析器会在当前位置创建一个文本节点,将文本插入这个文本节点后面。我们并不推荐使用 document.write(),但在某些场景下它有很重要的用途。当 HTML 解析器遇到 script 元素时,它默认 必须先执行脚本,然后恢复文档的解析和渲染。这对于内联脚本没什么问题,但如果脚本源代码是一个由 src 属性指定的外部文件,这意味着脚本后面的文档部分在下载和执行脚本之间,都不会出现在浏览器中

脚本的执行只在默认情况下是同步和阻塞的。script 标签可以有 defer 和 async 属性,这可以改变脚本的执行方式。HTML 5 说这些属性只在和 src 属性联合使用时才有效,但有些浏览器还支持延迟的内联脚本

<script src="a.js" defer></script>
<script src="b.js" async></script>

defer 和 async 属性都在告诉浏览器链接进来的脚本不会使用 document.write(),也不会生成文档内容,因此不蜂鸣器可以在下载脚本时继续解析和渲染文档,defer 属性使得浏览器延迟脚本的执行,直到文档的载入和解析完成,并可以操作。async 属性使得浏览器可以尽快地挂靠脚本,而不用在下载脚本时阻塞文档解析。如果 script 标签同时有两个属性,同时支持两者的浏览器会 遵从 async 属性并忽略 defer 属性

注意,延迟的脚本会按它们在文档里的 出现顺序执行。而异步脚本在它们载入后执行,这意味着它们可能会 无序执行

事件驱动的 JavaScript

上面的打印斐波那契数列程序在页面载入时开始挂靠,生成一些输出,这种程序今天已经不沉凶了。通常我们使用注册事件处理程序函数来写程序。之后在注册的事件发生时 异步调用这些函数。

事件都有名字,比如 click, change, load, mouseover, keypress, readystatechange 等,如果想要程序响应一个事件,就需要注册一个事件处理函数

事件处理程序的属性名字一般都以「on」开始,后面跟着事件的名字。大部分浏览器中的事件会把一个对象传递给事件处理程序作为参数,那个对象的属性提供了事件的详细信息。比如,传递给点击事件的对象,会有一个属性说明鼠标的哪个按钮被点击了。(在 IE 里,这些事件信息被存储在全局 event 对象里,而不是传给处理程序的函数)

有些事件的目标是文档元素,它们会经常往上传递事件给文档树。这个过程叫做「冒泡

关于事件传播顺序可以参考 ppk 的 这篇文章

客户端 JavaScript 线程模型

JavaScript 语言核心并不包含任何线程机制,并且客户端 JavaScript 传统上也没有定义任何线程机制。HTML 5 定义了一种作为后台线程的「WebWorker」,但是客户端 JavaScript 还像严格的单线程一样工作。甚至当可能并发执行的时候,客户端 JavaScript 也不会知道是否真的的有并行逻辑执行

单线程执行是

免责声明:

本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。

本站信息来自网络收集整理,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。

如果您喜欢该程序和内容,请支持正版,购买注册,得到更好的正版服务。我们非常重视版权问题,如有侵权请邮件与我们联系处理。敬请谅解!

发表评论:

抱歉,检测到您未登录,需要评论,请先