前言
在深入学习前端以及了解这个行业的过程中,我渐渐意识到基础知识对个人发展、日后求职的重要性。由此,我在近期入手了网上推荐的一些前端书籍,希望借此巩固基础并加深学习。
这里记一些需要了解/强调的基本要点或细节。部分内容具体可以翻翻书。
第1章 JavaScript简史
JavaScript的起源
- JavaScript是Netscape公司与Sun公司合作开发的。在JavaScript出现之前,Web浏览器不过是一种能够显示超文本文档的简单的软件。而在JavaScript出现之后,网页的内容不再局限于枯燥的文本,它们的可交互性得到了显著的改善。
- JavaScript是使网页具备交互能力的程序设计语言。
- 人们现在谈论的JavaScript 实际上就是ECMAScript。
- JavaScript是一种脚本语言,通常只能通过Web浏览器去完成一些操作而不能像普通意义上的程序那样独立运行。
- JavaScript与java无关,蹭了当时java的热度。
DOM
- 简单地说,DOM是一套对文档的内容进行抽象和概念化的方法。
浏览器战争
DHTML
- DHTML是“Dynamic HTML”(动态HTML)的简称。DHTML并不是一项新技术,而是描述HTML、CSS和JavaScript技术组合的术语。
- DHTML背后的含义是:
- 利用HTML把网页标记为各种元素;
- 利用CSS设置元素样式和它们的显示位置;
- 利用JavaScript实时地操控页面和改变样式。
浏览器之间的冲突
- Netscape公司的DOM使用了专有元素,这些元素称为层(layer)。层有唯一的ID,JavaScript代码需要像下面这样引用它们:
document.layers['myelement']
- 而在微软公司的DOM中这个元素必须像下面这样引用:
document.a11['myelement']
若想找出myelement元素的1eft位置并把它赋值给变量xpos:
- Netscape Navigator 4浏览器:
var xpos=document.layers['myelement'].left;
- IE4浏览器:
var xpos = document.al1['myelement'].leftpos;
制定标准
就在浏览器制造商以DOM为武器展开营销大战的同时,W3C不事声张地结合大家的优点推出了一个标准化的DOM。令人欣慰的是,Netscape、微软和其他一些浏览器制造商们还能抛开彼此的敌意而与W3C携手制定新的标准,并于1998年10月完成了“第1级DOM”(DOM Level1)。
我们已经用
<div>
标签定义了一个ID为myelement的页面元素,现在需要找出它的1eft位置并把这个值保存到变量Xpos中。下面是使用新的标准化DOM时需要用到的语法:var xpos =document.getElementById("myelenent").style.left;
浏览器制造商们感兴趣的只不过是通过JavaScript操控网页的具体办法,但W3C推出的标准化DOM却可以让任何一种程序设计语言对使用任何一种标记语言编写出来的任何一份文档进行操控。
浏览器以外的考虑
- DOM是一种API(应用程序接口)。
- 简单地说,API就是一组已经得到有关各方共同认可的基本约定。在现实世界中,相当于API的例子包括(但不限于)摩尔斯码、国际时区、化学元素周期表。以上这些都是不同学科领域中的标准,它们使得人们能够更方便地交流与合作。
- W3C对DOM的定义是: “一个与系统平台和编程语言无关的接口,程序和脚本可以通过这个接口动态地访问和修改文档的内容、结构和样式。”
- W3C推出的标准化DOM,在独立性和适用范围等诸多方面,都远远超出了各自为战的浏览器制造商们推出的各种专有DOM。
浏览器战争的结局
受浏览器战争影响最重的人群是那些网站设计人员。跨浏览器开发曾经是他们的噩梦。除了刚才提到的那些在JavaScript实现方面的差异之外,Netscape Navigator和IE这两种浏览器在对CSS的支持方面也有许多非常不同的地方。而编写那些可以同时支持这两种浏览器的样式表和脚本的工作也成了一种黑色艺术。
崭新的起点
- 今天,几乎所有的浏览器都内置了对DOM的支持。20世纪90年代后期的浏览器大战的硝烟已经散尽。现在的浏览器厂商无一不在争先恐后地实现最新规范。
- HTML5极大地改进了标记的语义,让我们通过
<audio>
和<video>
得以控制各种媒体,<canvas>
元素具备了完善的绘图能力,浏览器本地存储超越了cookie限制,更有内置的拖放支持,等等。
第2章 JavaScript语法
准备工作
引用js最好的做法是把
<script>
标签放到HTML文档的最后,</body>
标签之前,这样能使浏览器更加快地加载页面(第五章有详解)。1
2
3
4
5
6
7
8
9
10
11
12
13
14<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Example</title>
</head>
<body>
Mark-up goes here...
<script src="demo.js"></script>
</body>
</html>
//<script>标签里没有包含传统的`type="text/java script"`属性。
//因为脚本默认是JavaScript,所以没必要指定这个属性。JavaScript是解释型语言。
- 程序设计语言分为 解释型 和 编译型 两大类。
- Java或C++等语言需要一个编译器(compiler)。编译器是一种程序,能够把用Java等高级语言编写出来的源代码翻译为直接在计算机上执行的文件。
- 用编译型语言编写的代码有错误,这些错误在代码编译阶段就能被发现。
- 解释型程序设计语言不需要编译器——它们仅需要解释器。对于Javascript语言,在互联网环境下,Web浏览器负责完成有关的解释和执行工作。浏览器中的JavaScript解释器将直接读入源代码并执行。浏览器中如果没有解释器,JavaScript代码就无法执行。
- 解释型语言代码中的错误只能等到解释器执行到有关代码时才能被发现。
- Java或C++等语言需要一个编译器(compiler)。编译器是一种程序,能够把用Java等高级语言编写出来的源代码翻译为直接在计算机上执行的文件。
语法
- 语句
- 建议在每条语句后加
;
,让代码更加易读。
- 建议在每条语句后加
注释
//单行注释
1
2/* 多行注释
多行注释 */HTML中的注释:
<!-- 注释 -->
变量
- JavaScript 允许程序员直接对变量赋值而无需事先声明。这在许多程序设计语言中是不允许的。
- 在JavaScript脚本中,如果程序员在对某个变量赋值之前未声明,赋值操作将自动声明该变量。虽然JavaScrip没有强制要求程序员必须提前声明变量,但提前声明变量是一种良好的编程习惯。
- JavaScript中,变量与其他语法元素的名字都区分大小写;
- 不允许变量名中包含空格或标点符号(美元符号“$”例外);
- 允许变量名包含字母、数字、美元符号和下划线(但第一个字符不允许是数字)。
- 推荐使用驼峰式命名法:不使用下划线,第一个单词的字母小写,随后每个新单词首字母大写。
- 例:myMood
- 数据类型
- JavaScript为弱类型语言。
- 必须明确类型声明的语言称为强类型(strongly typed)语言。
- 字符串
- 你可以随意选用引号,但最好是根据字符串所包含的字符来选择。如果字符串包含双引号,就把整个字符串放在单引号里;如果字符串包含单引号,就把整个字符串放在双引号里。
- 想让单双引号变成一个普通字符,用转义:
var mood = 'don\'t ask';
- 作为一个好的编程习惯,不管选择用双引号还是单引号,请在整个脚本中保持一致。
- 数值
- 布尔值
- JavaScript为弱类型语言。
数组
array[index] = element;
数组元素可以是变量:
1
2
3var beatles = new Array();
var name = "John";
beatles[0] = name;数组元素还可以包含其他的数组:
1
2
3var lennon = ['John',1940,false];
var beatles = [];
beatles[0] = lennon;
关联数组
- beatles数组是传统数组的典型例子:每个元素的下标是一个数字,每增加一个元素,这个数字就依次增加1。
- 如果在填充数组时只给出了元素的值,这个数组就将是一个传统数组,它的各个元素的下标将被自动创建和刷新。
可以通过在填充数组时为每个新元素明确地给出下标来改变这种默认的行为。在为新元素给出下标时,不必局限于使用整数数字。你可以用字符串:
1
2
3
4var lennon = Array();
lennon["name"] = "John";
lennon["year"] = 1940;
lennon["iiving"] = faise;这是关联数组。由于可以使用字符串来代替数字值,因而代码更具有可读性。但是,不推荐大家使用。本质上,在创建关联数组时,你创建的是Array对象的属性。在JavaScript中,所有的变量实际上都是某种类型的对象。比如,一个布尔值就是一个Boolean类型的对象,一个数组就是一个Array类型的对象。在上面这个例子中,你实际上是给lenmon数组添加了name、year和living三个属性。理想情况下,你不应该修改Array对象的属性,而应该使用通用的对象(Object)。
- 对象
操作
算术操作符
- 加号(+)是一个比较特殊的操作符,它既可以用于数值,也可以用于字符串。把两个字符毒合二为一是一种很直观易懂的操作:
var message = "I am feeling" + "happy";
- 如果把字符串和数值拼接在一起,其结果将是一个更长的字符串(数值会被自动转换为字符串);
- 用同样的操作符来“拼接”两个数值,其结果将是那两个数值的算术和。
1
2
3alert("10"+20); //1020
alert(10 + 20); //30
alert(10 +"20"); //1020
符号(+=),它可以一次完成“加法和赋值”
1
2
3var year = 2019;
var message = "This year is";
message += year; //This year is 2019
条件语句
1 | if(condition){ |
比较操作符
- ==和===区别:全等操作符(===)不仅比较值,还会比较变量的类型。!=和!==一样的道理。
1
2
3
4
5var a = false;
var b = "";
if(a===b){ //false
alert("a equals b");
}
逻辑操作符
&& || !
循环语句
while循环
while
1
2
3while(condition){
statements;
}do…while
1
2
3do{
statements;
}while(condition);
for循环
1
2
3for(initial condition;test condition;alter condition){
statements;
}for循环最常见的用途之一是对某个数组里的全体元素进行遍历处理。
函数
- 作为一种良好的编程习惯,应该先对函数做出定义再调用它们。
变量的作用域
- 如果在某个函数中使用了var,那个变量就将被视为一个局部变量,它只存在于这个函数的上下文中;反之,如果没有使用var,那个变量就将被视为一个全局变量,如果脚本里已经存在一个与之同名的全局变量,这个函数就会改变那个全局变量的值。
对象
实例是对象的具体个体。
- 内建对象
如:Array对象,Date对象等 - 宿主对象
由浏览器提供的预定义对象被称为宿主对象(host object);
第3章 DOM
Document Object Model
- DOM代表着加载到浏览器窗口的当前网页。浏览器提供了网页的地图(或者说模型),而我们可以通过JavaScript去读取这张地图。
- DOM把一份文档表示为一棵树。(文档:“节点树”)
节点
- 元素结点
- 标签的名字就是元素的名字:如
<p>
、<ul>
、<li>
- 标签的名字就是元素的名字:如
- 文本节点
- 在XHTML文档里,文本节点总是被包含在元素节点的内部。
如:<p>Hello world</p>
中的Hello world
- 在XHTML文档里,文本节点总是被包含在元素节点的内部。
- 属性节点
- 属性节点总是被包含在元素节点中。
如:<p title="nihao">Hello world</p>
中的title="nihao"
- 属性节点总是被包含在元素节点中。
获取元素
typeof操作符可以告诉我们它的操作数是一个字符串、数值、函数、布尔值还是对象。
文档中的每一个元素都是一个对象。
- document.getElementById(id):返回一个与那个有着给定id属性值的元素节点对应的对象。
- document.getElementsByTagName(tag):返回一个对象数组
alert(document.getElementsByTagName("*").1ength);
- 上述例子能获取到文档里的所有元素节点
- 通配符(星号字符“*”)必须放在引号里,这是为了让通配符与乘法操作符有所区别。
- document.getElementsByClassName(class)
- 使用这个方法还可以查找那些带有多个类名的元素。要指定多个类名,只要在字符串参数中用空格分隔类名即可。
- 不仅类名的实际顺序不重要,就算元素还带有更多类名也没有关系。
获取和设置属性
object.getAttribute(attribute)
getAttribute方法不属于document对象,所以不能通过document对象调用。object.setAttribute(attribute,value)
setAttribute做出的修改不会反映在文档本身的源代码里。
第4章 案例研究:JavaScript图片库
事件处理函数
- 在onclick事件处理函数所触发的JavaScript代码里增加一条return false语句,就可以阻止默认行为。
<a href="https://niccce.github.io/" onclick="return false;">Click me</a>
- 也可以调用某函数后再阻止默认行为。
拓展
- childNodes属性:可用来获取任何一个元素的所有子元素
- 它是一个包含这个元素全部子元素的数组
- element.childNodes
- 由childNodes属性返回的数组包含所有类型的节点,而不仅仅是元素节点。事实上,文档里几乎每一样东西都是一个节点,甚至连空格和换行符都会被解释为节点,而它们也全都包含在childNodes属性所返回的数组当中。
- nodeType属性
- node.nodeType
- 每个节点都有nodeType属性,nodeType属性总共有12种可取值,但其中仅有3种具有实用价值:
- 元素节点的nodeType属性值是1
- 属性节点的nodeType属性值是2
- 文本节点的nodeType属性值是3
- nodeValue属性:用来获取一个节点的值
- firstChild、lastChild属性
- 无论何时何地,只要需要访问childNodes数组的第一个元素,都可以把它写成firstchild;lastChild则是最后一个元素
node.firstChild
相当于node.childNodes[0]
node.lastChild
相当于node.childNodes[node.childNodes.length-1]
第5章 最佳实践
平稳退化
- 网站的访问者完全有可能使用的是不支持JavaScript的浏览器,还有一种可能是虽然测览器支持 JavaScript,但用户已经禁用它了(比如,因为讨厌看到弹出广告)。
- 如果正确地使用了JavaScript脚本,就可以让访问者在他们的浏览器不支持JavaScript的情况下仍能顺利地浏览你的网站。这就是所谓的平稳退化(graceful degradation),就是说,虽然某些功能无法使用,但最基本的操作仍能顺利完成。
- “JavaScript:”伪协议,不建议使用
- 内嵌的事件处理函数,不建议使用
向CSS学习
- 结构与样式分离
CSS技术的最大优点是,它能够帮助你将Web文档的内容结构(标记)和版面设计(样式)分离开来。
渐进增强
所谓“渐进增强”就是用一些额外的信息层去包裹原始数据。按照“渐进增强”原则创建出来的网页几乎(如果不是“全部”的话)都符合“平稳退化”原则。
更值得推荐的办法是,先把样式信息存入一个外部文件,再在文档的head部分用
<link>
标签来调用这个文件
分离JavaScript
- 若Js语句直接放到js文件里,没有用任何函数封装,这条语句将在JavaScript文件被加载时立刻执行。
- 如果JavaScript文件是从HTML文档的
<head>
部分用<script>
标签调用的,它将在HTML文档之前加载到浏览器里。 - 同样,如果
<script>
标签位于文档底部</body>
之前,就不能保证哪个文件最先结束加载(浏览器可能一次加载多个)。园为脚本加载时文档可能不完整,所以模型也不完整。没有完整的DOM,getElementsByTaglame等方法就不能正常工作。 - 必须让这些代码在HTML文档全部加载到浏览器之后马上开始执行,可用
window.onload
文档将被加载到一个浏览器窗口里,document对象又是window对象的一个属性。当window对象触发onload事件时,document对象已经存在。
1
2
3
4window.onload = sayHi;
function sayHi(){
alert("Hello World");
}1
2
3
4
5
6window.onload = function(){
sayHi();
};
function sayHi(){
alert("Hello World");
}
向后兼容
对象检测
大多数现代的浏览器对DOM的支持都非常不错。但比较古老的浏览器却很可能无法理解DOM提供的方法和属性。因此,即使某位用户在访问你的网站时使用的是支持JavaScript的浏览器,某些脚本也不一定能正常工作。
针对这一问题的最简单的解决方案是,检测浏览器对JavaScript的支持程度。
1 | function myFunction(){ |
或
1 | function myFunction(){ |
浏览器嗅探技术
在JavaScript脚本代码里,在使用某个特定的方法或属性之前,先测试它是否真实存在是确保向后兼容性最安全和最可信的办法,但它并不是唯一的办法。
在浏览器市场群雄逐鹿的那个年代,一种称为浏览器嗅探(browser sniffing)的技术曾经非常流行。
“浏览器嗅探”指通过提取浏览器供应商提供的信息来解决向后兼容问题。从理论上讲,可以通过JavaScript代码检索关于浏览器品牌和版本的信息,这些信息可以用来改善JavaScript脚本代码的向后兼容性,但这是一种风险非常大的技术。
性能考虑
- 尽量少访问DOM和尽量减少标记
- 合并和放置脚本
- 脚本在标记中的位置对页面的初次加载时间也有很大影响。传统上,我们都把脚本放在文档的
<head>
区域,这种放置方法有一个问题。位于<head>
块中的脚本会导致浏览器无法并行加载其他文件(如图像或其他脚本)。一般来说,根据HTTP规范,浏览器每次从同一个域名中最多只能同时下载两个文件。而在下载脚本期间,浏览器不会下载其他任何文件,即使是来自不同域名的文件也不会下载,所有其他资源都要等脚本加载完毕后才能下载。 - 把所有
<script>
标签都放到文档的末尾,</body>
标记之前,就可以让页面变得更快。
- 脚本在标记中的位置对页面的初次加载时间也有很大影响。传统上,我们都把脚本放在文档的
- 压缩脚本
所谓压缩脚本,指的是把脚本文件中不必要的字节,如空格和注释,统统删除,从而达到“压缩”文件的目的。
第6章 案例研究:图片库改进版
如果想用JavaScript给某个网页添加一些行为,就不应该让JavaScript代码对这个网页的结构有任何依赖。
共享onload事件
1 | window.onlaod = firstFunction; |
可换成如下:1
2
3
4window.onlaod = function(){
firstFunction();
secondFunction();
}
- 可以使用一个函数,这个函数的名字是addloadEvent,它是由Simon Willison编写的。它只有一个参数:打算在页面加载完毕时执行的函数的名字
下面是addLoadEvent函数将要完成的操作:
- 把现有的window.onload事件处理函数的值存入变量oldonload。
- 如果在这个处理函数上还没有绑定任何函数,就像平时那样把新函数添加给它。
- 如果在这个处理函数上已经绑定了一些函数,就把新函数追加到现有指令的末尾。
1
2
3
4
5
6
7
8
9
10
11function addLoadEvent(func){
var oldonload = window.onload;
if(typeof window.onload != 'function'){
window.onload = func;
} else {
window.onload=function(){
o1donload();
func();
}
}
}
学习用 参考链接:
https://www.cnblogs.com/yangtoude/p/4753306.html
https://www.imooc.com/wenda/detail/336004
小心onkeypress
onclick事件处理函数比我们想象得更聪明。虽然它的名字“onclick”给人一种它只与鼠标点击动作相关联的印象,但事实却并非如此:在几乎所有的浏览器里,用Tab键移动到某个链接然后按下回车键的动作也会触发onclick事件。
DOM Core和HTML-DOM
- getElementById、getElementByTagName、getAttribute等这些方法都是DOM Core的组成部分。它们并不专属于JavaScript,支持DOM的任何一种程序设计语言都可以使用它们。它们的用途也并非仅限于处理网页,它们可以用来处理用任何一种标记语言(比如XML)编写出来的文档。
- 像onclick这样的属性,属于HTML-DOM
比如说,HTML-DOM为图片提供了一个src对象。这个对象可以把下面这样的语句:element.getAttribute("src")
简化为:element.src
第7章 动态创建标记
一些传统的方法
- document.write:document对象的write()方法可以方便快捷地把字符串插入到文档里。(尽量避免使用该方法)
事实上,那个<p>
和</p>
只不过是一个将被插入文档的字符串的组成部分而已。 - innerHTML属性:innerHTML属性可以用来读、写某给定元素里的HTML内容。
- innerHTML属性不会返回任何对刚插入的内容的引用。
- 类似于document.write方法,innerHIML属性也是HTML专有属性,不能用于任何其他标记语言文档。浏览器在呈现正宗的XHTML文档(即MIME类型是application/xhtml+xml的XHTML文档)时会直接忽略掉innerHTML属性。
DOM方法
setAttribute方法并未改变文档的物理内容,因为浏览器实际显示的是那棵DOM节点树。在浏览器看来,DOM节点才是文档。
createElement:用于创建元素节点。
document.createElement("p")
不论何时何地,只要你使用了createElement方法,就应该把新创建出来的元素赋给一个变量,那个变量会包含一个指向刚创建的那个元素的引用。- appendChild:将新创建的节点插入某个文档的节点树。(会追加到某个元素节点内)
parent.appendChild(child)
- createTextNode:用于创建文本节点。
document.createTextNode("Hello world")
- insertBefore()方法:把一个新元素插入到一个现有元素的前面。
- 新元素:你插入的元素(newElement);
- 目标元素:你想把这个新元素插入到哪个元素(targetElement)之前;
- 父元素:目标元素的父元素(parentElement)。
parentElement.insertBefore(newElement,targetElement)
可用targetElement.parentNode
得到父元素 - 在DOM里,元素节点的父元素必须是另一个元素节点(属性节点和文本节点的子元素不允许是元素节点)。
- DOM没有直接提供在已有元素后插入一个新元素的方法。可编写insertAfter函数:
1
2
3
4
5
6
7
8
9function insertAfter(newElement,targetElement) {
var parent = targetElement.parentNode;
if (parent.lastChild == targetElement) {
parent.appendChild(newElement);
} else {
parent.insertBefore(newElement,targetElement.nextSibling);
//targetElement.nextSibling为目标元素的下一个兄弟元素
}
}
Ajax
学习参考链接:
总结 - Ajax工作原理和实现步骤
Ajax简介
- AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
- AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
- Ajax与服务器交换数据并更新网页中的一小部分的艺术,在不重新加载整个页面的情况下。
- Ajax的主要优势就是对页面的请求以异步方式发送到服务器。而服务器不会用整个页面来响应请求,它会在后台处理请求,与此同时用户还能继续浏览页面并与页面交互。你的脚本则可以按需加载和创建页面内容,而不会打断用户的浏览体验。
- 渐进增强地使用Ajax:Hijax
Ajax所包含的技术
大家都知道Ajax并非一种新的技术,而是几种原有技术的结合体。它由下列技术组合而成。
- 使用CSS和XHTML来表示。
- 使用DOM模型来交互和动态显示。
- 使用XMLHttpRequest来和服务器进行异步通信。
- 使用JavaScript来绑定和调用。
- Ajax技术的核心是XMLHttpRequest对象,这个对象充当着浏览器中的脚本(客户端)与服务器之间的中间人的角色。以往的请求都由浏览器发出,而JavaScript通过这个对象可以自己发送请求,同时也自己处理响应。
- 不同的浏览器创建XMLHttpRequest对象的方法是有差异的。
- IE 浏览器使用 ActiveXObject,而其他的浏览器使用名为 XMLHttpRequest 的 JavaScript 内建对象。
Ajax的工作原理
- 浏览器捕获用户的操作,并进行相应的处理,然后把用户的操作反馈到服务器。
- 服务器接收浏览器端传来的用户操作,然后再把用户操作分发到其他浏览器端。
- 浏览器接收由服务器端分发下来的用户动作,并进行相应的处理。
XMLHttpRequest对象
- XMLHttpRequest对象的三个常用属性
- onreadystatechange属性:该属性存有处理服务器响应的函数。
- readyState属性:该属性存有服务器响应的状态信息。每当readyState改变时,onreadystatchange函数就会被执行。
readyState属性可能的值有5个:
状态 | 描述 |
---|---|
0 | 未初始化。请求未初始化(在调用 open() 之前) |
1 | 正在加载。请求已提出(调用 send() 之前) |
2 | 加载完毕。请求已发送(这里通常可以从响应得到内容头部) |
3 | 正在交互。请求处理中(响应中通常有部分数据可用,但是服务器还没有完成响应) |
4 | 完成。请求已完成(可以访问服务器响应并使用它) |
我们要向这个 onreadystatechange 函数添加一条 If 语句,来测试我们的响应是否已完成(意味着可获得数据)p117
responseText属性:该属性用来取回由服务器返回的数据。
其他属性。
XMLHttpRequest对象的方法
- open()方法:open() 有三个参数。第一个参数定义发送请求所使用的方法,第二个参数规定服务器端脚本的URL,第三个参数规定应当对请求进行异步地处理。
- 它用来指定服务器上将要访问的文件,指定请求类型:GET、POST或SEND。这个方法的第三个参数用于指定请求是否以异步方式发送和处理。
xmlHttp.open("GET","test.php",true);
- 它用来指定服务器上将要访问的文件,指定请求类型:GET、POST或SEND。这个方法的第三个参数用于指定请求是否以异步方式发送和处理。
- send()方法:send() 方法将请求送往服务器。如果我们假设 HTML 文件和 PHP 文件位于相同的目录,那么代码是这样的:
xmlHttp.send(null);
- 其他方法。
Ajax编程步骤
创建XMLHttpRequest对象
- 创建XMLHttp对象语法:
var xmlHttp=new XMLHttpRequest();
- 如果是IE5或者IE6浏览器,则使用ActiveX对象,创建方法:
var xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
- 一般我们手写Ajax的时候,首先要判断该浏览器是否支持XMLHttpRequest对象,如果支持则创建该对象,如果不支持则创建ActiveX对象。JS代码如下:
1
2
3
4
5
6
7//第一步:创建XMLHttpRequest对象
var xmlHttp;
if (window.XMLHttpRequest) { //非IE
xmlHttp = new XMLHttpRequest();
} else if (window.ActiveXObject) { //IE
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP")
}- 创建XMLHttp对象语法:
设置请求方式
在web开发中,请求有get和post两种,区别如下。这是W3C的解释。
注意:GET主要用于查询,PUT、POST、DELETE用于修改。1
2
3
4//第二步:设置和服务器端交互的相应参数,向路径http://localhost:8080/JsLearning3/getAjax准备发送数据
var url = "http://localhost:8080/JsLearning3/getAjax";
xmlHttp.open("POST", url, true);GET 还是 POST?
与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。然而,在以下情况中,请使用 POST 请求:- 无法使用缓存文件(更新服务器上的文件或数据库)
- 向服务器发送大量数据(POST 没有数据量限制)
- 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
异步 - True 或 False?
- AJAX 指的是异步 JavaScript 和 XML(Asynchronous JavaScript and XML)。XMLHttpRequest 对象如果要用于 AJAX 的话,其 open() 方法的 async 参数必须设置为 true:对于 web 开发人员来说,发送异步请求是一个巨大的进步。很多在服务器执行的任务都相当费时。AJAX 出现之前,这可能会引起应用程序挂起或停止。
- 通过 AJAX,JavaScript 无需等待服务器的响应,而是:在等待服务器响应时执行其他脚本,当响应就绪后对响应进行处理
调用回调函数
回调函数就是上述属性onreadystatechange属性,并用此创建一个匿名方法。1
2
3
4
5
6
7
8
9
10
11//第三步:注册回调函数
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
var obj = document.getElementById(id);
obj.innerHTML = xmlHttp.responseText;
} else {
alert("AJAX服务器返回错误!");
}
}
}xmlHttp.status是服务器返回的结果,其中200代表正确。404代表未找到页面,所以这里我们判断只有当xmlHttp.status等于200的时候才可以继续执行。
AJAX状态码说明:
1–:请求收到,继续处理
2–:操作成功收到,分析、接受
3–:完成此请求必须进一步处理
4–:请求包含一个错误语法或不能完成
5–:服务器执行一个完全有效请求失败发送请求
如果需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中规定您希望发送的数据。1
2
3
4
5//第四步:设置发送请求的内容和发送报送。然后发送请求
var params = "userName=" + document.getElementsByName("userName")[0].value + "&userPass=" + document.getElementsByName("userPass")[0].value + "&time=" + Math.random();// 增加time随机参数,防止读取缓存
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=UTF-8"); // 向请求添加 HTTP 头,POST如果有数据一定加加!!!!
xmlHttp.send(params);
第8章 充实文档的内容
- 把“不可见”变成“可见”
- 如果把某个元素的display属性设置为none,这个元素仍是DOM节点树的组成部分,只是浏览器不显示它们而已。
- alt属性的用途:在图片不可用(无法显示)时用一段描述文字来解释这个位置的图片。
- 如何把这不可见变为可见?
- 得到隐藏在属性里的信息
- 创建标记封装这些信息
- 把这些标记插入到文档
- HTML在某些情况下会允许省略结束标签(建议不要省略)
在XHTML的世界里,所有的标签都必须闭合——对诸如
<img>
和<br>
之类的孤立元素也不例外:在书写时它们必须有一个反斜线字符表示标签结束:即<img/>
和<br/>
这样。
注意:为了与早期的浏览器保持兼容,应该在反斜杠字符的前面保留一个空格。书中例子:
- 显示“缩略语列表”:
缩略语(<abbr>
标签)
“定义列表”元素(<dl>
元素)
“定义标题”(<dt>
元素)
“定义描述”(<dd>
) - 显示“文献来源链接表”:
<blockquote cite="https://niccce.github.io/">
获取其中的cite属性。 - 显示“快捷键清单”:
属性accesskey,不同值对应不同的快捷键。如:<a href="index.html" accesskey="1">Home</a>
- 检索和添加信息
思路:
- 获取元素集合;
- 遍历集合,获取元素特定属性或子元素;
- 将各类数据存储在数组里;
- 遍历数组,创建标记,为标记增添所需内容;
- 将标记添加到文档。
- 显示“缩略语列表”:
for/in循环
- 遍历关联数据时可以采用for/in循环该方式,这是由于数组的下标不再是数字,而是人为的命名。其语法如下:
for (variable in arry)
- 在进入第一次循环是,变量variable将被赋值为数组array的第一个元素的下标值;在进入第二次循环时,变量variable将被赋值为数组array的第二个元素的下标值;依此类推,直到遍历完数组array里面的所有元素为止。
- 遍历关联数据时可以采用for/in循环该方式,这是由于数组的下标不再是数字,而是人为的命名。其语法如下:
第9章 CSS-DOM
三位一体的网页
结构层
网页的结构层(structural layer)由HTML
或XHTML之类的标记语言负责创建。表示层
表示层(presentation layer)由CSS
负责完成。CSS描述页面内容应该如何呈现。行为层
行为层(behavior layer)负责内容应该如何响应事件这一问题。这是JavaScript
语言和DOM
主宰的领域。网页的表示层和行为层总是存在的,即使未明确地给出任何具体的指令也是如此。
style属性
- 文档中的每个元素都是一个对象,每个对象又有着各种各样的属性。
- 有一些属性告诉我们元素在节点树上的位置信息。比如说,
parentNode
、nextSibling
、previousSibling
、childNodes
、firstChild
和1astChild
这些属性,就告诉了我们文档中各节点之间关系信息。
- nodeName属性是一个字符串
- style属性是一个对象
- style对象本身是文档中的每个元素节点都具备的属性。
不仅文档里的每个元素都是一个对象,每个元素都有一个style属性,它们也是一个对象。
获取样式
element.style.color
- font-family属性的获取方式与color属性略有不同
- 因为“font”和“family”之间的连字符与JavaScript语言中的减法操作符相同,JavaScript会把它解释为减号。
- 减号和加号之类的操作符是保留字符,不允许用在函数或变量的名字里。这同时意味着它们也不能用在方法或属性的名字里(别忘了,方法和属性其实是关联在某个对象上的函数和变量)。
element.style.fontFamily
- DOM属性fontFamily的值与CSS属性font-family的值是一样的。
- 不管CSS样式属性的名字里有多少个连字符,DOM一律采用驼峰命名法来表示它们。
- 绝大部分样式属性的返回值与它们的设置值都采用同样的计量单位。
内嵌样式
- 通过style属性获取样式有很大的局限性,style属性只能返回内嵌样式(即把css style属性插入到标记里)
- 最好的办法是用一个外部样式表去设置样式,在开头用link元素引入。
- DOM style属性不能用来检索在外部CSS文件里声明的样式,即使把样式添加在html文件的
<head>
中也如此。
在外部样式表里声明的样式不会进入style对象,在文档的
<head>
部分里声明的样式也是如此。
设置样式
- 许多DOM属性是只读的———我们只能用它们来获取信息,但不能用它们来设置或更新信息,但style对象的各个属性都是可读写的。
element.style.property = value
- style对象的属性值(value)必须放在引号里,单双引号均可,若缺了引号,JavaScript会把等号右边的值解释为一个变量。
何时该用DOM脚本设置样式
就像你不应该利用DOM去创建重要的内容那样,你也不应该利用DOM为文档设置重要的样式。
不过,在使用CSS不方便的场合,还是可以利用DOM对文档的样式做一些小的增强。
根据元素在节点树里的位置来设置样式
通过CSS声明样式的具体做法主要有三种
- 为标签元素统一地声明样式
- 为特定class属性的所有元素统一声明样式
- 为独一无二的id属性的元素单独声明样式
也可以为有类似属性的多个元素声明样式
1
2
3input[type*="test"]{
font-size:1.2em;
}在现代浏览器中,甚至可以根据元素的位置声明样式:
1
2
3
4p:first-of-type{
font-size:2em;
font-weight:bold;
}文档中的下一个节点可以用nextSibling属性查找出来
根据某种条件反复设置某种样式
在用CSS安排你的内容时,千万不要人云亦云地认为表格都是不好的。虽然利用表格来做页面布局不是好主意,但利用表格来显示表格数据却是理所应当的。
- 让表格里的行更可读的常用技巧是交替改变它们的背景色,从而形成斑马线效果,使相邻的两行泾渭分明。通过分别设置奇数行和偶数行样式的办法可实现这种效果。如果浏览器支持CSS3,那就很简单,只需要如下两行样式:
1
2tr:nth-child(odd) { background-color:#ffc; }
tr:nth-child(even) { background-color:#fff; }
响应事件
CSS提供的:hover等伪class属性允许我们根据HTML元素的状态来改变样式。DOM也可以通过omouseover等事件对HTML元素的状态变化做出响应。
- 需要决定是采用纯粹的CSS来解决,还是利用DOM来设置样式。你需要考虑以下因素:
- 这个问题最简单的解决方案是什么;
- 哪种解决方案会得到更多浏览器的支持。
className属性
在本章前面的例子里,我们一直在使用DOM直接设置或修改样式。这种做法让“行为层”
干“表示层”的活,并不是理想的工作方式。如果可以在样式表里进行那些修改,那就好多了。设置class属性:
elem.setAttribute("class","intro");
element.className = value
这个技巧只有一个不足:通过className属性设置某个元素的class属性时将替换(而不是
追加)该元素原有的class设置可以利用字符串拼接操作,把新的class设置值追加到className属性上去
elem.className += " intro";
注意,intro前一个字符是空格
对函数进行抽象
把一个非常具体的东西改进为一个较为通用的东西的过程叫做抽象(abstraction)。
第10章 用JavaScript实现动画效果
动画基础知识
- position属性的合法值有static、fixed、relative和absolute四种。static是position属性的默认值,意思是有关元素将按照它们在标记里出现的先后顺序出现在浏览器窗口里。
JavaScript函数
setTimeout
能够让某个函数在经过一段预定的时间之后才开始执行。- 这个函数带有两个参数:第一个参数通常是一个字符串,其内容是将要执行的那个函数的名字;第二个参数是一个数值,它以毫秒为单位设定了需要经过多长时间后才开始执行第一个参数所给出的函数
setTimeout("function",interval)
在绝大多数时候,最好把这个函数调用赋值给一个变量:variable =setTimeout("function",interval)
例:
1
2movement = setTimeout("moveMessage()",5000);
//此处movement没有var,是全局变量- 这个函数带有两个参数:第一个参数通常是一个字符串,其内容是将要执行的那个函数的名字;第二个参数是一个数值,它以毫秒为单位设定了需要经过多长时间后才开始执行第一个参数所给出的函数
clearTimeout
函数可以取消“等待执行”队列里的某个函数。- 这个函数需要一个参数:保存着某个setTimeout函数调用返回值的变量
clearTimeout(variable)
- 这个函数需要一个参数:保存着某个setTimeout函数调用返回值的变量
parselnt
可以把字符串里的数值信息提取出来。- 如果把一个以数字开头的字符串传递给这个函数,它将返回一个数值:
parseInt(string)
例:1
parstInt("39 steps");//39
- 如果把一个以数字开头的字符串传递给这个函数,它将返回一个数值:
parseFloat
函数可以提取的是带小数点的数值(浮点数)parseFloat(string)
实用的动画
CSS的overflow属性用来处理一个元素的尺寸超出其容器尺寸的情况。
当一个元素包含的内容超出自身的大小时,就会发生内容溢出,这种情况,你可以对内容进行“裁剪”,只让一部分内容可见。你还可以通过overflow属性告诉浏览器是否需要显示滚动条,以便让用户能够看到内容的其余部分。
overflow属性的可取值有4种:visible、hidden、scro11和auto。- visible:不裁剪溢出的内容。
浏览器将把溢出的内容呈现在其容器元素的显示区域以外,全部内容都可见。 - hidden:隐藏溢出的内容。
内容只显示在其容器元素的显示区域里,这意味着只有一部分内容可见。 - scroll:类似于hidien,浏览器将对溢出的内容进行隐藏,但显示一个滚动条以便让用户能够滚动看到内容的其他部分。
- auto:类似于scrol1,但浏览器只在确实发生溢出时才显示滚动条。如果内容没有溢出,就不显示滚动条。
- visible:不裁剪溢出的内容。
- 把position设置为relative可以让子元素使用绝对位置。通过使用值relative,子元素的(0,0)坐标将固定在设置了relative的父元素的左上角。
- JavaScript允许我们为元素创建属性
element.property = value
- ceil方法:返回不小于某数值的一个整数。
Math.ceil(number)
- floor方法:返回不大于某数值的一个整数。
Math.floor(number)
- round方法:将任意浮点数舍入为与之最接近的整数
Math.round(number)
第11章 HTML5
HTML5简介
HTML5是HTML语言当前及未来的新标准。
- 在结构层中,HTML5添加了新的标记元素,如
<section>
、<article>
、<header>
和<footer>
。想知道所有新标记可查看规范- HTML5还提供了更多交互及媒体元素,例如
<canvas>
、<audio>
和<video>
。 - 表单得到了加强,新增了颜色拾取器、数据选择器、滑动条和进度条。其中很多新元素都还带有自己的JavaScript和DOM API。
- HTML5还提供了更多交互及媒体元素,例如
- 在行为层中,HTML5规定了DOM中每个新元素的交互方式,以及新的API。
- 在表现层中,CSS3的多个模块囊括了高级选择器、渐变、变换,还有动画。
Modernizr是一个开源的JavaScript库,利用它的富特性检测功能,可以对HTML5文档进行更好的控制。Modernizr不会给你添加浏览器不支持的特性,比如,在IE6中无法使用本地存储.
- Modernizr能做的是为你提供一些不同的CSS类名以及特性检测(feature-detection)属性。
- Modernizr脚本要放在文档开头的
<head>
里,因为这样才可以在加载其他标记之前先加载它,以便它在文档呈现之前能够创建好新的HTML5元素。
Canvas
HTML5的
<canvas>
元素可以动态创建和操作图形图像。
在网页中支起一块“画布”:1
2
3<canvas id="draw-in-me" width="120" height="40">
<p>Powerd By HTML5 canvas</p>
</canvas>所谓绘图空间,在这里就是一个平面二维的绘图表面,其原点(0,0)位于
<canvas>
的左上角。在这个绘图表面的坐标系里,越往右x的值越大,右往下y的值越大。- 书中例子:用
<canvas>
对象在浏览器中把一幅彩色图片变成灰度图片- 为什么使用
<canvas>
而不是队长图片呢?
只有在基于用户操作实现交互时,使用canvas
的优势才会显现出来
- 为什么使用
音频和视频
- 插件是在一个封闭的环境中运行的,通过脚本无法修改或者操作视频内容。如果插件没有提供API,插件运行环境无异于文档中的一个独立王国。
HTML5的
<video>
元素为在文档中嵌入影片以及与影片交互定义了一种标准方式
1 | <video src="movie.mp4"> |
这里嵌入了一段mp4视频,并给出了浏览器不支持video时的替代下载链接。
<audio>
和<video>
这两个标签都很简单,也都有相应的属性用于显示播放控件或更改播放设置,但是它并未说明支持哪些视频格式。
- 像movie.mp4这样的视频,其实是一个包含很多东西的容器。扩展名mp4表示视频是使用基于苹果QuickTime技术的MPEG4打包而成的。这个容器规定了不同的音频和视频轨道在文件中的位置,以及其他与回放相关的特性。
- 在每个影片容器中,音频和视频轨道都使用不同的编解码器来编码。编解码器决定了浏览器在播放时应该如何解码音频和视频。编解码器的核心就是一个算法,用于压缩和存储视频,以减少原始文件的大小,同时可能会也可能不会损失品质。
- 眼下看来,为了保证每个人都能看到视频,必须制作多种格式的视频并在
<canvas>
元素中包含多个来源。 - 为了确保HTML5的最大兼容性,至少要包含下列三个版本:
- 基于H.264和ACC的MP4
- WebM(VP8+Vorbis)
- 基于Theora视频和Vorbis音频的Ogg文件
浏览器在显示
<video>
元素时,会为其添加一些与浏览器样式统一的标准播放控件。
要想自定义这些控件的外观,或者添加新的控件,可以通过一些DOM属性来实现,主要包括:
- currentTime,返回当前播放的位置,以秒表示;
- duration,返回媒体的总时长,以秒表示,对于流媒体返回无穷大;
- paused,表示媒体是否处于暂停状态。
还有一些与特定媒体相关的事件,可以用来触发你的脚本。主要事件有:
- play,在媒体播放开始时发生;
- pause,在媒体暂停时发生;
- loadeddata,在媒体可以从当前播放位置开始播放时发生;
- ended,在媒体已播放完成而停止时发生。
- 不管创建什么控件,都别忘了在
<video>
元素中添加contro1属性<video src="movie.ogv" controls>
这行代码会呈现出一个类似Chrome浏览器中所示的常见的播放控制界面,但其中的控件可以通过脚本来移走。
表单
HTML5给我们带来了很多新表单元素、新输入控件类型和新的属性。
- 新的输入控件类型(type):
- email,用于输入电子邮件地址;
- url,用于输入URL;
- date,用于输入日期和时间;
- number,用于输入数值;
- range,用于生成滑动条;
- search,用于搜索框;
- tel,用于输入电话号码;
- color,用于选择颜色。
新的属性:
- autocomplete,用于为文本(text)输入框添加一组建议的输入项;
- autofocus,用于让表单元素自动获得焦点;
- form,用于对
<form>
标签外部的表单元素分组; - min、max和step,用在范围(range)和数值(number)输入框中;
- pattern,用于定义一个正则表达式,以便验证输入的值;
- placeholder,用于在文本输入框中显示临时性的提示信息;
- required,表示必填。
旧浏览器会将新类型默认为text,并呈现出标准的文本输入框。
用Modernizr库,可以进行兼容性检测。
比如,要检查浏览器是否支持某个输入类型的控件,可以使用inputtypes.type属性
1
2
3if(!Modernizr.inputtypes.data){
//生成日期选择器的脚本
}要检查某个属性,则可以使用input.attribute属性
1
2
3if(!Modernizr.input.placeholder){
//生成占位符提示信息的脚本
}
HTML5还有其他特性吗?
- 使用localStorage和sessionStorage在客户端存储大型和复杂数据集的更有效方案
- 使用WebSocket与服务器端脚本进行开放的双向通信
- 使用Web Worker在后台执行JavaScript
- 标准化的拖放实现
- 在浏览器中实现地理位置服务
第12章 综合示例
附录 JavaScript库
- 本文作者: Niccce
- 本文链接: https://niccce.github.io/2019/06/30/JavaScript_DOM_Programming_Art(2nd_Edition)/
- 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!