Dom编程艺术学习笔记5

这部分记录了第十章到第十二章的笔记内容。有着鸡汤的味道,尽管部分内容已经跟不上现在的版本了,但是很多原则依旧实用。这本书确实很适合我这样的初学者看,收获不少。而且看着不会感到生涩难懂,哪怕有一些内容没有接触过,按着提供的过程走下去还是能比较愉快的get到一些点的。正如作者所说,这仅仅是前端开发的入门!

Chapter10 用JavaScript实现动画效果

setTimeout

variable = setTimeout("function",interval)第一个参数是一个字符串,是将要执行的那个函数的名字;第二个参数是间隔时间,以毫秒为单位。

clearTimeout(variable)取消某个正在排队等候执行的函数。

在函数中未使用关键字var声明的变量,是一个全局变量,这意味着这个变量可以在该函数之外被读取。

时间递增量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function moveMessage() {
if (!document.getElementById) {
return false;
}
if (!document.getElementById("message")) {
return false;
}
var elem = document.getElementById("message");
var xpos = parseInt(elem.style.left);
var ypos = parseInt(elem.style.top);
if (xpos == 200 && ypos == 100) {
return true;
}
if (xpos < 200) {
xpos++;
}
if (xpos > 200) {
xpos--;
}
if (ypos < 100) {
ypos++;
}
if (ypos > 100) {
ypos--;
}
elem.style.left = xpos + "px";
elem.style.top = ypos + "px";
movement = setTimeout("moveMessage()",10);
}

这个函数以每次1px的方式在浏览器窗口里移动,一旦这个元素的top/left属性同时等于目标值,这个函数就停止执行。

抽象

moveMessage函数只能完成一个特定的任务,并没有什么卵用,所以需要抽象出moveElement函数,从而能够推广到更多的使用范围。

创建moveElement函数

1
2
3
* 打算移动的元素的ID:elementID
* 该元素的目的地的left和top值:final_x,final_y
* 两次移动之间的停顿时间:intrval
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
function moveElement(elementID,final_x,final_y,interval){ //声明各个参数
//兼容性检查
if (!document.getElementById) {
return false;
}
if (!document.getElementById(elementID)){
return false;
}
var elem = document.getElementById(elementID);

//变量作用域问题添加内容
//A处...
//

var xpos = elem.style.left;
var ypos = elem.style.top;

//判断是否到达给定位置
if (xpos == final_x && ypos ==final_y) {
return true;
}
if (xpos < final_x) {
xpos ++;
}
if (xpos > final_x) {
xpos --;
}
if (ypos < final_y) {
ypos ++;
}
if (ypos > final_y) {
ypos --;
}

elem.style.left = xpos + "px";
elem.style.top = ypos + "px";

var repeat = "moveElement('"+elementID+"',"+final_x+","+final_y+","+interval+")";
movement = setTimeout(repeat,interval);

}

css

css的overflow属性用来处理一个元素的尺寸超出其容器尺寸的情况,4个可取值:visible、hidden、scroll、auto。

js

如果用户移动鼠标的速度够快,积累在setTimeout队列里的事件就会导致动画效果产生滞后。为了消除滞后的现象,可以用clearTimeout函数清除积累在setTimeout队列里的事件。

clearTimeout(movement);

我们不能使用局部变量var moument = setTimeout(repeat,interval)。否则,clearTimeout函数调用语句将无法工作,因为局部变量movement在clearTimeout的上下文里不存在!

我们既不能使用全局变量,又不能使用局部变量,需要一种介乎两者之间的东西——“属性”。js允许我们为元素创建属性:element.property = value eg:elem.foo = "bar"

这像是在创建一个变量,区别在于,这仅专属某个特定元素。我们在上面代码段的”A处”添加下面的代码:

1
2
3
4
5
if (elem.movement) {
clearTimeout(elem.movement);
}
//添加到最后
elem.movement = setTimeout(repeat,interval);

改变移动速度+添加安全检查

Math.ceil(number)返回大于number值的一个最小整数。

Math.floor(number)返回小于number值的一个最大整数。

Math.round(number)返回四舍五入的整数值。

引入dist值

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
function moveElement(elementID,final_x,final_y,interval) {
if (!document.getElementById) {
return false;
}
if (!document.getElementById(elementID)) {
return false;
}
var elem = document.getElementById(elementID);
if (elem.movement) {
clearTimeout(elem.movement);
}

//安全检查
if (!elem.style.left) {
elem.style.left = "0px";
}
if (!elem.style.top) {
elem.style.top = "0px";
}


var xpos = parseInt(elem.style.left);
var ypos = parseInt(elem.style.top);
var dist = 0;
if (xpos == final_x && ypos ==final_y) {
return true;
}
if (xpos < final_x) {
dist = Math.ceil((final_x - xpos)/10);
xpos = xpos + dist;
}
if (xpos > final_x) {
dist = Math.ceil((xpos - final_x)/10);
}
if (ypos < final_y) {
dist = Math.ceil((final_y - ypos)/10);
ypos = ypos + dist;
}
if (ypos > final_y) {
dist = Math.ceil((ypos - final_y)/10);
ypos = ypos - dist;
}
elem.style.left = xpos + "px";
elem.style.top = ypos + "px";
var repeat = "moveElement('"+elementID+"',"+final_x+","+final_y+","+interval+")";
elem.movement = setTimeout(repeat,interval);
}

