客户端JavaScript
web浏览器中的JavaScript
一. 客户端JavaScript
1. document
web 浏览器中呈现静态信息的页面叫做文档(由于加入了JavaScript,静态页面的信息看上去会动来动去,但信息本身是静态的)
2. window
Window
对象是所有客户端JavaScript
特性和API
的主要接入点,是一个全局对象,处于作用域链的顶部。引用自身:
window
Window
对象的属性(全局变量):location
属性(指代Location
对象,Location
对象指定当前显示在窗口中的URL
)、document
(引用Document
对象,Document
对象表示窗口中的文档)
window.location = "http://www.oreilly.com/";
//设置location属性,从而跳转到新的web页面
-
Window
对象的方法(全局函数):alert(),setTimeout()
等
4. 事件处理程序
- 事件处理程序的属性名是以
on
开始的。 - 为事件处理程序绑定一个函数,函数会在某个事件发生时以异步的方式调用。
-
Window
对象的onload
处理程序是最重要的事件处理程序之一。当显示在窗口中的文档内容稳定并可以操作时会触发它。
5. JavaScript的角色
- 动态
HTML
或DHTML
:JavaScript
程序可以通过Document
对象和它包含的Element
对象遍历和管理文档的内容。它可以通过操纵CSS
样式和类,修改文档内容的呈现。并且可以通过注册适当的时间处理程序来定义文档元素的行为。内容、呈现和行为的组合,叫做动态HTML
或DHTML
。 -
Web
文档里的JavaScript
:设计良好的文档需要在禁用JavaScript
后还能工作。JavaScript
用于增强用户的浏览体验,使信息的获取和传递更加容易。如可通过以下方式: - 创建动画和其他视觉效果,巧妙地引导和帮助用户进行页面导航;
- 对表格的列进行分组,让用户更容易找到所需要的;
- 隐藏某些内容,当用户“深入”到内容时,再逐渐展示详细信息。
-
Web
应用里的JavaScript
:JavaScript
访问浏览器提供的高级服务(比如网络、图像和数据存储),例如常见的XMLHttpRequest
对象。
二. 在 HTML 里嵌入 JavaScript
1. 内联,放置在 <script> 和 </script> 之间;
2. 放置在由 <script> 标签的 src 属性指定的外部文件中;(最好)
- 可以把大块
JavaScript
代码从HTML
文件中删除,这有助于保持内容和行为的分离,从而简化HTML
文件。
- 如果多个
web
页面共用相同的JavaScript
代码,用src
属性可以让你只管理一份代码,而不用在代码改变时编辑每个HTML
文件。 - 如果一个
JavaScript
代码文件由多个页面共享,就只需要下载它一次,通过使用它的第一个页面,随后的页面可以从浏览器缓存检索它。 - 由于
src
属性的值可以是任意的URL
,因此来自一个 web 服务器的JavaScript
程序或 web 页面可以使用由另一个 web 服务器输出的代码。
3. 放置在 HTML 事件处理程序中,该事件处理程序由 onclick 或 onmouseover 这样的 HTML 属性值指定。
4. 放置一个 URL 里,这个 URL 使用特殊的 “javascript:” 协议。
三. JavaScript 程序的执行
1. JavaScript 程序执行的两个阶段
第一个阶段,载入文档内容,并执行 <script>
元素里的代码(包括内联脚本和外部脚本)。脚本通常会按照它们在文档里出现的顺序执行。所有脚本里的 JavaScript
代码都是从上往下,按照它在条件、循环以及其他控制语句中的出现顺序执行的。
文档载入完成,并且所有脚本执行完成后, JavaScript
执行进入第二阶段。这个阶段是异步的,而且是由事件驱动的。在事件驱动阶段, web 浏览器调用事件处理程序函数来响应异步发生的事件,调用事件处理程序通常是响应用户输入,还可以由网络活动、运行时间或者 JavaScript
代码中的错误来触发。
JavaScript 是单线程执行的,脚本和事件处理程序在同一个时间只能执行一个,没有并发性,这保持了 JavaScript 编程的简单性。单线程执行时为了让编程更加简单,编写代码时可以确保两个事件处理程序不会同一时刻运行,操作文档内容时也不必担心会有其他线程试图同时修改文档。
单线程执行意味着浏览器必须在脚本和事件句处理程序执行的时候停止响应用户输入。
2. 同步、异步和延迟的脚本
当HTML解析器遇到 <script>
元素时,它默认必须先执行脚本,然后再恢复文档的解析和渲染。这对于内联脚本没什么问题,但是如果脚本源代码时一个由 src
属性指定的外部文件,这意味着脚本后面的文档部分在下载和执行脚本之前,都不会出现在浏览器中。
脚本的执行只是在默认的情况下是同步和阻塞的。
<script>
标签可以有 defer
和 async
属性,这可以改变脚本的执行方式。浏览器可以在加载脚本时继续解析和渲染文档。
defer
属性使得浏览器延迟脚本的执行,直到文档的载入和解析完成,并可以操作。(先载入文档,再执行脚本)
aync
属性使得浏览器可以尽快地执行脚本,而不用在下载脚本时阻塞文档解析。(同时执行脚本和解析文档)
如果 <script>
标签同时有两个属性,同时支持两者的浏览器会遵从 async
属性并忽略 defer
属性。
延迟的脚本会按它们在文档里的出现顺序执行,而异步脚本在它们载入后执行,这意味着它们可能会无序执行。
3. 事件驱动的 JavaScript
- 事件的名字:
click
,change
等指示发生的事件的通用类型。 - 事件的目标:是一个对象,并且事件就是在它上面发生的。
- 如果想要程序响应一个事件,写一个函数,叫做“事件处理程序”“事件监听器”或“回调”。然后注册这个函数,这样他就会在事件发生时调用它。
- 注册事件处理程序最简单的方法是把
JavaScript
函数赋值给目标对象的属性。
function handleResponse() {...}
request.onreadystatechange = handleResponse;
- 事件处理程序的属性的名字是以
on
开始,后面跟着事件的名字。还要注意在上面的任何代码里<strong>没有函数调用</strong>:只是把函数本身赋值给这些属性。浏览器会在事件发生时执行调用。 - 为一个事件注册多个事件处理程序函数,大部分可以用
addEventListener()
方法,允许注册多个监听器。
ie9
之前用attachEvent()
方法 - 传递给
setTimeout()
的函数和真实事件处理程序的注册不同,他们通常叫做“回调逻辑”而不是“处理程序”,但他们也是异步的。
4. 客户端 JavaScript 时间线
web 浏览器创建
Document
对象,并且开始解析web
页面,解析HTML
元素和它们的文本内容后添加Element
对象和Text
节点到文档中。在这个阶段document.readyState
属性的值是loading
当
HTML
解析器遇到没有async
和defer
属性的<script>
元素时,它把这些元素添加到文档中,然后执行行内或外部脚本。这些脚本会同步执行,并且在脚本下载和执行时解析器会暂停。这样脚本就可以用document.write()
来把文本插入到输入流中。解析器恢复时这些文本会成为文档的一部分。同步脚本经常简单定义函数和注册后面使用的注册事件处理程序,但它们可以遍历和操作文档树,因为在它们执行时已经存在了。这样,同步脚本可以看到它自己的<script>
元素和它们之前的文档内容。当解析器遇到设置了
async
属性的<script>
元素时,它开始下载脚本文本,并继续解析文档。脚本会在它载入完成后尽快执行,但是解析器没有停下来等它下载。异步脚本禁止使用document.write()
方法。它们可以看到自己的<script>
元素和它之前的所有文档元素,并且可能或者干脆不可能访问其他的文档内容。当文档完成解析,
document.readystate
属性变成interactive
。所有有
defer
属性的脚本,会按它们在文档里的出现顺序执行。异步脚本可能也会在在这个时间执行。延迟脚本能访问完整的文档树,禁止使用document.write()
方法。浏览器在
Document
对象上触发DOMContentLoaded
事件。这标志着程序执行从同步脚本执行阶段转换到了异步事件驱动阶段。但要注意,这时可能还有异步脚本没有执行完成。这时,文档已经完全解析完成,但是浏览器可能还在等待其他内容载入,如图片。当所有这些内容完成载入时,并且所有异步脚本完成载入和执行,
document.readyState
属性改变为complete
,web 浏览器触发Window
对象上的load
事件。从此刻起,会调用异步事件,以异步响应用户输入事件、网络事件、计时器过期等。
四. 兼容性和互用性
- 客户端
JavaScript
兼容性和交互性的问题可以归纳为: - 演化:不同的浏览器、新特性
- 未实现:有些现代浏览器实现的功能在老旧浏览器中没实现。
同样实现一个功能在不同浏览器中有很大差别。 - bug:每个浏览器都有
bug
,并且没有按照规范准确地实现所有客户端的JavaScript API
。 - 处理不兼容问题其中一种最简单的方法是使用类库。
- 功能测试:
if (element.addEventListener) {
element.addEventListener("keydown",handler,false);
element.addEventListener("keypress",handler,false);
}
else if (element.attachEvent) {
element.attachEvent("onkeydown",handler);
element.attachEvent("onkeypress",handler);
}
else {
element.onkeydown = element.onkeypress = handler;
}
- 浏览器测试:确定当前浏览器的厂商和版本的代码通常叫做浏览器嗅探器或者客户端嗅探器。
- IE里的条件注释
- html里的条件注释
<!--[if IE6]>
this content is actually inside an html comment.
it will only be displayed in IE6
<![endif]-->
<!--[if lte IE7]>
displayed by IE5,6 and 7 and earlier
<![endif]-->
<!--[if !IE]><-->
IE will not display id
<!--><![endif]-->
- javascript 里的条件注释:
/*@cc_on
@if (@_jscript)
alert("In IE");
@end
@*/
五. 可访问性
- 如果你设计的站点过于依赖
JavaScript
来呈现数据的话,可能会把读屏软件的用户拒之门外,因为一些读屏软件只能在禁用JavaScript
时才会工作得更好。 -
JavaScript
的角色应该是增加信息的表现力,而不是负责信息的呈现。 -
JavaScript
可访问性的一条重要原则是,设计的代码即使在禁用JavaScript
解释器的浏览器中也能正常使用。
六. 安全性
浏览器针对恶意代码的第一条防线就是它们不支持某些功能:
客户端
JavaScript
没有权限来写入或删除客户计算机上的任意文件或列出任意目录。客户端
JavaScript
没有任何通用的网络能力。浏览器针对而已代码的第二条防线是在自己支持的某些功能上施加限制,如:
限制打开新窗口的功能。
不允许未经用户允许关闭用户打开的窗口。
HTML FileUpload
的value
属性是只读的。脚本不能读取从不同服务器载入的文档的内容,除非这个就是包含该脚本的文档。一个脚本不能再来自不同服务器的文档上注册事件监听器。
同源策略:是对
JavaScript
代码能够操作哪些web
内容的一条完整的安全限制。跨站脚本(XSS),用来表示一类安全问题,也就是攻击者向目标
web
站点注入html
标签或者脚本。
防止XSS攻击的方式是,在使用任何不可信的数据来动态的创建文档内容之前,从中移除html
标签。拒绝服务攻击:如果访问了启用
JavaScript
功能的一个恶意web
站点,这个站点可以使用一个alert()
对话框的无限循环占用浏览器,或者用一个无限循环或没有意义的计算来占用CPU。
————————————————分割线—————————————————
END:Answer
Window对象是全局对象,它有属性和方法,alert()方法是它的一个方法,是一个全局函数,可以直接使用。
DOM: document object model 文档对象模型
BOM: browser object model 浏览器对象模型
BOM的最根本对象是window,是对浏览器窗口的操作。
DOM的最根本对象是document,是对页面文档的操作。
BOM包含DOM。
DOM常用来获取文档的节点、元素,操作他们的样式呈现和行为。
JavaScript的DOM常用来增强用户体验。
一个浏览器进程中一般有四个线程:javascript引擎线程、渲染引擎线程、浏览器事件线程、http请求线程。同步:等前一个任务完成之后再执行下一个任务,是顺序的。如果前一个任务耗时很长,后一个任务将总是等不到执行。
异步:后一个任务是通过前一个任务执行回调执行的。<script>标签可以是内联的,放在html文档中,当解析的时候遇到内联的<script>标签的时候就会停止文档的解析,执行脚本代码。直到脚本执行完后继续解析文档。
<script>标签放在<head>标签中,文档的解析要等到脚本全部加载完后才解析。
<script>标签放在</body>前,先解析文档,再执行脚本代码。事件驱动三要素:事件、事件的目标、事件回调函数。
事件处理机制:事件冒泡、事件传播、事件捕获、事件委托。JavaScript 是单线程的,默认是同步的,阻塞的;可以通过 defer 和 async 属性改变脚本的执行方式。