window对象:表示web了浏览器的一个窗口或窗体(winow属性引用自身)
含有以下属性:location包含Location对象,指定当前显示在窗口中URL,允许脚本往窗口里载入新的URL
含有以下方法:
alert(),setTimeout();
document属性 引用Document对象,后者表示显示在窗口中的文档,它包含有一些重要方法,比如getElementById(),返回Element对象,这个对象有其它重要的属性和方法。每个Element对象都有style和className属性。允许脚本指定文档元素的css样式,或者修改应用到元素上的css类名。设置这些css相关的属性会改变文档元素的呈现
Window、Document和Element对象上另一个重要的属性集合是事件处理程序相关的属性,可以在脚本中为之绑定一个函数,事件处理程序的属性名是以单词“on”开始的
Window对象的onlaod处理程序:当显示在窗口中的文档内容稳定并可以操作是会触发它
javaScript程序可以通过Document对象和它包含的Element对象遍历和管理文档内容。它可以通过操纵css样式和类,修改文档内容的呈现,并且可以通过注册适当的事件处理程序来定义文档元素的行为。内容 呈现 和行为的组合,叫做动态HTML
嵌入方式:
1.内联 放置在<script>和</script>标签之间。
2、放置在有<script>标签的src属性指定的外部文件中
3、放置在HTML事件处理程序中,该事件处理程序由onclick或者onmouseover这样的HTML属性指定
4、放在一个URL里,这个url使用特殊的“javascript:”协议
注册时间处理程序:web浏览器先注册javascript函数,并在之后调用它作为事件的响应,javascript代码可以通过把函数赋值给Element对象的属性来注册事件处理程序。Element对象表示文档里的一个HTML元素。
<a href="javascript:new Date().toLocalTimeString;">what time is ite</a>
部分浏览器(firefox)会执行URL里的代码,并使用返回的字符串作为待显示新文档的内容,浏览器会擦除当前文档并显示新文档。
<a href="javascript:alert(new Date().toLocaleTimeString());">时间</a>
当浏览器载入这种类型的URL时,它会执行javascript代码,但是由于没有返回值(alert()方法返回undefined)作为新文档的显示内容,类似firefox的浏览器并不会体会当前显示的文档
javascript:url能识别的“资源”是转换成字符串的执行代码的返回值.如果代码返回undefined,那么这个资源是没有内容的,可以用在可以使用常规URL的任意地方:比如<a>标记的href属性,<form>的action属性,甚至window.open方法的参数
如果要确保javascript:url不会覆盖当前文档,可以用void操作符强制函数调用或给表达式赋予undefined值:
<a href='javascript:void window.open('about:blank');'></a>
如果这个url里没有void操作符,调用window.open()方法返回的值会被转化为字符串并显示,而当前文档也会被覆盖为包含该字符串的文档
javascript程序是由web页面中所有包含的所有javascript代码(内联脚本 html事件处理程序和javascript:URL)和通过《script》标签的src属性引用的外部javascript代码组成。所有这些单独的代码共用同一个全局Window对象。这意味着它们都可以看到相同的Document对象,可以共享相同的全局函数和变量的集合:如果一个脚本定义了新的全局变量或者函数,那么这个变量或者函数会在脚本执行之后对任意javascript代码可见。
如果web页面包含一个嵌入的窗体(通常使用《iframe》元素),嵌入文档中的javascript代码和被嵌入文档里的javascript代码会有不同的全局对象,它可以当作一个独立的javascript程序。但是要记住,没有严格的关于javascript程序范围的定义。如果外面和里面的文档来自于同一个服务器,那么两个文档中的代码就可以进行交互。并且如果你愿意,就可以把它们当作是同一程序的两个互相作用的部分
javascript程序的执行有两个阶段.在第一个阶段,载入文档内容,并执行《script》元素里的代码(包括内联脚本和外部脚本)。脚本通常(但不总是)会按它们在文档里的出现顺序执行。所有脚本里的javascript代码都是从上往下,按照他在条件、循环以及其他控制语句中的出现顺序执行
当文档载入完成,并且所有脚本执行完成后,javascript执行就进入他的第二阶段。这个阶段是异步的,而且由事件驱动的,在事件驱动阶段,web浏览器调用事件处理程序函数(由第一阶段里执行的脚本指定的html事件处理程序,或者之前 调用的事件处理程序来定义),来响应异步发生的事件。调用事件处理程序通常是响应用户输入(鼠标单击或者键盘按下等)。但是还可以有网络活动,运行时间或者javas代码中的错误来触发,注意 ,嵌入web页面里的javascript:url也可以当作是一种事件处理程序,因为直到用户通过单击链接或者提交表单之后它们才有有效果
事件驱动阶段发生的第一事件是laod事件,指示文档已经完全载入,并可以操作,javascript程序经常用这个时间来触发或发生消息。正是这个onlaod事件会对文档进行操作,并做程序想做的任何事。javascript程序的载入阶段是相对短暂的,通常只持续1~2秒。在文档载入完成之后,只有web浏览器显示文档。事件驱动阶段就会一直持续下去
核心javascript和客户端javascript有一个单线程执行模型,脚本和事件处理程序在同一个时间只能执行一个,没有并发性
javascript第一次添加到web浏览器时,还么有api可以用来遍历和操作文档的结构和内容。当文档还在载入时,javascript影响文档内容的唯一方式是快速生成内容。当HTML解析器遇到《script》元素时,它默认必须先执行脚本,然后再恢复文档的解析和渲染,这对于内联脚本没什么问题。但如果脚本源代码是一个有Src属性指定的外部文件,这意味着脚本后面的文档部分在下载和执行脚本之前,都不会出现在浏览器中
脚本的执行只在默认情况下是同步和阻塞的。《script》标签可以有defer和async属性,这可以改变脚本的执行方式,这些都是布尔属性,没有值。只需要出现在《script》标签里即可
defer和async属性都想在告诉浏览器链接进来的脚本不会使用document。write,也不会生成热火文档内容,因此浏览器可以在下载脚本是继续解析和渲染文档,defer属性使得浏览器延迟脚本的执行,知道文档的载入和解析完成,并可以操作。async属性使得浏览器可以尽快的执行脚本,而不用在下载脚本时阻塞文档解析,如果《script》标签同时又两个属性,同时支持两者的浏览器会遵从async属性并忽略defer属性。
注意,延迟的脚本会按它们在文档里的出现顺序执行,而异步脚本在他们载入后执行,这意味着他们可能会无序执行
甚至可以在不支持async属性的浏览器里,通过动态创建《script》元素并把它插入到文档中
来实现脚本的异步加载和执行。
function loadasync(url){ var head=document.getElementsByTagName("head")[0]; var s=document.createElement("script"); s.src=url; head.appendChild(s); }
事件都有名字,比如click change load mouseover keypress或者readystatechange,指示发生的事件的通用类型。事件还有目标,它是一个对象,并且事件就是在它上面发生的。当我们谈论事件的时候,必须同时指定事件类型(名字)和目标,比如一个单击事件发生在HTMLButtonElement对象上,或者一个readystatechange事件发生在XMLHttpRequest对象上
如果想要程序响应一个事“件,写一个函数,叫做“事件处理程序”、“事件监听器”或者“回调”,然后注册这个函数,这样他就会在事件发生时调用它,正如前面提到的,这个可以通过HTML属性来完成,但是我们不鼓励奖javascript代码和HTML内容混淆在一起,反之,注册事件处理程序最简单的方法是把javascript函数赋值给目标对象的属性
比如
window.onload=function (){};
document.getElementById().onclick=function(){}
function handleResponse(){}
request.onreadystatechange=handleResponse;
事件处理程序的属性的名字是以“on”开始,后面跟着事件的名字
对于大部分浏览器中的大部分事件来说,会把一个对象传递给事件处理程序作为参数,那个对象的属性提供了事件的详细信息。比如,传递给单击事件的对象,会有一个属性说明鼠标的哪个按钮被单击(在IE里,这些事件信息被存储在全局event对象里,而不是传递给处理程序函数)。事件处理程序的返回值有时用来指示函数是否充分处理了事件,以及阻止浏览器执行它默认会进行的各种操作。
有些事件的目标是文档元素,它们会经常往上传递给文档树,这个过程叫做“冒泡”。如果注册在按钮上的函数没有处理该事件,事件会冒泡到按钮嵌套的容器元素。
大部分可以成为事件目标的对象都有一个叫做addEventListener的方法,允许注册多个监听器:
window.addEventListener("load",function(){},false);
request.addEventListener("readystatechange",function(){},false);
微软目前只有在IE9中实现了它,在IE8以及之前的浏览器中,必须使用一个相似的方法:
window.attchEvent("onloac",function(){});
客户端javascript程序还是使用异步通知类型,这些类型往往不是事件。如果设置window对象的onerror属性为一个函数,会在发生javascript错误时调用函数。传递给setTimeout和setInterval的函数和真实事件处理程序的注册不同,它们通常叫做“回调逻辑”而不是“处理程序”,但它们和事件处理程序一样,也是异步的
function onLoad(f){ if(onload.loaded){ window.setTimeout(f,0); } else if(window.addEventListener){ window.addEventListener("load",f,false); } else if(window.attchEvent){ window.attchEvent("onload",f); } } onLoad.loaded=false; onLoad(function(){ onLoad.loaded=true; });
客户端javascript时间线
1、web浏览器创建Dcoment对象,并且开始解析Web页面,解析HTML元素和它们的文本内容后添加Element对象和Text节点到文档中。在这个阶段document.readystate属性的值是"loading"。
2、当HTML解析器遇到没有async和defer属性的<script>元素时,它把这些元素添加到文档中,然后执行行内或者外部脚本,这些脚本会同步执行,并且咋脚本下载(如果需要)和执行时解析器会暂停。这样脚本就可以用document.write()来吧文本插入到输入流中,解析器恢复时这些文本会成为文档的一部分。同步脚本将从简单定义函数和注册后面使用的注册事件处理程序。但它们可以遍历和操作文档树,因为在它们执行时已经存在了。这样,同步脚本可以看到它自己的</script>元素和它们之前的文档内容。
3、当解析器遇到设置了async属性的<script>元素时,它开始下载脚本文本,并继续解析文档。脚本会在它下载完成后尽快执行。但是解析器没有停下来等它下载,异步脚本禁止使用document.write方法,它们可以看到自己的《script》元素和它之前的所有文档元素,并且可能或者干脆不可能访问其他的文档内容
4、当文档完成解析,document.readyState属性变成 "interactive"
5、所有defer属性的脚本,会按它们在文档里的出现顺序执行。异步脚本可能也会在这个时间执行。延迟脚本能访问完整的文档树,禁止使用document。write方法
6、浏览器在Document对象上触发DOMContentLoaded事件。这标志这程序执行从同步脚本阶段转换到异步事件驱动阶段。但要注意,这时可能还有异步脚本没有执行完成。
7、这时,文档已经完全解析完成,但是浏览器可能还在等待其他内容载入,如图片,当所有这些内容完成载入时,并且所有异步脚本完成完成载入和执行,document。readyState属性改变为“complete”,web浏览器出发Window对象上的load事件。
8、从此刻起,会调用异步事件,以异步响应用户输入事件、网络事件、计时器过期等
所有浏览器普遍都支持load事件,都会触发它,它是决定文档完全载入并可以操作最通用的技术。
DOMContentLoaded事件在load事件之前触发,当前所有浏览器都支持这个事件,除了IE之外,document.readyState属性在写本书是已被大部分浏览器实现,但是属性的值在浏览器之间有细微的差别。defer属性被所有当前版本的IE支持,但是现在还未被其他浏览器实现。async属性的支持在写本书时还不通用,但是13-4里展示的异步脚本执行技术会被当前所有浏览器支持
标准模式和怪异模式
要进行这种渲染模式的特性检测,通常检查document.compatMode属性。如果其值为“CSS1Compat”,则说明
浏览器工作在标准模式,如果值为“BackCompat”(或者undefined,说明属性根本不存在),则说明浏览器工作在怪异模式。所有现代浏览器都实现了compatMode属性,并且HTML5规范对它进行了标准化
同源策略
是对javascript代码能够操作哪些web内容的一条完整的的安全机制。当web页面使用多个《iframe》元素或者打开其他浏览器窗口的时候,这一策略通常就会发挥作用。
在这种情况下,同源策略负责管理窗口或者窗体中的javascript代码以及和其他窗口或帧的交互,具体的说,脚本只能读取和所属文档来源相同的窗口和文档的属性
文档的来源包含协议、主机,以及载入文档的url端口。从不同web服务器载入的文档具有不同的来源。通过同意主机的不同端口载入的文档具有不同的来源。使用http协议载入的文档和使用https协议载入的文档具有不同的来源,即使它们来自同一服务器。
脚本本身的来源和同源策略并不相关,相关的是脚本所嵌入的文档的来源
为了支持多个子域的多域名站点,可以使用Document对象的domain属性属性,在默认情况下,属性domain存放的是载入文档的服务器的主机名。可以设置这一属性,不过使用的字符串必须具有有效的域前缀或它本身。
另外,domain值中必须有一个点号,不能把它设置为“com”或者其他顶级域名。
如果两个窗口(或者窗体)包含的脚本把domain设置成了相同的值,那么这个两个窗口就不再受同源策略的约束,它们可以互相读取对方的属性。
不严格的同源策略的第二项技术已经标准化为:跨域资源共享,这个标准草案用新“Origin”:请求头和新的Access-control-allow-origin响应头来扩展http,一些浏览器可以使用这种新的头信息来允许跨域http请求,这样XMLHttpRequest就不会被同源策略所限制了。
另一种新技术,叫做跨文档消息,允许来自一个文档的脚本可以传递文本消息到另一个文档里的脚本,而不管脚本的来源是否不同。调用Window对象上的postMessage方法,可以异步传递消息事件(可以用onmessage事件句处理程序函数来处理它)到窗口的文档里。一个文档里的脚本还是不能调用在其他文档里的方法和读取属性,但她们可以用这种消息传递技术来实现安全的通信。
跨站脚本XSS
攻击者像目标web站点注入html标签或者脚本
var name=decodeURLComponent(window.location.search.substring(1))||""; document.write("hello"+name);
防止xss攻击的方式是,在使用任何不可信的数据来动态的创建文档内容之前,从中移除html标签
name=name.replace(/</g,"<").reaplce(/>/,">");