avascript 等于 ECMAScript + 宿主环境。宿主环境提供了一系列的全局对象,例如Node.js提供的require, console等;浏览器提供的DOM、BOM对象。本节课咱们便来了解浏览器,熟悉客户端脚本开发和调试。javascript
Javascript 已经成为 Web 页面逻辑的默认脚本语言,能够直接在 HTML 文件中引入而不需代表脚本语言。Javascript 使用 <script>
标签引入,该标签能够出如今 <head>
中,也能够出如今<body>
中。css
在HTML4中,
<script>
标签须要指定脚本类型:type="text/javascript"
。如今已经没必要这样作了。JavaScript 是 HTML5 默认的脚本语言。html
在HTML中引入Javascript有两种方式:内嵌JavaScript和外部JavaScript文件。java
内嵌JavaScript(Inline JavaScript)是指在HTML中添加<script>
标签,并将JavaScript代码直接写在标签的内容中。jquery
<!-- embeded-script.html --> <html> <head> <script> console.log("I'll give you an alert!"); alert('This is an alert.'); </script> </head> <body> script is embeded in HTML </body> </html>
将上述代码另存为embeded-script.html
并用浏览器打开它,你将会看到一个弹出窗口。web
在介绍CSS时提到,为了分离HTML中的样式,咱们把全部样式规则都移到独立的CSS文件中,而后在HTML中加以引入。这使得HTML更加容易理解和维护,同时也对搜索引擎、屏幕阅读器更加友好。ajax
外部脚本也是同样的道理,除了在极少数状况下(少许的JavaScript、Google Analytics等),JavaScript老是应看成为外部资源来引入到HTML中。编程
为了方便维护和复用,咱们经常将不一样语言的代码分离到不一样的文件。更重要的是,这样的组织方式会让你的代码更优雅!浏览器
只须要将<script>
标签内容留空,并添加src
属性:服务器
// file: script.js console.log("I'll give you an alert!"); alert('This is an alert.');
<!-- file: import-script.html --> <html> <head> <script src="./script.js"></script> </head> <body> script.js has been imported. </html>
分别保存上述两个文件,置于同一目录下并打开HTML,会有相同的效果。
HTML为典型的流文档。即:自上而下分红一行一行, 并在每行中按从左至右依次排放元素。正由于HTML流式文档的特征,其中的<script>
也是按从上到下的顺序执行的。HTML之因此采用这样的设计是由于互联网架设之初网络速度颇有限,流式文档能够在载入的过程当中就能够逐步地显示。**
文档对象模型(Document Object Model,DOM)是中立于平台和语言的接口,它容许程序和脚本动态地访问和更新文档的内容、结构和样式。一样地,DOM 也是 W3C(万维网联盟)的标准。换句话将,DOM 定义了访问 HTML 和 XML 文档的标准。
咱们关心的 HTML DOM 则是 DOM 的延伸,它包括 HTML 的标准对象模型、HTML 的标准编程接口、W3C DOM 标准。HTML DOM 定义了全部 HTML 元素的对象和属性,以及访问它们的方法。
说了这么多,上述关于 DOM 和 HTML DOM 的概念或许在你有必定 Web 开发经历时才会理解。如今你能够认为 DOM 就是用来定义如何组织 HTML 结构、如何操做 HTML 元素的。固然,咱们指的是从Javascript中操做 HTML 元素。
HTML DOM 将 HTML 文档视做树结构。这种结构就是咱们常讲的 DOM 树:
若是你须要更多关于DOM的信息,请参考 W3C Schrool 的 DOM 教程。
整个 HTML 文档是由树状组织的节点及其属性构成的。那么如何在Javascript中操做它呢?请看例子:
<!-- file: dom.html --> <html> <body> <ul id="fruits"> <li>Carrot</li> <li>Apple</li> <li>Banana</li> </ul> <script src='./dom.js'></script> </body> </html>
// file: dom.js // 得到id为fruits的节点 var ul = document.getElementById('fruits'), carrot = ul.firstElementChild; ul.removeChild(carrot); var pear = document.createElement('li'); // 设置pear的style属性 pear.setAttribute('style', 'color: red'); // 设置pear的内容 pear.innerHTML = 'pear' ul.appendChild(pear);
这段代码给出了一个简单的操做DOM元素过程。找到id
为fruits
的标签并删除其第一个子节点;而后建立一个新的元素pear
并添加到<ul>
中。更多 DOM 操做的方法请参考 W3C School: DOM 方法。
正是 DOM 事件使得页面能够与用户进行交互,例如点击、移入、移出、滚动等。一样地,来个例子:
<!-- file: event.html --> <html> <head> <script src='./event.js'></script> <head> <body> <div id='block' onmouseover="over(this)" onmouseout="out(this)"> Mouse Over Me ! </div> </body> </html>
// file: event.js function over(obj) { obj.innerHTML="mouse is over!!!" } function out(obj) { obj.innerHTML="mouse is out..." } window.onload = function(){ var div = document.getElementById('block'); div.setAttribute('style', "background:lightgreen; width:200px;height:50px; margin: 50px;"); };
经过设置HTML元素的属性,能够设置其事件处理函数。咱们在<div>
上绑定了两个事件:mouseover
(鼠标移入)和mouseout
(鼠标移出)。
那么window.onload
是什么呢?注意到咱们在<head>
中引入了event.js
,然而由于HTML是流式文档,在执行event.js
时,<body>尚未获得渲染,此时直接document.getElementById('block')
只会获得空。所以咱们须要绑定窗口载入事件的处理函数,在窗口已经载入后,再进行 DOM 操做。
而window
即是咱们接下来要介绍的 BOM。
浏览器对象模型 (Browser Object Model,BOM) 使 JavaScript 有能力与浏览器“对话”。虽然尚无正式标准,但大多现代浏览器都实现了相同的交互方法和属性。其功能包括:操做浏览器窗口、浏览历史与导航、Cookie操做、各种提醒框等。
window
是浏览器中一个特殊的对象。全部 JavaScript 全局对象、函数以及变量均自动成为 window 对象的成员。全局变量是 window 对象的属性。全局函数是 window 对象的方法。
window.location
对象用于访问当前 URL,或者导航到新的页面。location
有以下几个属性:
hostname
:web 主机的域名
pathname
:当前页面的路径和文件名
port
:web 主机的端口
href
:当前url,对它赋值能够实现重定向
reload()
:这是一个方法,调用后会刷新当前页面
除了window.location
外,还有window.history
提供浏览器历史的操做,经常使用的有:
history.back()
:与在浏览器点击后退按钮相同
history.forward()
:与在浏览器中点击按钮向前相同
更多浏览器导航的BOM对象能够参考W3C School:location、W3C School:history。
弹出窗口对象使用简单方便,但因其交互方式生硬,一般只用于调试。能够在 JavaScript 中建立三种消息框:警告框、确认框、提示框。
alert("some message")
:警告框,点击肯定按钮才能继续进行操做;
confirm("something")
:确认框,点击肯定或者取消才能继续进行操做,相应地,返回值为true
或false
;
prompt("something")
:提示框,输入内容,并点击确认或取消才能继续进行操做,相应地,返回输入内容,或者null
(若是取消)。
注意这些弹窗都会阻塞当前的Javascript进程。
console
咱们已经很熟悉了,除了经常使用的console.log()
外,还有console.error()
,console.info()
,console.debug()
等用以日志分级的函数。
console
咱们在Node.js的课程中已经屡次使用,但console并不是 ECMAScript 标准提供的对象。只是浏览器和 Node.js 都实现都提供了这样的全局对象而已。
AJAX(Asynchronous JavaScript and XML,异步的 JavaScript 和 XML),是用来与服务器交换数据并更新部分网页的技术,避免了从新加载整个页面。
能够说AJAX是现代化的页面的标志,可用来建立动态性极强的 web 界面,如今咱们来学习它!绝大多数浏览器都提供了 XMLHttpRequest
对象来完成 AJAX。为了理解 AJAX 是如何工做的,咱们仍是首先看一个案例:
这里有一个按钮,点击按钮将会向服务器请求当前时间,服务器返回后将时间显示在下面。每次点击按钮时间都会更新,但页面不会刷新。
为了实现上述的效果,首先须要在页面上显示相似这样的元素:
<input type='button' onclick='ajaxload()' value='Click Here to Get Data!'> <div id='result'></div>
点击按钮时将会调用ajaxload()
函数,在该函数中进行 AJAX 请求:
function ajaxload(){ var result = document.getElementById('result'); // 建立一个 AJAX 请求 var xhr = new XMLHttpRequest(); // 打开URL:/date xhr.open('GET', '/date', true); // xhr 状态改变的处理函数 xhr.onreadystatechange=function(){ // 状态为4表示响应已就绪;状态码200表示成功的响应 if (xhr.readyState==4 && xhr.status==200) // 显示响应文本 result.innerHTML=xhr.responseText; } xhr.send(); }
更多关于
readyState 的信息
,参见W3C School:ReadyState
上述的代码在ajax.html
中。除此以外,咱们还须要一个服务器来处理这些请求。当请求根目录/
时,返回这个 HTML
文件;当请求/date
时,返回当前时间。下面服务器代码ajax.js
:
// file: ajax.js var http = require('http'), fs = require('fs'), html = fs.readFileSync('./ajax.html', 'utf8'); http.createServer(function (req, res) { switch(req.url){ case '/': res.writeHead(200, {'Content-Type': 'text/html'}); res.write(html) break; case '/date': var date = new Date(); res.writeHead(200, {'Content-Type': 'text/plain'}); res.write(date.toString()) break; } res.end(); }).listen(1337, '127.0.0.1')
这段代码的意图应该比较容易理解吧?咱们在下面的Chrome调试中,会详细地介绍这些代码产生的效果。
到这里,咱们已经介绍了经常使用的几个浏览器全局变量。window
下的全局变量还有:
innerHeight/innerWidth
:浏览器窗口内部高度/宽度;
navigator
:包含有关访问者浏览器的信息;
screen
:访问者屏幕的宽度,以像素计;
setTimeout()/clearTimeout()
:定时器/取消定时;
document.cookie
:如今多数网站使用Cookie来识别用户。
通常的网站都会包含客户端脚本,这些脚本的数量甚至比服务器代码还要多,尤为是单页APP这种交互性优秀的站点。
jQuery 是一个javascript基础框架,极大地方便了客户端脚本的编写,这里只作简要介绍,此后的项目开发中,你会见到众多的jQuery代码。jQuery提供的API包括:
DOM操做:选择、读取和更改DOM元素的内容、属性;
AJAX:异步网络请求;
动画效果:滑动、延迟、淡入淡出等;
事件处理:键盘/鼠标事件、浏览器事件、表单事件等;
表单:表单的提交、表单的序列化、控件焦点变化等。
为了表现jQuery的强大,咱们引入jQuery,使用jQuery从新实现 DOM 一节中的参考代码dom.html
和dom.js
。首先在dom-jquery.js
以前引入jquery.js
:
... <script src='./jquery.js'></script> <script src='./dom-jquery.js'></script> ...
// file: dom-jquery.js // 选择 id 为 fruits 的元素集合(该集合中只有一个元素,即 ul ) var $ul = $('#fruits'); // 找到该元素的第一个子元素(即 li)并将其移除 $ul.find(':first-child').remove(); // 建立一个 li 元素,并设置其 color 样式为 red,其内容为 pear var $pear = $('<li>') .css('color', 'red') .html('pear'); // 将 pear 添加到 ul 中 $ul.append($pear);
若是你是初识jQuery,可能会奇怪$是什么。其实$在javascript中是一个合法的标识符,也就是说
$
能够用来命名变量。
jQuery 提供的全局变量:$
,它称为 jQuery 对象。习惯上,经过 jQuery 选择符获得的集合通常命名为以$起始的字符串,例如 $ul
。
$ul
是一个集合,只不过它只有一个元素。若是使用 $li = $('li')
,那么该集合便会有3个元素,jQuery的全部方法都是对整个集合进行操做的。
Chrome和Firefox是Web开发中经常使用的调试工具,咱们以Chrome为例。使用如下的任何一种方式均可以打开Chrome调试窗口:
在任何一个页面上,点击右键,选择“审查元素”;
快捷键F12
;
设置 -> 更多工具 -> 开发者工具。
打开的调试窗口中,有8个标签页。经常使用的有 Elements、Network、Sources、Console。
Elements 中,咱们能够查看页面元素,在左侧能够点选某一个元素,该元素会在页面上高亮,同时在右侧显示该元素的全部样式。这些样式仍是可编辑的。
Network 中,能够查看当前页面的全部网络请求。好比 AJAX 一节中咱们会发送多个请求,在 Network 标签页中,能够看到访问页面时的请求,以及点击按钮获取数据时的请求,以下图所示:
从上图中能够看到这两个请求:
第一个请求的URL是localhost
,方法为 GET,响应状态码为 200,响应的Content-Type
为text/html
,响应大小为712B,文件大小为567B(其他为协议头所占空间),载入时间为13毫秒。
第二个请求Content-Type
为text/plain
,这是在服务器代码中决定的。另外其initiator
即初始化该请求的代码,在首页(index
)的第14行,咱们这一行的代码为:
xhr.send();
text/html
指示浏览器这是一个HTML文件,浏览器便会把它渲染为一个Web文档。若是将Content-Type
设置为text/plain
,浏览器则会直接显示HTML源码。
不只如此,咱们还能够点击第二个请求来查看其详情,以下图:
右侧详情窗口中有5个标签页,经常使用的是 Headers、Preview、Response。其中 Headers 中给出了请求和响应的全部头字段;Response 则给出了响应体的内容,这里是:
Mon Mar 30 2015 21:32:17 GMT+0800 (CST)
它就是xhr.responseText
的值。
Sources标签页下,能够查看当前网站的HTML,及其引入的全部CSS、Javascript文件。重要的是,在Javascript文件中的任何一行,咱们均可以设置断点,脚本将会在这一行停下来。触发断点时,咱们能够查看断点所在的做用域内的全部变量的值,以下图所示:
右侧窗格显示了局部变量、监视变量以及调用栈。右侧窗格的上方有继续、下一步、进入函数、跳出函数、禁用断点等按钮。
还能够切换至Console,在当前做用域下执行任何Javascript语句。
Console与Node.js的控制台相似,这是一个Javascript的交互式环境。在这里能够执行任何Javascript语句,如图:
上图中咱们首先执行了:
new Date()
控制台中输出了这个语句的返回值。接着执行:
console.error('test error')
咱们便在控制台看到了一则错误,其内容为test error
。
在断点触发时(例如上图中的状况),在控制台能够访问当前做用域的任何对象,读取或设置它们的值,甚至在这里调用做用域内的任何函数。如图即是输出了上述断点触发时的xhr
对象。
本文由Harttle创做,转载需署名做者且注明文章出处