Chapter11 HTML5

由于这本书其实已经算是老书了,前端发展的速度又是非常的迅速,大多数浏览器都已经支持更先进的标准了。有一些浏览器还已经支持ES2015的部分标准了。所以这两章目测讲的都是过时的内容,随便过一下就可以啦!很多东西和之前看的教材《headfirst html5》中重合,可以说还没有headfirst系列详细。

  • HTML5的目标是和已有的HTML及XHTML文档全部兼容,无论怎么标记文档,无论遵循什么编码规则。
  • ,等标签即便不封闭也不影响展示,但是还是专业点加上吧。

发现11.3.2 视频那个实例在chrome ver47中不能运行。在Safari和firefox中都能正常运行。应该是css的支持有问题。不知道是chrome的bug还是咋滴。

Chapter12 综合实例

站点结构管理:

  • /images
  • /styles
  • /scripts
    分别放置图片、css样式表、js脚本。index.html、about.html等页面文件一般放在项目根目录。

css管理

如果把所有css都放到一个文件中,可能会为后期维护带来一些麻烦,把所有css文件分别放在——

  • layout.css(保存和整体布局有关的样式),
  • color.css(作为专门的颜色样式表),
  • typography.css(保存和板式有关的样式)

则是个不错的做法,然后导入到一个基本的样式表basis.css中:

1
2
3
@import url(layout.css);
@import url(color.css);
@import url(typography.css);

字符串:

indexOf方法用于在字符串中寻找子字符串的位置:string.indexOf(substring)
eg:currenturl.indexOf(linkurl)查看某个字符串是否被包含在另一个字符串里面,是否是当前URL里的链接URL,如果没有匹配到,indexOf方法将返回-1.如果返回其他值,则表示有匹配。

字符串分隔:
array = string.split(character)
eg:var sectionId = links[i].getAttribute("href").split("#")[1]第一个元素是#前面的所有字符,第二个则是后面的所有字符。通过上面这段,我们可以把#后面的字符提取出来并保存到sectionId变量中。

表单验证:

  • 验证脚本写得不好,反而不如没有验证
  • 千万不要完全依赖js。客户端验证不能取代服务器端的验证。
  • 客户端的验证的目的在于帮助用户填单,节省时间;服务器端的验证的目的在于保护数据库和后台系统的安全。

  • 占位符值,HTML5的placeholder属性可以添加占位符文本,增进可访问性。

    form对象
    HTML文档中的每个元素都是一个对象,每个元素都有nodeName、nodeType之类的DOM属性。
    文档中的每个表单元素都是一个form对象,每个form对象都有一个elements.length属性。这个属性返回表单中的包含表单元素的个数:form.elements.length
    这个返回值域childNodes.length不一样,后者返回的是元素中包含的所有节点的个数。而form对象的elements.length属性只关注那些属于表单元素的元素,如input、textarea等。
    相应地,表单中的所有字段都保存在form对象的elements 属性中。也就是说form.elements是一个包含所有表单元素的数组。
    同样,这个属性和childNodes属性也不一样,后者也是一个数组。childNodes数组返回的是所有节点,而elements数组则只返回input、select、textarea以及其他表单字段。
    elements数组中的每个表单元素都有自己的一组属性。如element.value等价于element.getAttribute("value")

AJAX

request.setRequestHeader("Content-type","application/x-www-form-urlencoded")这个头信息对于POST请求是必须的,表示请求中包含URL编码的表单。

总结

Web的无所不在是它的魅力。保证任何人都能无障碍地使用它,是一个最基本的原则。
  • 语义化结构标签。

  • 表现信息分离到CSS样式表中。

  • 渐进增强,平稳退化。

  • 常用的脚本收集到自己的代码库中!如addLoadEvent、addClass、insertAfter等

JS 库

常见的库有:JQuery,Prototype,Dojo,Mootools等。(从2015年开始,流行趋势都开始回落了)

库就是可重用的代码包。有以下一些优点:

  • 库代码经过了大量用户的测试和验证。

  • 库能够很容易的与已有的开发框架集成。

  • 库为大多数日常琐碎的DOM编程工作提供了方便、简洁的方案,每个函数都能节省很多行代码。

  • 库很好的解决了跨浏览器的问题,更省心。

    也有一些缺点:

  • 库是由别人而不是自己写的,可能不了解内部工作机制,因此很难调适bug或解决由它导致的问题。

  • 使用库需要集成到脚本中,会加重页面加载的负担,挤占用户有限的带宽。

  • 混合使用多个可能会造成冲突,同时也会造成浪费。

如果你对库只能亦步亦趋而不能超越,那它也会成为你不思进取的慢性毒药。

  • CDN,Content Delevery Network,内容分发网络。

选择库的时候,一定要全面考察!搞清楚如何处理库之间的冲突,功能太少还是太多,社区支持状况,开发文档的情况。同时要能够进一步理解库的工作原理,依赖于库不要紧,但是千万不要停留在简单的使用。

坚持原创技术分享,您的支持将鼓励我继续创作!