码迷,mamicode.com
首页 > 编程语言 > 详细

javascript dom编程艺术 第2版

时间:2015-07-16 19:14:26      阅读:368      评论:0      收藏:0      [点我收藏+]

标签:

W3C 推出了标准化的DOM, 就是我们现在常用方法, 比如获取一个元素:document.getElementById(id)

语法
用JavaScript编写的脚本,都是由一系列指令构成,这些指令叫做语句(statement). 只要按照正确的语法编写出来的语句才能得到正确的解释.
JavaScript 每条语句以换行符或分号视为结束. 如下为两条语句:
first statement
second statement
也可以放在一行:
first statment; second statment;
建议每行语句的末尾加上分号,并在不用的行显示,易于阅读, 是编程一种良好的习惯:
fisrt statment;
second statment;

注释
JavaScript 注释分单行注释和多行注释,分别为:
// 这里是单行注释说明
<!--这里是单行注释(由于这种注释和html注释相同,容易混淆,所以使用比较少.)-->
/*
这里是多行注释
说明
*/

变量 (variable)
在日常生活里, 有些东西是固定不变的, 有些东西则是会发生变化的.例如,人的姓名和生日是不固定不变的,但心情和年龄却会随着时间的变化而变化. 人们把那些全变化的东西称为变量.
把值存入变量的操作称为赋值(assignment). 我把变量 mood 赋值为 "Happy", 把变量 age 赋值为 30.
var mood = ‘Happy‘;
var age = 30;

数据类型

字符串(String): 由零个或多个字符构成. 字符包括(但不限于)字母, 数字, 标点符号和空格. 字符串必须包在引号里, 单引号双引号都可以.
如下是完全相同的字符串:
var mood = "Happy";
var mood = ‘Happy‘;
当字符串里面包含单引号并且用单引号包,字符串引号前要加转义符"\". 同样的道理双引号也是如此. 如下:
var mood = ‘don\‘t ask‘;
var height = "about 5‘10 \" tall";

数值(Number)
JavaScript 允许使用带小数点的数值, 允许任意位数, 这样的为称为浮点数(floating-point number). 也可以使用负数.
var age = 30.5;
var num = -20.2;

布尔(Boolean)
布尔数据只有两个可选值 true 或 false. 数值也可以转变成布尔类型. 0 false, 1 true.
var b1 = true;
var b2 = false;

数组(Array)
用一个变量表示一组值的集合, 集合中的每个值都是这个数组中的元素. 声明方法:
var arr1 = Array(4); // 声明一个长度为4的空数组
arr1[0] = "abc"; // 为数组的第一元素赋值为"abc"
var arr3 = ["a", "b", "c"]; // 字符串数组
var arr4 = [1, 2, 3, 4]; // 数值数组

对象(Object)
使用一个名字表示一组值,对象的每一个值是对象的一个属性. 例如:
var person = Object(); 
person.name = "vimer";
person.age = 30;
另外一种创建对象的方法是花括号:
var person = { name:"vimer", age:30};


操作(operation)
算术操作符
加法+ 减法- 乘法* 除法/ 递增++ 递减-- 例如:
var num = 1 + (2 * 3) / 2;
var i = 1;
i++; // 2
var s = "hello" + "world"; // 加号还可以作为字符串连接符

条件语句
大于>, 大于等于>= , 小于<, 小于等于<=, 不等于!=, 赋值=, 相等==, 恒等===;
if (condition) {
statements;
} else {
statements;
}
while (condition) {
statements;
increment;
}
do {
statements;
increment;
} while ( condition )
for (initial condition; test condition; alter condition) {
statements;
}
函数:
fucntion name() {
statements;
}

变量作用域
全局变量:(global variable) 可以在脚本中任何位置被引用.
局部变量:(local varibale) 只存在于声明它的那个函数的内部, 函数的外部无法引用.

小结:
简单回顾一下javaScript基本的语法, 详细请阅读 w3school 

 

前面两章都是概念性的东西,基本是找书的原文记录。从本章开始,更多是用一些实例来详细说明DOM的常用的操作和方法。
首先解释一下什么是DOM(Document Object Model),文档对象模型。DOM结构很像我们的家谱树,用parent(父)、child(子)、sibling(兄弟)等来表示家庭中的成员。

要获取一个DOM文档中的成员的有以下几个方法,通过节点ID,通过节点名,通过类名。
例如:
<div id="div1" class="divClass"></div>
<script type="text/javascript">
document.getElementById("div1"); //返回节点对象
document.getElementsByTagName("div");//返回div集合
document.getElementsByClassName("divClass");//返回className为divClass集合
</script>

其中getElementsByClassName 是HTML5中新加的方法,在一些浏览器中还没有的到使用,所以慎用该方法。
写自己的getElementsByClassName:
<script type="text/javascript">
function getElementsByClassName(node, classname){
if(node.getElementsByClassName){
return node.getElementsByClassName(classname);
}else{
var arr = [];
var nodes = node.getElementsByTagName("*");
for(var i = 0, l = nodes.length; i < l; i++){
if(nodes[i].indexOf(classname) != -1){
arr.push(nodes[i]);
}
}
return arr;
}
}
</script>

获取和设置节点属性的方法分别为:
obj.setAttribute(attr);
obj.getAttribute(attr);
值得一提的是getAttribute获取href属性时在IE6和IE7下得到的是绝对路径,在其他浏览器下得到是相对路径。
例如:

<a id="home" href="/doc/index.html">home</a>
<script type="text/javascript">
var home = document.getElementById("home");
var url = home.getAttribute("href");
//标准浏览器下返回的是 /doc/index.html
//IE6和IE7下返回的是(如开有本地服务器) http://localhost/doc/index.html
alert(url); 
</script>

小结:
本章学习,DOM最基本的5个方法,分别为:
获取节点:
getElementById();
getElementsByTagName();
getElementsByClassName(); // 只有新的浏览器支持该方法,写自己的getEelementsByClassName
getAttribute(); // IE6和IE7 获取href和标准浏览器下不一致
setAttribute();

--------------------

js dom第4章图片库1学习

技术分享

html1部分代码

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>javascript图片库</title>

<link href="xl1.css" type="text/css" rel="stylesheet"/>
</head>
<body onload="countBody()">
<!--例子1:javascript图片库1-->
<h1>Snapshots</h1>
<ul>
<li>
<a href="0.jpg" title="a fireworks display" onclick="shopPic(this);return false" >图片1</a>
</li>
<li>
<a href="1.jpg" title="a cup of black coffee"onclick="shopPic(this);return false" >图片2</a>
</li>
<li>
<a href="2.jpg" title="the famous clock"onclick="shopPic(this);return false" >图片3</a>
</li>
</ul>
<img src="0.jpg" alt="png1" id="png">
<!--出现以下几个问题1:占位符,还有当点击链接时,不想跳到另一个窗口,而且是出现一个新的标签,当点击某个链接时,拦截网页的默认行为,,在点击某个链接时,把占位符图片替换为与那个链接相对应图片即可,解决如下
<img src="0.jpg" alt="png1" id="png">
通过对这个id=png进行控制它的效果开始编写js代码
如下:function shopPic(whichpic){
//whichpic它是一个元素节点,也就是图片的链接地址,把路径进行分解,通过getAttribute()方式来获取
// 传入给变量为source
var source=whichpic.getAttribute(‘href‘)
//然后通过document.getElementById(id)来获取它的id,并把这个变量给placeholder
var placeholder=document.getElementById(‘png‘)
//接着使用setAttribute(scr,obj)方法来对前面2个属性进行刷新
placeholder.setAttribute(‘src‘,source)
};
接下来使用非dom解决方案:
{其实,也可以不使用setAttribute()方法也可以改变图片的src属性
setAttribute属于第一级dom的组成部分,它可以设置任意元素节点的任意属性,在第一级dom出现之前
你可以通过另一种办法设置大部分元素的属性,如下
element.value=‘str‘等于element.setAttribute(‘value‘,‘str‘)
类似的方法也可以改变图片的src图片,如下
placeholder.src=source,第一级dom的另一种优势是可移植性好}
应用这个函数也就是导入这个.js文件,当文件量多(或者大)时,应该写在一起,这样方便管理和节省数据量
;
事件处理函数:作用<在特定的事件发生时调用特定的javascript代码,比如点击事件,移动事件,关闭事件>
需要注意刚刚写的shopPic()需要一个参数,一个带有href属性的元素节点参数,需要onlick事件来给链接添加这个行为,如何做的:
有一个非常有效的方法可以做到这一点,使用this关键字,它的意思是:这个对象,如下
shopPic(this)
当把事件处理函数放到图片列表的一个链接中,会遇到一个问题,点击图片链接时,不仅会调用shouPic()函数体
还会调用把网页的默认行为也会触发,这样的情况,我不想要出现,所以要阻止这情况
事件处理机制:在给定某个元素添加事件处理函数后,一旦触发,相应js代码就会得到执行
被调用js代码可以返回一个值,这个值将被传递给那个事件处理函数,返回值:true(被点击了)和false(没被点击)>>>-->
<!--测试事件处理函数是否被调用,例如-->
<a href="http://www.qq.com"onclick="return false">腾讯</a>
<!--#根据上面 的例子,就可以对需要的链接使用这样的方法了
<a href="0.jpg" title="a fireworks display" onclick="shopPic(this);return false" >图片1</a>-->
<!--对shopPic()这个函数进行扩展学习:对不同的链接进行显示不同的文本信息,
在图片库中,有一个名为title的属性,可以利用这个属性把相对的图片和它的文本一同显示的页面上,通过getAttribute方法,如下:-->
<!--《《《学习几个dom的新元素,如下
childNodes属性:可以用获取任何一个元素的所有子元素,它是一个包含这个元素全部子元素的数组
element.childNonds
例如,想把页面里面的body元素的全体子元素搜索出来,首先通过document.getElementsByTagName(‘body‘)方法返回数组中的第一个(也不唯一一个)元素如下
body=document.getElementsByTagName(‘body‘)[0]
然后通过 body.childNodes获取,利用lenght方法可以知道有多少个元素>
childNodes会包含所有类型的节点,不仅是元素节点,文档几乎每一样东西都是一个节点,还有空格等..-->
<!--nodeType:可以让我们知道自己正在与哪一种节点打交道,语法如下:node.nodeTye
// 屏幕上显示值为1,它一共有12种可取值,其中kwde3tkh具有实用价值
// 元素节点属性为1,属性节点属性为2,文本节点属性为3;
//在标记增加一个文本节点,在显示图片时,把这个属性替换成目标图片链接title值,如下:-->
<p id="description">aa</p>
<!--想的效果是这样的,当点击某个链接时,不仅把占位符图片转换为那个链接href属性所指向图片,还要把文本替换为那个图片的链接的title属性值,需要对shopPic()进行修改下,如下-->
<!--nodeValue属性:如果想修改一个文本的节点时,使用它就可以了,语法如下
node.nodeValue,验证这个方法,如下-->
<script type="text/javascript" src="xl1.js"></script>

</body>
</html>

-------------
js部分代码
function shopPic(whichpic) {
//whichpic它是一个元素节点,也就是图片的链接地址,把路径进行分解,通过getAttribute()方式来获取
// 传入给变量为source
var source = whichpic.getAttribute(‘href‘)
//然后通过document.getElementById(id)来获取它的id,并把这个变量给placeholder
var placeholder = document.getElementById(‘png‘)
//接着使用setAttribute(scr,obj)方法来对前面2个属性进行刷新
placeholder.setAttribute(‘src‘, source)
// 把相对的图片和它的文本一同显示的页面上
var text = whichpic.getAttribute(‘title‘);
//这样是不会显示在页面上的,需要几个属性才可以,《《《
var description = document.getElementById(‘description‘)
//alert(description.nodeValue)
//这样调用,返回一个null;<p>元素本来也就是nodeValue属性的null值
//包含在<p>元素里面文本是另一种节点,它是<p>元素第一个子节点,所以需要使用如下方法
//alert(description.childNodes[0].nodeValue)
//firstChild《访问第一个属性》和lastChild《最后一个》属性
//firstChild语法如下:node.firstChild等于node.childNodes[0]
//lastChild语法如下:node.lastChild等于node.childNodes[node.childNodes.lenght-1]
//利用nodeValue属性刷新描述
alert(description.firstChild.nodeValue)
//nodeValue另外的功能是:不仅可以搜索节点的值,还可以用来设置节点的值
//上面有个text变量,当图片库页面上某个图片链接被点击时,会把这个链接的title属性传递给text变量,可以如下
description.firstChild.nodeValue=text
alert(description.firstChild.nodeValue)
// 刚刚加的3条语法:
// var text = whichpic.getAttribute(‘title‘);
// var description = document.getElementById(‘description‘)
// description.firstChild.nodeValue=text
//当点击图片链接时,这个链接title属性值将被提取出来,并保存到text变量中,得到id中description的<p>
//并把它保存到变量description,并把它对象的第一个子节点nodeValue属性设置为变量text值

}
//>..
function countBody(){
body=document.getElementsByTagName(‘body‘)
body1=body[0]
//alert(body1.childNodes.length)
//alert(body1.nodeType)

}
-----
css部分代码
body{
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #333;background-color: #ccc;margin: lem 10%;
}
h1{color: #333;background-color: transparent}
a{color: #c60;background-color: transparent;font-weight: bold;text-decoration: none}
ul{padding: 0}
li{float: left;padding: lem;list-style: none}
img{display: block;clear: both}

(第4章)最终效果(但不是js dom最终里面的效果)

技术分享


-----------------------------
----------------
第5章 最佳实践

 1:平稳退化:确保在页面里面没有js也能正确工作

2:分离js:把页面与js代码分开

3:向下兼容:确保老版本浏览器不会因为js脚本 而死掉

4:性能考虑:如何把脚本执行的性能最优

》》过会的错误:

1:不要怪罪js,因为易学的东西,会泛滥成群

2:flash的遭遇

3:质疑一切

#创建新浏览器窗口方式

window.open(url,name,features):这3个参数都是可选

url:地址,如果url省略,则出现一个空白的窗口

name:新窗口名称,比如a页面可以向b(新的)页面发请求,b页面回馈给a页面

features:以一个逗号分隔的字符串,里面它有新窗口的属性,比如尺寸,以及新窗口的一些功能(如是否右击,菜单栏,状态栏等)

#例如

function show(url){
open(url,‘popUp‘,‘width=320,height=480‘)
}
调用popUp函数的一个办法是使用伪协议
..1:javascript:伪协议
<a href="javascript:popUp(‘http://www.qq.com‘)">exp</a>和javascript:void(0)
‘真‘协议有http,ftp等
内嵌事件处理函数:在第4章学习过这样的知识,这情况也可以调用
popUp函数
<a href="#" onclick="popUp(urlfadd);return false">exp</a>
#return false如果有这个存在,表示不会真正打开这个链接

谁关心这个(如何让这样的js代码预留退路,其中很简单,直接在href写入真实地址)
<a href="url" onclick="popUp(urlfadd);return false">exp</a>这样就成为有效地址
出现另一个情况,因为这个url地址出现了2次,所以有点冗长,简写js代码,如下
<a href="url" onclick="popUp(this.href);return false">exp</a>(平稳退化的案例)

----
向css学习

1:结构与样式分隔
css(层叠样式表),特点:结构与样式分隔
2:渐进增强
就是用一些额外的信息层去包裹原始数据,原则是创建出来的页面几乎都符合“平稳退化“的原则
直接在html里面编css代码,如下
<p style=‘size,width‘>
  str<p>这样做弊大于得
外部的css
<p id=‘p1‘>
p1{
自己写}

分隔js(与分隔css原理一样)

html部分
<a href="#" onclick="popUp(urlfadd);return false" class=‘class‘>exp</a>
如果想把一个事件添加到某个带有特定的id属性元素上,如下docElementById(id).event=action

如果是多个元素可以使用getElementsByTagName和getAttribute把事件添加到有着特定属性的一级元素上:
1:把文档里面所有链接全放入一个数组中
2:遍历数组
3:如果某个链接的class属性等于popUp,就表示这个链接被点击了
var links=document.getElementsByTagName(‘a‘)//如果这行代码放在外部时,它是无法运行的,因为它会直接被运行,如果是从html文档的head部分用script标签调用的,它将在html文档之前加载到浏览器,如果它/body之前,就无法保存哪个文件最先结束加载(浏览器可能一次加载多个),因为脚本加载时文档可能不完整,所以模型也不完成,没有完整的dom,
getElementsByTagName等方法就不能正常工作
 for(var i=0;i<links.length;i++){
        if(links[i].getAttribute(‘class‘)==‘class1‘){
links[i].onclick=function(){
class1(this.getAttribute(‘href‘));
return false
}
}
}
上面的代码放在外部js.js文件中,
解决方法如下:使用window.onload方法,当触发onload时,document对象已经存在,如下代码
window.onload=function1;
function function1(){
var links=document.getElementsByTagName(‘a‘)
  for(var i=0;i<links.length;i++){
if(links[i].getAttribute(‘class‘)==‘class1‘){
links[i].onclick=function(){
class1(this.getAttribute(‘href‘));
return false
}
}
}
}
function show(url){
open(url,‘popUp‘,‘width=320,height=480‘)
}
这个也放在外部

----
向后兼容

1:对象检测:检测浏览器对js支持程序
解决方式如下
function func1(){
if(document.getElementById){
  检用户所使用的浏览器是否运行此方法,在使用对象检测时,一定要删除方法名后的圆括号,如果不删除,只会回返结果,无法是否存在}
}
还可以通逻辑表达式来检测对象是否支持
if(!method){
  语句体}

window.onload=function1;
function function1(){
if(!document.getElementsByTagName){return false};//这样就能保存那些老版浏览器不会因为此行的代码而出现问题,这样做的好处是向后兼容
var links=document.getElementsByTagName(‘a‘)
  for(var i=0;i<links.length;i++){
if(links[i].getAttribute(‘class‘)==‘class1‘){
links[i].onclick=function(){
class1(this.getAttribute(‘href‘));
return false
}
}
}
}

浏览器嗅控技术
在使用某个特定方法或者属性之前,先测试它是否真实存在是确保向后兼容性最安全和最可信的办法,
概念:通过提取浏览器供应商提供的信息来解决向后兼容问题,从理论上讲,可以通过JS代码检索关于浏览器品牌和版本信息,这样可以用来 改善js脚本向后兼容性,但是有风险


-----
性能考虑
1:尽可能少访问dom和尽量减少标记
如下
if(document.getElementsByTagName(‘a‘).length>0){
var l=document.getElementsByTagName(‘a‘);
for(var i=0;i< l.length;i++){
//处理链接
}
}
1:取得所有<a>元素,然后判断是否大于0
2:解决上面的代码性能问题
如下
l=document.getElementsByTagName(‘a‘)
if(l.length>0){
for(var i=0;i< l.length;i++){
信息
}
}

2:合并和放置脚本
如下
<script src=‘a.js‘></script>


包含脚本 最佳方式是使用外部文件,因为外部文件与标记能够清晰的分隔,而且浏览器也能对站点中多个页面重用缓存过相同脚本 ,但是,
下面的情况最好不要使用如下
<script src=‘a.js‘></script>
<script src=‘a.js‘></script>
<script src=‘a.js‘></script>
<script src=‘a.js‘></script>
推荐作法是将多个脚本文件合并到一个脚本文件中,这样可以减少加载页面时发送请求数量,而减少请求数据通常都是在性能优化时首先要考虑的

脚本在标记中的位置对页面实效加载时间也有很大影响,一般情况下,会放在head区域,但是这样有一个问题,位于head块中的脚本会导致浏览器无法并行加载其他文件(如图像或者其他脚本 ),一般情况下,根据http规范,浏览器每次从同一个区域中最多只能同时下载2个文件,而在下载脚本期间,不会下载其他任何文件,来自不同域名的文件也不会下载,所以其他资源都要等脚本加载完毕才能被下载
解决方式是把script标签放到别的地方并不是问题,把所有script标签放到文档末尾,这样会让页面速度点
压缩脚本 :也可以加快速度
概念:就是把脚本文件中不必要的字节:如空格,和注释都删除,从而达到“压缩”文件的目的

压缩工具如下
douglas crockford的jsmin{http://www.crockford.com/javascript/jsmin.html}
雅虎的yui compressor{http://yui.github.io/yuicompressor/}
谷歌的closure compiler{http://closure-compiler.appsport.com/home}(需要FQ)
<!--第6章:图片库改进版-->
1:支持平稳退化吗?
如果js功能被禁用,会怎么样?
根据前面所学的东西,其实js脚本中已经留下 退路么了,即使js功能被禁用掉了,图片库也可以使用,如下:
<li>
<a href="2.jpg" title="the famous clock"onclick="shopPic(this);return false" >图片3</a>
</li>

在没有js干扰情况下,浏览器会沿着href属性给出的链接前进,用户将看到一张新图片,而不是“该页面无法显示”之类的错误信息,虽然说用户体验比用js效果要略差点,但页面基本功能没有受到损害
,以前使用的伪协议如下:
<li>
<a href="javascript:showPic(‘02.jpg‘).return false";title=‘str‘ >图片3</a>
</li>
写成这样,它们在不支持或者禁用js功能的浏览器里面将没有什么作用,换成 href=‘#‘与伪协议一样的问题


<!--它的js与html标记是分离的吗:文档的结构与文档行为分开了吗?也就是说页面里面的行为层是作用于其结构层之上的,还是混合在一起:答案是混合在一起的,如下
<li>
<a href="2.jpg" title="the famous clock"onclick="shopPic(this);return false" >图片3</a>
</li>
,那么如何分离呢?答案如下:
<li>
<a href="2.jpg" title="the famous clock"class="pic1" >图片3</a>
</li>
,因为有共同点,所以直接使用一个id作为分离点的要求,如下:-->

<ul id="imagegallery">
<li>
<a href="0.jpg" title="a fireworks display">图片1</a>
</li>
<li>
<a href="1.jpg" title="a cup of black coffee" >图片2</a>
</li>
<li>
<a href="2.jpg" title="the famous clock">图片3</a>
</li>
</ul>
<!--添加事件处理函数,如下:(
需要完成几个工作:
检查浏览器是否理解getElementsByTagName,getElementById,检查当前页面中是否存在一个id为imagegallery
的元素,遍历这个id中所有元素,设置onclick事件,让它在有关链接被点击完成以下操作:
1:把这个链接作为参数传给shopPic()函数,取消链接被点击时默认行为,不让浏览器打开这个链接,创建函数)-->
---------------------
js
function prepareGallery(){
// 1检点当前浏览器是否理解getElementsByTagName,getElementById
if(!document.getElementsByTagName)return false;
//这行代码表示当那些老的浏览器出现此部分代码时不会被执行
//也就是当这个getElementsByTagName未定义时,就离开,对getElementById相同的操作
if(!document.getElementById) return false;
//合并在一起使用
//if(!document.getElementsByTagName||!document.getElementById)return false
//或者一个变量
//var supported=!document.getElementsByTagName && !document.getElementById;
//if(!supported)return
//也可以如下
//if(!document.getElementsByTagName)
// return false;
//if(!document.getElementById)
// return false;
// 进行逻辑非操作测试,如下
//if( document.getElementById(‘imagegallery‘))return false
//设置一个变量名
var galleay=document.getElementById(‘imagegallery‘)
var linkes=document.getElementsByTagName(‘a‘)
//遍历
for(var i=0;i<linkes.length;i++){
//改变行为
//linkes是一个数组,它是一个节点列表,由dom节点构成集合,添加行为,如下
linkes[i].onlick=function(){//这行匿名函数
//linkes[i].onlick意思说会随着变量i的递增进行变化,比如lines里面有4个元素,第一个是0,最后一个是3
shopPic(this);
return false;
}
}
}
//共享onload事件
//prepareGallery()这个函数需要绑定window.onload事件(在jq说过js里面当如果出现2个或者2个以上的函数时,最后一个会把前面的替换掉)

//通过一个函数体来解决这个问题,如下
function addLoadEvent(func){
var oldonload=window.onload;//把现有的onload传给变量oldonload
if(typeof window.onload!=‘function‘){//如果在这个处理函数上还没有绑定任何函数,就像平时那样把新函数添加给它
window.onload=func;
}else{
window.onload=function(){//如果已经绑定了,就把新函数追加到指令末尾
oldonload();
func();
}
}
}
//addLoadEvent(obj1),addLoadEvent(obj2)当页面里有2个或者以上的时,页面加载完毕时,就可以执行2个或者以上的函数,如下

//不要做太多的假设
/*shopPic()发现了一个问题,就是没有让它进行任何测试和检查
* shopPic()它由prepareGallery()函数调用,而后面开头对getElementsByTagName,getElementById
* 等dom方法是否存在进行了检查,所以确切知道用户浏览器不会因为不理解这2个方法而出问题,对第4章的里面的代码未进行检查(源代码请看第4章)
* ,现在需要让shopPic()函数负责完成2件事:1是找出id属性png的图片并修改其src属性,二是找出id属性description的元素并修改其第一个子(firstChild)的nodeValue属性
* 分2个步骤就可以获得效果了,如下只要png图片存在,即使description不存在,在切换显示新图片的操作也照常进行
* 对它进行shopPic()修改,如下*/
function shopPic(whichpic) {
if(!document.getElementById)return false;
var source = whichpic.getAttribute(‘href‘);
var placeholder = document.getElementById(‘png‘);
placeholder.setAttribute(‘src‘, source);
if(document.getElementById(‘description‘)){
var text = whichpic.getAttribute(‘title‘);
var description = document.getElementById(‘description‘);
description.firstChild.nodeValue=text}
return false;
}
//下一个问题,当如果删除了图片就会出现点击链接没反应(不管是那个链接)
//解决这个问题在prepareGallery()函数体内进行,如下
function prepareGallery(){
if(!document.getElementsByTagName)return false;//这样表示未更新
if(!document.getElementById) return false;
if(!document.getElementById(‘prepareGallery‘))return false;
var galleay=document.getElementById(‘imagegallery‘);
var linkes=document.getElementsByTagName(‘a‘);
alert(11)
for(var i=0;i<linkes.length;i++){
linkes[i].onlick=function(){
return !shopPic(this);

}
}
}
addLoadEvent(prepareGallery);
//优化代码
//1在shopPic中的链接中都有一个名为title属性,现在要这样做,利用if处理,如下
//var text=whichpic.getAttribute(‘title‘);
//if(text!=null){
// pass
//}
//简写if(whichpic.getAttribute(‘title‘)){}
//最后的代码如下
//if(whichpic.getAttribute(‘title‘)){
// var text=whichpic.getAttribute(‘title‘);
//}else{
// text=‘‘
//}
//高效办法(三元操作符)语法如下:condition ? value if true : value if false;
//最终代码如下:
function shopPic(whichpic) {
if(!document.getElementById)return false;
var source = whichpic.getAttribute(‘href‘);
var placeholder = document.getElementById(‘png‘);
if(placeholder.nodeName!=‘IMG‘)return false;
placeholder.setAttribute(‘src‘, source);
if(document.getElementById(‘description‘)){
var text=whichpic.getAttribute(‘title‘)?whichpic.getAttribute(‘title‘):"";
var description = document.getElementById(‘description‘);
if(description.firstChild.nodeType==3){//利用nodeType可以进行检查类型
description.firstChild.nodeValue=text}
}
return false;
}
//键盘事件
//linkes[i].onlick=function(){
// if(shopPic(this)){
//
// }else{
//
// }
//};//利用三元操作符进行简化,如下
//linkes[i].onlick=function(){
// return shopPic(this)?false:true;
//};
////这边只作了一个假设,如果用户使用了键盘操作
////但是并非所有的用户都喜欢使用键盘进行操作,也有鼠标进行操作的,通过一个名为onkeypress事件解决这个问题,如下
//linkes[i].onlick=function(){
// return shopPic(this)?false:true;
//};
//linkes[i].onkeypress=function(){
// return shopPic(this)?false:true;
//};
////更简单的方法,如下
//linkes[i].onkeypress=linkes[i].onclick;
////最终形成的代码,如下
//linkes[i].onlick=function(){
// return shopPic(this)?false:true;
//};
//linkes[i].onkeypress=linkes[i].onclick;
//小心onkeypress的一些问题:当用户每按一个按键都触发它,在某些浏览器里, 甚至tab键,如果这个事件进行处理函数都传回false;
//最终上面的代码如下:
function prepareGallery(){
if(!document.getElementsByTagName)return false;//这样表示未更新
if(!document.getElementById) return false;
if(!document.getElementById(‘prepareGallery‘))return false;
var galleay=document.getElementById(‘imagegallery‘);
var linkes=document.getElementsByTagName(‘a‘);

for(var i=0;i<linkes.length;i++){
linkes[i].onlick=function(){
return !shopPic(this)?false:true;

}
}
}
function shopPic(whichpic) {
alert(1111)
if(!document.getElementById)return false;
var source = whichpic.getAttribute(‘href‘);
var placeholder = document.getElementById(‘png‘);
if(placeholder.nodeName!=‘IMG‘)return false;
placeholder.setAttribute(‘src‘, source);
if(document.getElementById(‘description‘)){
var text=whichpic.getAttribute(‘title‘)?whichpic.getAttribute(‘title‘):"";
var description = document.getElementById(‘description‘);
if(description.firstChild.nodeType==3){//利用nodeType可以进行检查类型
description.firstChild.nodeValue=text}
}
return true;
}
----------------------
css部分
#imagegallery{
list-style:none;
}
#imagegallery li{
display:inline;//这样 表示从按纵向显示变成横向
}


layout.css
body{
font-family:
color:backround:margin:1em 10%}
h1{
color:backround}
a{color,backround-color,font-weight,text-decoration}
ul{
padding}
li{float,padding:list-style}
#imagegallery{
list-style:none;
}
#imagegallery li{
display:inline;//这样 表示从按纵向显示变成横向
}
#imagegallery li a img{
border}

dom core与html-dom
dom:document.getElemenByTagName(‘form‘)
html-dpm:document.form

图片属性src
doc.getAttribute(‘src‘)
doc.src


-------------------------------------
动态创建标记
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!--<link href="css.css" type="text/css" rel="stylesheet"/>-->
<!--<link rel="shortcut icon" href="../image/web1.ico" type="images/x-icon"/>-->
<script language="JavaScript" src="js2.js" charset="UTF-8"></script>
<!--<script ></script>-->
</head>
<body>
<!--动态创建标记-->
传统方式:document.write(),innerHTML
document.write()它是方便将字符串插入到文档里面
但是write()有一个最大的缺点:无法让行为与表示分离,即使把放外部去,需要body部分使用script标签才能调用它

<script>
document.write(‘<p>hello world </p>‘)
insertParagraph(‘你好‘)
</script>
innerHTML属性(大部分浏览器都支持这个属性,但不是w3c dom标准,已经集成在html5里面,它开始于微软ie4浏览器 ),
作用:读写某给定的元素里面html内容,如下
<div id="testdiv">
<p>
this is<em>
content.
</em>
</p>
</div>
<div id="testdiv1">
<p>
this is<em>
content.
</em>
</p>
</div>
元素节点div,p,em 属性节点id="testdiv"
p下面有文本节节点this,content.
//更复杂的例子
<p>this is<em>content.</em></p>
文本节点this is,content.
元素节点em p
<div id="testdiv2">
<p>
this is<em>
content.
</em>
</p>
</div>
</body>
</html>

js
//编写一个函数将一个<p>标签,字符串和一个</p>标签拼接在一起,如下
//function insertParagraph(text){
// var str=‘<p>‘;
// str+=text;
// str+=‘</p>‘
// document.write(str)
//}
////更新上面这个文件,读取
//window.onload=function(){
// var testdiv=document.getElementById(‘testdiv‘) ;
// alert(testdiv.innerHTML)
//};
////现在是写入
//window.onload=function(){
// var testdiv=document.getElementById(‘testdiv‘) ;
// testdiv.innerHTML=‘write:‘+‘ <p>this is<em>content.</em></p>‘
//};
////dom下面的创建,添加方法
////createElement方法:语法createElement(noneName)
////例如
//
////要完成以下2个工作:创建新元素与插入节点树
//onload=function(){
// var para=document.createElement(‘p‘);//创建了
// var info=‘nodeName‘;
// info+=para.nodeName;
// info+="nodeType:";
// info+=para.nodeType;
// alert(info)
// //这边的p为nodeName属性,聚会为1的nodeType属性,表示一个元素节点
//};
////appendChild()方法:语法obj.appendChild(obj),将新创建节点插入到某个文档节点树下面,如下:
//onload=function(){
// var testdiv=document.getElementById(‘testdiv‘) ;
// var para=document.createElement(‘p‘);
// testdiv.appendChild(para);
//};
//createTextNone方法:语法:createTextNone(text)
//创建一个文本节点,如下
onload=function(){

var para=document.createElement(‘p‘);
var testdiv=document.getElementById(‘testdiv1‘) ;
testdiv.appendChild(para)
var text=document.createTextNode(‘hello world1!‘)
//这样创建它,只是在js世界里面变成了一个孤儿,因为没有被插入到任何一个文档节点树里面
//通过appendChild方法可以把这个文档节点插入为某个现有的子节点,如下
para.appendChild(text)
//创建顺序如下
//创建一个p元素节点,把这个p元素节点追加到obj.html文档中的一个元素节点上,创建一个文本节点是,然后追加到那个p元素节点上
//appendChild方法还可以用来连接那些尚未成为文档树一部分节点,与上面的类似

};

//对这个复杂的例子进行扩展
/*
* 1:创建一个p元素节点并赋值
* 2:创建一个文本节点并赋值
* 3:将2里面的追加到1里面
* 4:创建一个em元素节点并赋值
* 5:创建一个文本节点赋值
* 6:追加,
* 7:追加*/
onload=function(){
var parent=document.createElement(‘p‘);
var text1=document.createTextNode(‘this is‘);
parent.appendChild(text1);
var emphasis=document.createElement(‘em‘);
var text2=document.createTextNode(‘my‘);
var text3=document.createTextN;ode(‘content111111.‘)
emphasis.appendChild(text2)
parent.appendChild(emphasis);
parent.appendChild(text3);
var testdiv=document.getElementById(‘testdiv2‘) ;
testdiv.appendChild(parent)

};
第7章中的图片库重点
通过创建和插入方法的基础学习,现在对这几个进行组合使用,如下
obj=docment.createElement(obj)
obj.setAttribute(obj1,obj2)
obj.appendChild(obj3)
如果是第一个,可以使用如下方式
obj[0].appendChild(obj3)
在已有元素前插入一个新元素
insertBefore()
1:新元素:想插入的新元素名称
2:目标元素:想把这个新元素插入到那个目录元素之前
3:父元素:目标父元素
语法如下:insertBefore(新元素,目标元素位置)

在现有元素后插入一个新元素,如下

function insertAfter(new1,tar){
var parent=tar.parentNode;//目标元素属性值
if(parent.lastChild==tar){//判断目标元素是否是parnet的最后一个子元素,如果是就启用appendChild(new1)

parent.appendChild(new1)
}else{
parent.insertBefore(new1,tar.nextSibling)//否则就调用它,将新元素插入到目标元素下一个兄弟元素之前
}
}

--------------------
ajax(重点)
特点:是只针对部分地方刷新
优势:就是对页面请教以异常方式发送到服务器,而服务器不会用整个页面来响应请教,它会在后台处理请求,与此同时用户还能继续浏览器页面并与页面交互

xmlHttpRequest对象它是ajax技术的核心,在浏览器中充当脚本(客户端)与服务器之间的中间人角色,将请求由浏览器发出,通过这个对象可以自己发送请求,也可以处理响应
,例如
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!--<link href="css.css" type="text/css" rel="stylesheet"/>-->
<!--<link rel="shortcut icon" href="../image/web1.ico" type="images/x-icon"/>-->

<!--<script ></script>-->

</head>
<body>
<div id="news"></div>
<script language="JavaScript" src="addLoadEvent.js" charset="UTF-8"></script>
<script language="JavaScript" src="getHTTPObject.js" charset="UTF-8"></script>
<script language="JavaScript" src="getNewContent.js" charset="UTF-8"></script>
</body>
</html>


/**
* Created by Administrator on 2015/6/10 0010.函数名对应.js文件名
*/

function getHTTPObject(){

if(typeof XMLHttpRequest==‘undefined‘)
XMLHttpRequest=function() {
try {
return new ActiveXObject(‘Msxml2.XMLHTTP.6.0‘);
} catch (e) {
}try{return new ActiveXObject(‘Msxml2.XMLHTTP.3.0‘)}
catch(e){}
try{return new ActiveXObject(‘Msxml2.XMLHTTP‘)}
catch(e){}
return false
};
return new XMLHttpRequest();
}
//getHTTPObject()通过对象检测技术检测了XMLHttpRequest,如果未找到。则继续查找,最终返回false或者一个新的XMLHttpRequest(或者XMLHTTP)对象

//如果在脚本中使用了XMLHttpRequest对象时,可以将这个新对象直接赋值给一个变量,如下
//var requst=getHTTPObject()
//XMLHttpRequest()它有很多方法,(重点方法是open)用于指定服务器上将要访问的文件;指定方式类型有get,post,send(这个参数是用于指定请教是否以异常方式发送和处理的)



/**
* Created by Administrator on 2015/6/10 0010.
*/
function addLoadEvent(func){
var oldonload=window.onload;//把现有的onload传给变量oldonload
if(typeof window.onload!=‘function‘){//如果在这个处理函数上还没有绑定任何函数,就像平时那样把新函数添加给它
window.onload=func;
}else{
window.onload=function(){//如果已经绑定了,就把新函数追加到指令末尾
oldonload();
func();
}
}
}
//注意:在使用ajax时,千万要注意同源策略,使用XMLHttpRequest对象发关宔积能访问与基所在的html牌同一个域中的
// 数据,不能向其他域发送请求,此外,有些浏览器还限制ajax请求使用协议

/**
* Created by Administrator on 2015/6/10 0010.
*/
function getNewContent(){
var requst=getHTTPObject();
requst.open(‘GET‘,‘example.txt‘,true);
if(requst){
requst.onreadystatechange=function(){
if(requst.readyState==4){
var para=document.createElement(‘p‘);
var txt=document.createTextNode(requst.responseText);
para.appendChild(txt);
document.getElementById(‘news‘).appendChild(para)
}
};
requst.send(null)
}else{
alert(‘sorry,your brower xml‘)
}
}
addLoadEvent(getNewContent);
//当页面加载完之后,以上代码会发起一个get请求,请求与xml1.html文件位于同一个目录下的example.txt文件
//requst.onreadystatechange是一个事件处理函数。它会在服务器给XMLHttpRequest对象送回响应时被触发,在为requst.onreadystatechange指定函数时,示要在函数后加括号,因为加括号表示立即调用这个函数,我们只需要让这个函数自身调用即可

//function addLoadEvent(func){
// var oldonload=window.onload;//把现有的onload传给变量oldonload
// if(typeof window.onload!=‘function‘){//如果在这个处理函数上还没有绑定任何函数,就像平时那样把新函数添加给它
// window.onload=func;
// }else{
// window.onload=function(){//如果已经绑定了,就把新函数追加到指令末尾
// oldonload();
// func();
// }
// }
//requst.onreadystatechange=functiong;
//在指定请求目标,也明确如何处理响应后,可以使用send()方法来发送请求了
// requst.send(null)
//当浏览器如果不支持XMLHttpRequest对象,getHTTPObject()就返回一个false,因此需要处理以下几种情况,如下
//(服务器在向XMLHttpRequest对象发回响应时,该对象有很多属性可用 ,浏览器会在不同阶段更新readState属性,如下
// 0表示未初始化,1表示正在加载,2:加载完成,3:正在交互,4:完成,当readState等于4时,就可以访问服务器发送回来的数据了
// 访问服务器发送回来的数据要通过2个属性完成 :responseText:用于保存文本字符串形式的数据
// responseXML:保存content-Type头部中指定为"text/xml"的数据,其实就是documentFragment对象)

渐进增强ajax:迅速而且透明,很多人认为它像传统的桌面应用,而不是网站,很多站点需要启用js才能正常访问


hjax:渐进增强地使用ajax
ajax应用 主要依赖后台服务器,实际上是服务器脚本 语言完成了绝大部分工作,XMLHttpRequest对象作为浏览器与服务器之间的中间人角色,负责传递请求和响应,如果将这个中间人离不开,那么它们之后的请求和响应将长一点(并非中断),
然后,为了给这个登录表单添加ajax功能,就需要拦截提交表单(hajax嘛),让XMLHttpRequest请求来发送,触发事件,更多请谷歌之类的在线查找


--------------------
第8章:充实文档内容
1:不应该做什么
理论上可以利用js将一些重要的内容添加到页面上,但这样做其实是一种坏主意,这样一来js就没有任何空间去平衡退化,那些缺乏必要的js支持访问者就会永远看不到你的重要内容了,如果正在使用dom技术将一些重要的信息给页面添加时,就立即停止下来去检查您的计划和思路,可能会发现自己正在滥用dom
在第5章中学习了2个重要的概念
1:渐进增强:从最核心(内容)的部分开始,然后根据内容使用标记实现良好的结构,然后逐步加强这些内容,它可以利用CSS或者DOM来加强各种行为,如果直接使用dom技术,就过早了
2:平稳退化:按照渐进增强原则去充实内容,作为内容添加样式和行为就自动支持平稳退化,如果直接使用JS去添加重要的内容,就无法支持平稳退化了,

2:把“不可见”变成“可见”
在html里面利用CSS进行对结构的改变,比如display属性,title属性,还有alt(用途):在图片不可用(无法显示)时用一段文字描述这个图片的位置信息
通过dom编程就可以解决这个问题
方法如下:得到隐藏属性,创建标记封装这些信息,插入到文档中

3:内容
<h1>what is the document object Model?</h1>
<p>The <abbr title="World Wide Web Consortium">W3c</abbr> defines
the <abbr title="Documebt Object Model">Dom</abbr> as :</p>
<blockquote cite="http://www.w3.org/DOM/">
<p>
A platform- and language-neutral interface that will allow programs
and script to dynamically access and update the
content,strcuture and style of documents.</p></blockquote>
<p>
it is and <abbr title="Application Progamming Interfact">api</abbr> that can be used to navigate HTML and XML documents.</p>
注意:在谷歌浏览器,360浏览器,IE浏览器,UC浏览器里面<abbr ></abbr>不会出现下划线,在火狐下面出现 

abbr标签与acronym标签的区别
abbr表示是对单词或者短语简写的统称
acronym表示对首字母进行缩略
在html5中acronym已经被abbr替换掉了

选XHMTL,HTML,HTML5
我更喜欢html5方式
<!DOCTYPE html>
html5也支持xhtml,html标记
在某些浏览器中要根据doctype来决定使用标准模式,还是兼容模式来显示内容,兼容模式意味着浏览器要模仿早期浏览器的怪异行为,并宿州那些不堆满的页面在新浏览器下面正常工作,一般来说,坚持使用标准模式,html5中已经默认是标准模式
xhtml5
可以让WEB服务器以application/xhtml+xml的MIME类型来显示页面,但必须预先警告
xhml5的一些介绍请看(http://www.xazcit.com/xhtml5-introduction/)


css对上面的html里面的修改:
body{
font-family: Helvetica,Arial,sans-serif;
font-size: 10pt;
}
abbr{
text-decoration: none;
border: 0;
font-style: normal;
}
<link href="01.css" media="screen" rel="stylesheet"/>
media="screen" 每个样式表都需要包含相同的样式选择器,但是有不同的规则声明,以便适应不同的输出设备。即此处的媒体描述符media,这是它的两个value,screen是为了输出到屏幕的,而print是为了适合打印的,他们是对立的关系

显示缩略语列表
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<link href="01.css" media="screen" rel="stylesheet"/>
<!--<link rel="shortcut icon" href="../image/web1.ico" type="images/x-icon"/>-->
<script language="JavaScript" src="addLoadEvent.js" charset="UTF-8"></script>
<script language="JavaScript" src="displayAbbreviations.js" charset="UTF-8"></script>
</head>
<body>
<h1>What is the Document Object Model?</h1>
<p>
The <abbr title="World Wide Web Consortium">W3C</abbr> defines
the <abbr title="Document Object Model">DOM</abbr> as:
</p>
<blockquote cite="http://www.w3.org/DOM/">
<p>
A platform- and language-neutral interface that will allow programs
and scripts to dynamically access and update the
content, structure and style of documents.
</p>
</blockquote>
<p>
It is an <abbr title="Application Programming Interface">API</abbr>
that can be used to navigate <abbr title="HyperText Markup Language">
HTML</abbr> and <abbr title="eXtensible Markup Language">XML
</abbr> documents.
</p>
<!--创建标记-->
<dl>
<dt>Title 1</dt>
<dd>Descripton 1</dd>
<dt>Title 2</dt>
<dd>Descripton 2</dd>
</dl>
</body>
</html>
js部分代码
01.js文件
function displayAbbreviations() {
//检查兼容性
if(!document.getElementsByTagName)return false;
if(!document.createElement)return false;
if(!document.createTextNode)return false;



//取得所有缩略词
//将abbr元素所有的查询出来
var abbr = document.getElementsByTagName(‘abbr‘);
//开始进行遍历,但先需要进行判断测试
if (abbr.length < 1) {
return false;
//如果未找到abbr元素,则停止此函数运行
}
var defs = new Array();//为了获取并保存每个abbr元素提供的信息,需要得到每个abbr标签包含文本及其title属性值,当你需要把像这样的一系列数据保存起来时,数组是理想的
//开始遍历
//遍历这些缩略词
for(var i=0;i<abbr.length;i++){
var current_abbr=abbr[i]
    //添加这条语句解决了浏览器之间的问题,如下
    if(current_abbr.childNodes.length<1)continue;

var definition=current_abbr.getAttribute(‘title‘);//为了得到当家缩略语解释文字,使用了getAttribute()方法得到title属性值,并把值保存到变量里面
//得到元素标签的缩略信息需要使用nodeValue属性,也就是abbr里面最后一个子节点
var key=current_abbr.lastChild.nodeValue;//这条语句是得到这个文本节点的nodeValue属性并把它赋值给变量
defs[key]=definition;

//现在有2个变量,是把我想要保存到defs数组里面的内容,通过其中之王用作数组元素下标,另一个用作数组元素值的方式来同时保存这2值
//为了提高abbr[i]值,在本次循环里面正在被遍历的那个abbr数组元素--赋给一个名为current_abbr变量,在上面
}
//创建dl
var dlist=document.createElement(‘dl‘);
//进行创建并定义这个列表dl,并赋值给dlist变量
//开始进行for的defs数组遍历,与前面的那个for循环不同,可以通过for/in循环把某个数组下标进行临时赋值给一个变量
//语法for(i in iter)
//含义是:对于iter关连数组到每一个键,并把它赋值给变量i,然后进行循环
//遍历定义
for(key in defs){
var definiton=defs[key];
var dtitle=document.createElement(‘dt‘);//先创建一个dt元素
var dtitle_text=document.createTextNode(key);//创建一个临时变量key的文本节点
dtitle.appendChild(dtitle_text);//将文本节点添加到元素节点
var ddesc=document.createElement(‘dd‘);//与创建dt一样的方式
var ddesc_text=document.createTextNode(definiton);
ddesc.appendChild(ddesc_text);
dlist.appendChild(dtitle);
dlist.appendChild(ddesc)
}
  if(dlist.childNodes.length<1)return false

//插入这个定义列表
//首先先给他一个描述文本
//创建一个h2元素节点
var header=document.createElement(‘h2‘)
//创建一个Abbreviations文本节点
var header_text=document.createTextNode(‘Abbreviations‘)
//然后添加到header下面
header.appendChild(header_text)
//对于复杂的文档,可以通过id才能把新创建的元素插入到文档的特定位置
//引用body标签有2种方式:一是dom core,即引用某给定文档的第一个(也仅有一个)body标签
//document.getElementsByTagName(‘body‘)[0]
//第二种使用html-dom,即引用某给定的文档body属性
document.body
//首先,插入缩略语列表标题
document.body.appendChild(header)
//然后,插入它本身
document.body.appendChild(dlist)



}
addLoadEvent(displayAbbreviations);
 
02.js文件
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != ‘function‘) {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}

一个浏览器的"地雷"
 displayAbbreviations() 这个函数体有个问题(不是本身问题),是有关于浏览器方面的问题,在微软的ie6或者更早版本时,把这个.html文件加载到ie浏览器里面,不会看到缩略语列表,还可能看到js出错信息
,有一点不明白,明明 在这个函数开头部分加了对象探测语句,以确保只有支持dom的浏览器才会去执行dom代码,因为这个和历史原因有关js dom第2版中第1章提到(有兴趣的朋友可以看下)

解决方案如下
1:把abbr元素统一替换成acronym元素(不习惯,再说html5已经没有这个标记了)
2:在元素中使用html命名空间(<html :abbr>abbr</html:abbr>),这样只能在ie浏览器下面才能认出,其他则不行
3:保证这个函数体在ie下面平稳退化,解决方式如下:
  for(var i=0;i<abbr.length;i++){
var current_abbr=abbr[i]
    //添加这条语句解决了浏览器之间的问题,如下
    if(current_abbr.childNodes.length<1)continue;
//含义是:如果当前元素没有子元素时,就立刻开始下一次循环,因为ie浏览器在统计abbr元素的子节点个数时,问题是返回一个错误的值:0,所以这条语句在ie浏览器下面就不会继续执行
//但是加了这条if语句又违背了结构化程序设计的原则(一个函数应该只有一个入口和一个出口)
        var definition=current_abbr.getAttribute(‘title‘);//为了得到当家缩略语解释文字,使用了getAttribute()方法得到title属性值,并把值保存到变量里面
//得到元素标签的缩略信息需要使用nodeValue属性,也就是abbr里面最后一个子节点
var key=current_abbr.lastChild.nodeValue;//这条语句是得到这个文本节点的nodeValue属性并把它赋值给变量
defs[key]=definition;


//显示“文献来源链接表”
<blockquote cite="http://www.w3.org/DOM/">
<p>
A platform- and language-neutral interface that will allow programs
and scripts to dynamically access and update the
content, structure and style of documents.
</p>
</blockquote>
blockquote有一个属性cite,这是一个可选属性,可以给它一个url地址,告诉别人blockquote来自那里,但是在实践中,浏览器会忽略这个cite属性的存在
如何让它显示呢
步骤如下
1遍历这个文档中的
blockquote所有元素
2:从blockquote元素提取出cite属性值
3:创建文本source链接
4:把这个链接赋值给blockquote元素的cite属性值
5:把这个链接插入到文献节选末尾

function disp11() {

//查找出blockquote所有元素
var blockquoute=document.getElementsByTagName(‘blockquote‘)
//遍历这个集合
for(i=0;i<blockquoute.length;i++){
//因为我只对blockquoute里面的cite属性值感兴趣,所以进行判断
if(!blockquoute[i].getAttribute(‘cite‘))continue;
//接下来只要blockquoute[i].getAttribute(‘cite‘)这部分存在的情况下才会执行
//创建一个变量url,将blockquoute的cite属性值存入给url
var url=blockquoute[i].getAttribute(‘cite‘);
//查询你的元素:因这blockquoute元素必定包含了块级元素,如p,以容纳被引用大段文本。然后把文献来源链接放在blockquote元素包含的最后一个子元素节点之后,如下
//仔细一看blockquoute最后一个子节点元素应该是p,而这意味着lastCgild属性返回值 将是一个p元素节点
//那个p元素的确是blockquoute元素最后一个元素节点,但在<p>标签与</blockquoute>标签之间还存在着一个换行符,有些浏览器
//会把这个换行符解释为一个文本节点,这样一来,blockquoute的元素节点的lastChild属性就将是一个文本节点而不是那个p元素节点
/*在缩写dom脚本时,会想到某个节点肯定是一个元素节点,谤是错误的,如果没有100%的把握,还是需要查询它的nodeTyle属性值

* */
var blockquoute_child=blockquoute[i].getElementsByTagName(‘*‘);
//这行代码是将它里面的所有元素节点通过*查出来,
if( blockquoute_child.length<1)continue;
//与其假设,还不如进行判断它的长度是否小于1
var elem=blockquoute_child[blockquoute_child.length-1];
//为什么需要-1呢,1:数组从0开始,2:最后一个元素的下标不等于数组的长度,所以要-1
//创建链接
var link=document.createElement(‘a‘)//创建一个链接元素,并把这个赋值给变量link
//创建source文本节点,并把这个赋值给变量line_text
var line_text=document.createTextNode(‘source‘)
//将文本节点插入到这个新链接中
link.appendChild(line_text)
//使用setAttribute方式把它设置为变量url
link.setAttribute(‘href‘,url)
//插入链接
//创建一个sup元素节点
var superscript=document.createElement(‘sup‘)
//将这个新链接放入sup元素中
superscript.appendChild(line)
//这样存在于一个对象,但未插入到任何文档中
//把这个sup追加到elem下面
elem.appendChild(superscript)

}

}
addLoadEvent(disp11);
//显示的“快捷键清单”
//编写了前2个函数有很多共同之处:从创建一个由特定(abbr元素或者blockquote元素)构成的节点集合开始,进行循环这个节点的集合并在每次循环里面
//创建出一些标记,最后将这些新的插入到文档里面
//accesskey属性可以把一个元素(如链接)与键盘上的某个特定按键关联在一起,这对那些不能或者不喜欢用鼠标来浏览页面的人们很有用
//如<a href=‘url.url‘ accesskey=1>url</a>
//有兴趣的朋友可以看下这个网站:http://www.clagnut.com/blog/193;
/*accesskey下面几大数字的含义
1:返回到主页
2:后退到前一个页面
4:打开本页面搜索表单/页面
9:本网站的联系方法
0:查看本网站的快捷键清单
通过dom技术可以动态的创建一份快捷键清单,如下:
1查找出所有链接并取到一个集合中
2遍历这个集合所有链接
3如果某个链接上带有acesskey属性,就把它保存起来
4把这个链接在浏览器窗口的屏显示出来并保存
5创建一个清单
6为拥有快捷键的各大链接分别创建一个列表项
7把列表项添加到“快捷键清单里面”
8把快捷键清单添加到文档里面


* */
<ul id="navigation">
<li><a href="a.html" accesskey="1">a</a></li>
<li><a href="b.html" accesskey="4">b</a></li>
<li><a href="c.html" accesskey="9">c</a></li>
</ul>

代码如下


function d1(){
//显示的“快捷键清单”
//编写了前2个函数有很多共同之处:从创建一个由特定(abbr元素或者blockquote元素)构成的节点集合开始,进行循环这个节点的集合并在每次循环里面
//创建出一些标记,最后将这些新的插入到文档里面
//accesskey属性可以把一个元素(如链接)与键盘上的某个特定按键关联在一起,这对那些不能或者不喜欢用鼠标来浏览页面的人们很有用
//如<a href=‘url.url‘ accesskey=1>url</a>
//有兴趣的朋友可以看下这个网站:http://www.clagnut.com/blog/193;
/*accesskey下面几大数字的含义
1:返回到主页
2:后退到前一个页面
4:打开本页面搜索表单/页面
9:本网站的联系方法
0:查看本网站的快捷键清单
通过dom技术可以动态的创建一份快捷键清单,如下:
1查找出所有链接并取到一个集合中
2遍历这个集合所有链接
3如果某个链接上带有acesskey属性,就把它保存起来
4把这个链接在浏览器窗口的屏显示出来并保存
5创建一个清单
6为拥有快捷键的各大链接分别创建一个列表项
7把列表项添加到“快捷键清单里面”
8把快捷键清单添加到文档里面
* */

if(!document.getElementsByTagName)return false;
if(!document.createElement)return false;
if(!document.createTextNode)return false;
//取得文档中所有链接
var links=document.getElementsByTagName(‘a‘);
//创建数组,保存访问键
var akeys=new Array();
//遍历
for(var i=0;i<links.length;i++){
var current_link=links[i];
if(!current_link.getAttribute(‘accesskey‘))continue;
var key=current_link.getAttribute(‘accesskey‘);
var text=current_link.lastChild.nodeValue;//取得文本
akeys[key]=text;//添加到数组

}
var list=document.createElement(‘ul‘);
for(key in akeys){
var text=akeys[key];
var str=key+‘:‘+text;
var item=document.createElement(‘li‘);
var item_text=document.createTextNode(str);
item.appendChild(item_text);
list.appendChild(item)
}
var header=document.createElement(‘h3‘);
var header_text=document.createTextNode(‘Accesskeys‘);
header.appendChild(header_text);
document.body.appendChild(header);
document.body.appendChild(list);

}
addLoadEvent(d1);


//我这边 有个问题,在我这边的浏览器都没有显示书籍上面 的效果(但代码与书籍上面 是一样的)

//第9章;css-dom

1三位一体页面

1:结构层:它是由html或者xhtml之类的标记语言负责
如<a href=url></a>
2:表示层:由css负责完成
a{color:red}

3:行为层:通过js和dom来实现
function a(){
alert(‘hello world‘)
alert(obj.style.color)}


分离:不多说了,就是将这结构,行为,表示层

style属性
简单说来:就是告诉我们文档中各节点之间关系的信息
,如<p style="color:gray;font-family: Arial,sans-serif">hello</p>
然后通过dom技术对这个独一无二的<p>标签元素进行引用
获取样式
比如要获取它的颜色,如下
obj.style.color
比如要获取字体信息,下面这样是错误的
obj.style.
font-family
需要修改这样
obj.style.fontfamily

设置样式方式
比如设置为红色:obj.style.color="red",注意单引号或者双引号都可以

何时该用dom脚本设置样式
1:根据元素在节点树里面的位置来设置样式

css中
使用标签p{color:red}
使用class. .p1{}
使用id# #a1{}
使用多个元素声明
input[type*="text"]{}
根据元素位置声明样式
p:first-of-type{
}
function get1(node1){、、使用这个函数体就可以完成了
if(node1.nodeType==1)return node1;
if(node1.nextSibling){//这边说明下文档中下一个节点可以用nextSibling属性查找出来,但是这边并不需要下一个节点,而需要是下一个元素节点
return get1(node1.nextSibling)
}
return null;
}
function a(){
if(!document.getElementsByTagName)return false;
if(!document.createElement)return false;
if(!document.createTextNode)return false;
var head1=document.getElementsByTagName(‘h1‘);
var elem;
var i=0;
for(i;i<head1.length;i++){
elem=get1(head1[i].nextSibling);
elem.style.fontsize=‘1.2em‘;
elem.style.fontWeight=‘bold‘;
}
}
然后通过下面的函数体执行
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != ‘function‘) {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}


<body>
<h1>Hold the front page</h1>
<p>This first paragraph leads you in.</p>
<p>Now you get the nitty-gritty of the story.</p>
<p>The most important information is delivered first.</p>
<h1>Extra! Extra!</h1>
<p>Further developments are unfolding.</p>
<p>You can read all about it here.</p>
</body>

 

.intro {
font-weight: bold;
font-size: 1.2em;
}


根据某种条件反复设置某种样式


<body>
<table>
<caption>Itinerary</caption>
<thead>
<tr>
<th>When</th>
<th>Where</th>
</tr>
</thead>
<tbody>
<tr>
<td>June 9th</td>
<td>Portland, <abbr title="Oregon">OR</abbr></td>
</tr>
<tr>
<td>June 10th</td>
<td>Seattle, <abbr title="Washington">WA</abbr></td>
</tr>
<tr>
<td>June 12th</td>
<td>Sacramento, <abbr title="California">CA</abbr></td>
</tr>
</tbody>
</table>

body {
font-family: "Helvetica","Arial",sans-serif;
background-color: #fff;
color: #000;
}
table {
margin: auto;
border: 1px solid #699;
}
caption {
margin: auto;
padding: .2em;
font-size: 1.2em;
font-weight: bold;
}
th {
font-weight: normal;正常的
font-style: italic;斜体
text-align: left;
border: 1px dotted #699;
background-color: #9cc;
color: #000;
}
th,td {
width: 10em;
padding: .5em;
}
.odd {
background-color: #ffc;
}


如果使用了css3,只需要2行样式:
tr:nth-child(odd){}
tr:nth-child(even){}
编写 一个函数体来对这部分效果进行显示,如下
tr:nth-child()方式不可用时,要获取同样的效果就只要采用另外技术,只需要为表格中每个奇数行(或者偶数行)设置一个class属性即可,但是这样做很痛苦,所以通过下面的代码来实现

function a(){
if(!document.getElementsByTagName)return false;
if(!document.createElement)return false;
if(!document.createTextNode)return false;
var head1=document.getElementsByTagName(‘table‘);
var odd,rows;
var i=0;
for(i;i<head1.length;i++){
odd=false;
rows=head1[i].getElementById(‘tr‘);
for(var j=0;j<rows.length;j++){
if(odd==true){
rows[j].style.backgroundColor=‘#ffc‘
odd=false;
}else{
odd=true
}
}
}
}
响应事件
css提供了类似:hover伪class类等属性允许我们根据html元素状态来改变它的样式,dom可以通过onmouseover等事件对html元素状态变化做出响应
通过以下js代码能够解决这个问题


function a(){
if(!document.getElementsByTagName)return false;
if(!document.createElement)return false;
if(!document.createTextNode)return false;
var head1=document.getElementsByTagName(‘table‘);
var i=0;
for(i;i<head1.length;i++){
head1[i].onmousemove=function(){
this.style.fontWeight=‘bold‘;
}
head1[i].onmousemove=function(){
this.style.fontWeight=‘normal‘;
}
}

//这个函数体是将鼠标指针悬停在某个表格行的上方时,把该行加黑加粗
如果想改变某个元素的效果,就使用css,但如果想必改变某个元素行为,使用dom


className属性
来看下下面这个函数体如何添加样式
function a(){
if(!document.getElementsByTagName)return false;
if(!document.createElement)return false;
if(!document.createTextNode)return false;
var head1=document.getElementsByTagName(‘h1‘);
var elem;
var i=0;
for(i;i<head1.length;i++){
elem=get1(head1[i].nextSibling);
elem.style.fontsize=‘1.2em‘;
elem.style.fontWeight=‘bold‘;
}
}
 
当想把一级标题之后的那个元素使用css字符值从1.2em改为1.4em,就要去修改那个a()函数里面的信息
,但是,通过部分css代码,并声明一个样式类,即可解决这个问题,如下
.init{
font-weight:bold;
font-size=1.2}
通过setAttribute()方法来做这件事情
elem.setAttribute(‘class‘,‘init‘)
得到一个属性
elem.className
改变一个属性值
elem.classNmae=value
修改后的代码
function a(){
if(!document.getElementsByTagName)return false;
if(!document.createElement)return false;
if(!document.createTextNode)return false;
var head1=document.getElementsByTagName(‘h1‘);
var elem;
var i=0;
for(i;i<head1.length;i++){
elem=get1(head1[i].nextSibling);
elem.className=‘init‘
}
}
但是这样做有一个不足的地方,通过className民秘设置某个元素的class属性时将被替换(并非追加)该元素原有的class位置
<h1>str</h1>
<p class=‘dirslaimer‘>str1</p>
如果对上面包含标记的文档使用a()函数时,那个文本段元素的class属性将从dirslaimer被替换为init,而在这边实际需要的是追加效果-class属性应该替换为
dirslaimer init,也就是这2个类的叠加
编写一个函数体,如下

* 在需要给一个元素追加新class时,可以使用以下步骤
* 检查className属性值是否为null
* 如果是,把新的class设置值直接赋值给className属性
如果不是,把一个空和新的class设置值追加到className属性上去 */
function b(a,c){
if(!a.className){
a.className=c
}else{
newClass= a.className;
newClass+=" ";
newClass+=c;
a.className=newClass
}
}
function a(){
if(!document.getElementsByTagName)return false;
if(!document.createElement)return false;
if(!document.createTextNode)return false;
var head1=document.getElementsByTagName(‘h1‘);
var elem;
var i=0;
for(i;i<head1.length;i++){
elem=get1(head1[i].nextSibling);
b(elem,‘init‘)//通过这个函数体可以改变奇数和偶数表格行的背景颜色,

}
}

对函数进行抽象
仔细看上面的函数,就会看到它仅适用于h1元素,而且className属性值为init
编写一个新函数体,如下
function str1(a,b){
if(!document.getElementsByTagName)return false;
var hread=document.getElementsByTagName(a);
var elem;
for (var i=0;i<hread.length;i++){
elem=get1(elem[i].nextSibling);
addClass(elem,b)
}

}
/*现在如果把字符串h1,和init作为参数传递给这个新函数体,就可以获得原来的效果了*/
addLoadEvent(function(){
str1(‘h1‘,‘init‘)
});

-------------------------------------
第10章:用js实现动画效果
动画基础:
1:位置,页面元素在浏览器窗口里面是一种表示性信息,因此,位置信息通常是由css负责的,如下
element{
postion:abstion;top:50px;left:100px}
将把这个element元素摆放到距离浏览器的左边界100像素,距离浏览器窗口的上边界50像素位置,如下面的dom代码
element.style.position=‘absluts‘;
element.style.left=‘100px‘;
element.style.top=‘50px‘;

position属性合法值有:static,fixed,relative和absolute
static是position属性默认值,意思是:有关元素按照它们在标记里面出现先后顺序在浏览器中里面
relative含义与static相似,区别是position属性等于relative元素还可能(通过float元素),从文档正常显示顺序里面脱离出来
,当把某个元素的position属性设置为absolute,就可以把它摆放到窽它的窗口任何位置,它就是文档本身,要么是一个fixed或者absolute属性父元素,这个元素在原始标记的位置与它显示位置无关,显示位置由top,letf,right和bottom等属性决定,可以使用像素或者百分比作为单位设置这些属性值
top顶部 ,botton是底部 ,left左边界,right右边界
 <script  language="JavaScript" src="postionMessage.js" charset="UTF-8"></script>
<script language="JavaScript" src="addLoadEvent.js" charset="UTF-8"></script>
</head>
<body>
<p id="message">Wheel!</p>
</body>
function postionMessage(){
if(!document.getElementById)return false;
if(!document.getElementById(‘message‘))return false;
var elem=document.getElementById(‘message‘);
elem.style.position=‘absolute‘;
elem.style.left=‘50px‘;
elem.style.top=‘100px‘;

}

//改变某个元素的位置很简单,只要执行一个函数去改变这个元素的.top,.left等属性
function moveMessage(){
if(!document.getElementById)return false;
if(!document.getElementById(‘message‘))return false;
var elem=document.getElementById(‘message‘);
elem.style.left=‘200px‘
}
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != ‘function‘) {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}
addLoadEvent(postionMessage);
addLoadEvent(moveMessage);

时间
js函数setTimeout能够让某个函数在经过一段预定时间之后才开始执行,有2个参数:第一个参数通常是字符串,其内容是将要执行那个函数的名字,第二个参数是一个数值,它以毫秒为单位设定了需要经过多久时间后才开始执行第一个参数所给的函数,语法如下
time=setTimeout(func,interval)
如果想取消正在排除等待执行的函数,利用cleartTimeout函数来取消等待执行队列里面函数,这个函数需要一个参数:保存某个setTimeout函数调用返回值的变量
,如下代码
function postionMessage(){
if(!document.getElementById)return false;
if(!document.getElementById(‘message‘))return false;
var elem=document.getElementById(‘message‘);
elem.style.position=‘absolute‘;
elem.style.left=‘50px‘;
elem.style.top=‘100px‘;
moveTime=setTimeout(‘moveMessage()‘,5000)//全局变量

}

//改变某个元素的位置很简单,只要执行一个函数去改变这个元素的.top,.left等属性
function moveMessage(){
if(!document.getElementById)return false;
if(!document.getElementById(‘message‘))return false;
var elem=document.getElementById(‘message‘);
elem.style.left=‘200px‘
}
moveClear=clearTimeout(moveTime);
时间递增量
把某个元素在5秒钟向右移动150px显示效果称为动画实在有点儿勉强,真正的动画效果是一种渐变过程。元素应该从出发点逐步地移动到目的地,而不是从出发点一下子跳跃到目的地
,更下这个函数体,
步骤如下
1:获取当前位置
2:如果元素已经到达它的目的地,则退出这个函数
3:如果元素尚未到达它的目的地,则把它向目的地移近一点儿
4:经过一段时间间隔之后从步骤1开始重复上面操作
代码如下
function moveMessage(){
if(!document.getElementById)return false;
if(!document.getElementById(‘message‘))return false;
var elem=document.getElementById(‘message‘);
//分别将left,top给变量为posx,posy
var posx=parseInt(elem.style.left);
var posy=parseInt(elem.style.top);
//parseInt()可以将字符串数字转换成整形数字
if(posx==200 && posy==100){
return true
}
if(posx<200){
posx++//如果小于left,就给它加1
}if(posx>200){
posx--
}
if(posy<100){
posy++
}if(posy>100){
posy--
}
elem.style.left=posx+‘px‘;
elem.style.top=posy+‘px‘;
moveTime=setTimeout(‘moveMessage()‘,10)

}

抽象:刚才编写的moveMessage()函数只能完成只能完成一项非常特定的任务,它将把一个特定的元素移到一个特定的位置,再次移动之间的停顿时间也是一段固定的长度,如上面的代码

创建moveElement函数与
moveMessage()函数不同,新函数参数将会有多个,下面函数的步骤如下
1:打算移动的元素id
2:该元素目的地的左移动
3:该元素目的地的上移动
4:两次移动之间的停顿
参数如下
elementID,posx,posy,interval
创建函数如下


function moveElement(elementID,posx1,posy1,interval){
if(!document.getElementById)return false;
if(!document.getElementById(‘message‘))return false;
var elem=document.getElementById(‘message‘);
var posx=parseInt(elem.style.left);
var posy=parseInt(elem.style.top);
if(posx==posx1 && posy==posy1){
return true
}
if(posx<posx1){
posx++
}if(posx>posx1){
posx--
}
if(posy<posy){
posy++
}if(posy>posy){
posy--
}
elem.style.left=posx+‘px‘;
elem.style.top=posy+‘px‘;
var repeat = "moveElement(‘"+elementID+"‘,"+posx1+","+pos+","+interval+")";
moveTime=setTimeout(repeat,interval)
}
function postionMessage1(){
if(!document.getElementById)return false;
if(!document.getElementById(‘message‘))return false;
var elem=document.getElementById(‘message‘);
elem.style.position=‘absolute‘;
elem.style.left=‘50px‘;
elem.style.top=‘100px‘;
moveElement(‘message‘,200,100,10)


}
addLoadEvent(postionMessage1);

实用的动画

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Web Design</title>
<style type="text/css" media="screen">
@import url(styles/layout.css);
</style>
<script type="text/javascript" src="scripts/addLoadEvent.js">
</script>
<script type="text/javascript" src="scripts/moveElement.js">
</script>
<script type="text/javascript" src="scripts/prepareSlideshow.js">
</script>
</head>
<body>
<h1>Web Design</h1>
<p>These are the things you should know.</p>
<ol id="linklist">
<li>
<a href="structure.html">Structure</a>
</li>
<li>
<a href="presentation.html">Presentation</a>
</li>
<li>
<a href="behavior.html">Behavior</a>
</li>
</ol>
<div id="slideshow">
<img src="topics.gif" alt="building blocks of web design" id="preview" />
</div>
</body>
</html>

js

function prepareSlideshow() {
// Make sure the browser understands the DOM methods
if (!document.getElementsByTagName) return false;
if (!document.getElementById) return false;
// Make sure the elements exist
if (!document.getElementById("linklist")) return false;
if (!document.getElementById("preview")) return false;
// Apply styles to the preview image
var preview = document.getElementById("preview");
preview.style.position = "absolute";
preview.style.left = "0px";
preview.style.top = "0px";
// Get all the links in the list
var list = document.getElementById("linklist");
var links = list.getElementsByTagName("a");
// Attach the animation behavior to the mouseover event
links[0].onmouseover = function() {
moveElement("preview",-100,0,10);
}
links[1].onmouseover = function() {
moveElement("preview",-200,0,10);
}
links[2].onmouseover = function() {
moveElement("preview",-300,0,10);
}
}
addLoadEvent(prepareSlideshow);

 

 

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);
}
var xpos = parseInt(elem.style.left);
var ypos = parseInt(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+")";
elem.movement = setTimeout(repeat,interval);
}

#slideshow {
width: 100px;
height: 100px;
position: relative;
overflow: hidden;
}

 

技术分享



变量作用域问题
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);
}
var xpos = parseInt(elem.style.left);
var ypos = parseInt(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+")";
elem.movement = setTimeout(repeat,interval);
这边出现了一个问题:小女孩用户殷鼠标悬停在某个链接上,不管上一次,调用是否已经把图片移动到位,moveElement函数都会调用,如果用户移动速度快,setTimeout队列里面的事件就会导致导致动画效果产生滞后,为了消除这个问题,通过clearTimeout(movement)方式
elem.movement = setTimeout(repeat,interval);它如果变成了局部变量,clearTimeout()函数将无法被调用,因为局部变量movement在clearTimeout函数的上下文里面不存在 
,也就是说,它即不能是全局,也不能是局部变量
我们通过dom方式来解决这个问题
elem.attr=value

改进动画效果
xpos是被移动元素当前左位置,变量findal_x目的地左位置,
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);
}
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+=dist
/*
* xpos是被移动元素当前左位置,final_x是这个元素的目的地左位置,当
* xpos小于findl_x是,xpos+1,也就是说,不管那个元素与它的目的地距离多远,每次只前进一个像素
* 第1:我们需要算出元素与它的目的地之间的距离,如果xpos小于final_x,就可以知道多少,所以只要
* (final_x-xpos)/10
* 如果2者之间相差100px,那么他们的值将相加10px,通过Main.ceii(num)语法来解决这个问题
* */
}
if (xpos > final_x) {
dist=Math.ceil((xpos-final_x)/10)
xpos-=dist
}
if (ypos < final_y) {
dist=Math.ceil((final_y-ypos)/10)
ypos+=dist
}
if (ypos > final_y) {
dist=Math.ceil((ypos-final_y)/10)
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);

}

添加安全检查
var xpos = parseInt(elem.style.left);
var ypos = parseInt(elem.style.top);
,如果elem元素left或者top属性未被设置时,解决如下
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);
}
//如果未设置left,top属性,解决如下
第2种:将它们进行默认值的设置,都设置为0px
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+=dist
/*
* xpos是被移动元素当前左位置,final_x是这个元素的目的地左位置,当
* xpos小于findl_x是,xpos+1,也就是说,不管那个元素与它的目的地距离多远,每次只前进一个像素
* 第1:我们需要算出元素与它的目的地之间的距离,如果xpos小于final_x,就可以知道多少,所以只要
* (final_x-xpos)/10
* 如果2者之间相差100px,那么他们的值将相加10px,通过Main.ceii(num)语法来解决这个问题
* */
}
if (xpos > final_x) {
dist=Math.ceil((xpos-final_x)/10)
xpos-=dist
}
if (ypos < final_y) {
dist=Math.ceil((final_y-ypos)/10)
ypos+=dist
}
if (ypos > final_y) {
dist=Math.ceil((ypos-final_y)/10)
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);

}
为了所说的安全措施之后,不用再确定设置preview元素的出生点位置,所以将
preview.style.left=0px与style.top=0px删除


生成html标记
<div id="slideshow">
<img src="topics.gif" alt="building blocks of web design" id="preview" />
</div>

function prepareSlideshow() {
// Make sure the browser understands the DOM methods
if (!document.getElementsByTagName) return false;
if (!document.getElementById) return false;
// Make sure the elements exist
if (!document.getElementById("linklist")) return false;
var slideshow = document.createElement("div");
slideshow.setAttribute("id","slideshow");
var preview = document.createElement("img");
preview.setAttribute("src","topics.gif");
preview.setAttribute("alt","building blocks of web design");
preview.setAttribute("id","preview");
slideshow.appendChild(preview);
var list = document.getElementById("linklist");
insertAfter(slideshow,list);
// Get all the links in the list
var links = list.getElementsByTagName("a");
// Attach the animation behavior to the mouseover event
links[0].onmouseover = function() {
moveElement("preview",-100,0,10);
}
links[1].onmouseover = function() {
moveElement("preview",-200,0,10);
}
links[2].onmouseover = function() {
moveElement("preview",-300,0,10);
}
}
addLoadEvent(prepareSlideshow);



function insertAfter(newElement,targetElement) {
var parent = targetElement.parentNode;
if (parent.lastChild == targetElement) {
parent.appendChild(newElement);
} else {
parent.insertBefore(newElement,targetElement.nextSibling);
}
}




/*这是注释*/
//单行注释
var a=1;
var b=0;
var c=a+b;
if(a>b){
a+b;
}
if(a>b)
a+b;
var a=‘str1‘;
var a=‘0.05‘;
var a=Array();
var a=[1,2,3,4]
var a={1:12,2:{3:4}};
var a=‘str1‘;
//typeof:用于检测给定给变量的数据类型
/*
* undefined:未定义;
* boolean:布尔值
* string:字符串
* number:数值
* object:对象或者null
* function:函数*/
//alert(‘字符串‘+‘:‘+typeof a);
//a=1;
//alert(‘数字‘+‘:‘+typeof a);
//alert(‘对象‘+‘:‘+typeof []);
//alert(‘未定义‘+‘:‘+typeof abc);
//alert(‘Null‘+‘:‘+typeof null);//它是一个空的对象引用
//undefined:未定义
var abc1;
//alert(abc1==undefined);//true

//null它表示一个空对象指针,即object
//alert(typeof null)
//undefined它派生于null的对象
//alert(null==undefined);//true
//说明:只要在保存对象的变量还没有真正保存对象时,这样才是null,
//boolean:布尔(true and false)
//alert(‘:‘+Boolean(‘str1‘))//true
//number:数值
//判断数值范围:isFinite(obj):如果需要判断数值是否是有穷大时
result=Number.MAX_VALUE+Number.MAX_VALUE;
//alert(‘数值范围是‘+‘:‘+isFinite(result));//false
//infinity:无穷大
//NaN:非数值,用于表示一个本来要返回数值操作数未返回数值的情况
/*NaN有特点:任何涉及nan操作都会返回nan,其次它与任何值都不相等,包括nan本身*/
//alert(NaN==NaN)false
//nan有一个函数用于判断它的:isNan()函数,这个函数还可以接受一个参数,这个参数可以是任何类型,作用:是帮我们确定这个参数是否不是数值
//alert(‘开始‘);
//alert(isNaN(NaN));//true
//alert(isNaN(10));//false
//alert(isNaN(‘10‘));//false
//alert(isNaN(‘abc‘));//true
//alert(isNaN(1.2));//false
//在使用这个isnan()函数时,它会首先调用对象的valuesOf()方法,然后确定该方法返回的值是否可以转换为数值,如果不能,则再调用toString()方法,再进行测试
//数值转换
/*
* Number(),parseInt,parseFloat()
* Number()转换规则
* 如果是booleantrue,false(转换为10)
* 如果是数值:简单的传入和返回
* 如果是null,则返回0
* 如果是undefined,返回NaN
* 如果是字符串,按照下面的规则
* 如果字符串中呐包含了数值(包括前面带+或者-),则转换为十进制数值,注意:前导的零会被忽略
* 如果字符串中包含有效的浮点格式。则把其转换为对应的浮点数值(与上一条,注意一样);
* 如果字符串中包含了16进制,则转换为相同大小的十进制整数值* 如果字符串为空,则转换为0* 如果字符串除了上面的情况之外,则返回NaN* 如果是对象,则调用valueOf()方法,然后根据前面的规则进行以转换,如果转换为nan,则调用tostring(),然后再根据上面的规则进行转换*///例如num1=Number(‘hello world!‘);num2=Number(‘‘);num3=Number(‘00000111‘);num4=Number(true);//alert(num1);NaN//alert(num2);0//alert(num3);111,如果前面有0的情况下,会把0忽略掉//alert(num4);1//parseInt()函数在转换字符串,看其是否符合数值,它会忽略字符串前面的空格,直到找到第一个非空格字符//如果第一个字符不是数字或者负号时,就会返回nan,也就是说:它转换的字符会返回nan(Number()对空字符返回0),如果第一个字符串是数字,它将继续解析第二个,直到解析完所有后续字符或者遇到一个非数字字符,如果遇到小数(22.5),它将返回22,因为小数点并不是有效数字字符;//十六(8)进制也能够被paseInt()识别,如果字符串以0x开关且后面跟着是数字字符,就会解析为16进制整数,八进制和16进制原理一样//num1=parseInt(‘123abc‘)//123//num2=parseInt(‘‘)Nan//num3=parseInt(‘0xA‘)十六进制//num4=parseInt(22.5)22//num5=parseInt(‘070‘)56八进制//num6=parseInt(‘70‘)70十进制//num7=parseInt(‘0xf‘)15十六进制//parseInt(),它提供了第二个参数:转换时使用基数(多少进制)如下//parseInt(‘0xAF‘,16)这样表示指定基数为16进制,如果指定了基数之后,前面的0x可以省略如下//parseInt(‘AF‘,16)//parseFloat()它的功能与parseInt()类似,但是有一个区别是,它与parseInt(),如果遇到2.3.5这样的情况下,parFloat()它将把第二个小数点忽略掉,返回2.3,它的第二个区别是始终会忽略2毅力的0,它可以识别前面讨论过浮点数值格式,也包括十进制,它只对十进制解析,所以它没有第二个参数指定用法,最后//如果字符串包含的是一个可解析为整数的数(无小数点,或者小数点后为0),它将返回整数//stringvar a=‘123‘;var b="123";var c=‘123\nabc‘;var d=a+b;//连接b+=a;//这样也可以连接//转换为字符串,//age=11;//age=age.toString();//alert(‘str:‘+age);////tostring()大部分情况下不用传入参数,但是在调用数值时,可以转换一个基数参数,它可以输出二进制等,如下//age=10//alert(age.toString());//alert(age.toString(2));//二进制 返回1010//转换为string规则//如果值为tostring()时,调用该方法(无参数)并返回相应的结果//如果是null,则返回‘null‘,如果是undefined,则返回‘undefined‘//object它是一级数据和功能的集合,可以通过执行new操作符后要创建对象的名称来创建,而创建object类型的实例并为添加 添加属性和方法,如下a=new Object()//如果不给构造函数传递参数时,则可以省略后面的圆括号,有下面的属性,如下/** constructor:保存用于创建当前对象hasOwnProperty(Name)用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在,参数的属性名Name必须以字符串形式指定* propertyInEnumerable(Name)用于给定的属性是否能够使用for in循环与hasOwnProperty(Name)一样* isPrototypeof(object):检查传入的对象是否是传入对象的原型* toLocalestring()返回对象字符串,该字符串与执行环境地区对应* tostring()返回对象字符串表示* valueof()返回对象的字符串,数值,布尔与tostring()返回相同*/

操作符
包括:算术运算符,位操作符,关系运算符,相等操作

一元操作符
递增和递减操作符(++,--)


var abc=2; alert(++abc);
++i表示使用前置递增操作符给一个数值加1时,要把++放变量名前
abc=abc+1
alert(--abc);
--i与++i一样的道理
例如:
var abc=99; 
var def=++abc-1;
alert(abc);//100
alert(def);//99

i++它是语句执行后才运行
var abc=21; abc=-2+abc++; alert(abc)
i++和++i的规则(适用于整形,字符串,布尔,浮点和对象)
在应用于一个包含有效数字字符的字符串时,先将其转换为数值,再执行加减1的保管,字符串变量变成数值变量
在应用于一个不包含有效数字字符的字符串,将其变量设置nan,字符串变量变成数值变量
在应用于false,true先转换为0/1再执行加减1的操作,布尔变量变成数值变量
在应用于对象时,先调用对象的valueof()以取得一个可供操作的值,然后对该值应用前述规则,如果为nan,则再调用tostring()方法再应用前述规则,对象变量变成数值变量

例如
var s1=‘2‘;
var s2=‘z‘;
var b=false;
var f=1.1;
var o={valueOf:function(){
   return -1
}};
alert(++s1);//3
alert(++s2);//nan
alert(++b);//1
alert(--f);//0.1000000000000000000009
alert(--o);//-2
//在对非数值应用 一元加减操作符时,这样的操作符会像number()转型函数一样对这个值执行转换,也就是说,false, true会被转换为0,1字符串转换的规则与前面一样 
//例子

//一元加减操作符 var num=25; num+=num; alert(num);//50 var n1=25; n1=+n1; alert(n1);//25
var s1=‘01‘,s2=‘1.1‘,s3=‘z‘,b=false,f=1.1,o={valueOf:function(){return -1}}; 
s1=+s1; alert(s1);//1 s2=+s2; alert(s2);//1.1 s3=+s3; alert(s3);//nan b=+b; alert(b);//0 f=+f; alert(f);//1.1 o=+o; alert(o);//-1
一元操作符主要应用表示负数,一些规则与前面的类似
var s1=‘01‘,s2=‘1.1‘,s3=‘z‘,b=false,f=1.1,o={valueOf:function(){return -1}}; 
s1=-s1; alert(s1);//-1 s2=-s2; alert(s2);//-1.1 s3=-s3; alert(s3);//nan b=-b; alert(b);//0 f=-f; alert(f);//-1.1 o=-o; alert(o);//1

位操作符(所有语言通用)
如果是64位的,要先转换为32位整数,然后执行之后 再转回64位
对于有符号的整数,32位中的前31位用于表示整数,第32位表示符号,0表示整数,1表示负数
没有用于用0填充
比如10010
2**4*1+2**3*0+2**2*0+2**1*1+2**0*0
补码步骤
  求这个数值的绝对值(-18的绝对值是18)
  求二进制的反码,即0替换为1,1替换0
  得到二进制反码加1
例如
00000110011
转反码11111001100
加11111001101
----
在以二进制字符串形式输出一个负数时,会看到这个负数绝对值的二进制剪辑加上了一个负号,如下
num=-18; alert(num.toString(2));//-10010
"""
注意,在js中默认情况下都是有符号整数,当然也存在无符号整数,对于无符号整数来说,第32位不再表示符号,因为无符号整数只能是整数,而且无符号整数的值可以是更大,因为多出一位不再表示符号,可以用来表示数值

"""
负数和正数一样都是以二进制存储的

//~:not(取得反码) 
var n1=25;//(如果前面都是0,我以6位表示:011001) var n2=~n1;//(100110) alert(n2);//-26
//& and 2个操作符表示
/*第1数值位    第2数值位    第3数值位
    1           1           1
    1           0           0
    0           1           0
    0           0           0
* */
//and操作只在两个数值对应位都是1时才返回1,任何一位是0的,都返回结果为0
//例子
result1=25;
result2=3;
alert(result1&result2);//11
result1=25;
result2=0;
alert(result1&result2);//0
result1=25;
result2=-1;
alert(result1&result2);//25
//如果(只有2位进行and操作时)那么将返回result1这个变量的值
//| or(与and操作类似)
/*第1数值位    第2数值位    第3数值位
    1           1           1
    1           0           1
    0           1           1
    0           0           0
* */
result1=25;
result2=3;
alert(result1|result2);//27
result1=25;
result2=0;
alert(result1|result2);//25
result1=25;
result2=-1;
alert(result1|result2);//25

技术分享

//左移(<<)将数值所有位向左移指定的位数 alert(2<<5);//二进制:1000000,十进制:64


//有符号的右移(>>)向右移动,保留符号位,与左移相反,如下 alert(64>>5);//2 //无符号右移(>>>)将所有32位向右移动,对正数来说,它与有符号右移一样, alert(64>>>5);//2 //但是对于负数来说,首先,无符号右移是以0来填充的,而不是像有符号右移那样以符号位值来填充空位的,所以对正数的符号右移与有符号右移结果相同,但对负数结果就不一样了 //其次,无符号右移操作会把负数的二进制当成正数的二进制,而且由于负数以其绝对值二进制补码形式表示,因此就会导致无符号右移后结果非常之大,如下 alert(-64>>>5);//134217726 //-64位的补码是:1111111111111111111111100000



逻辑操作符

非(!)
a=1
1!a
alert(!1);
alert(![]);//false
alert(![1]);//false
alert(!‘‘.toString());
alert(!new Object() );
它的规则
如果是一个对象,非空字符串,任意非0数值(包括infinity),返回fasle
如果是一个空字符串,null,nan,返回true
逻辑非操作符也可以用于将一个值转换为与其对应的布尔值,而同时使用2个逻辑非操作符,就会模拟boolean()转型函数行为,其中第一个逻辑非操作会基于无论什么操作数返回布尔,第二个逻辑非则对该布尔求反,于是就得到这个值的真正对应的布尔值,它与boolean()函数相同,如下
alert(!!‘blue‘)//trye
alert(!!0)//false
与(&&)
result=true&&false
技术分享技术分享这样就会打印false
或(||)
技术分享

var a=false;

var result=(a||soub)//出现错误

alert(result)


可以利用逻辑或者这种情况来避免变量为null或者undefined,如下

var myobjects=proeffedObject+backupObject;

变量myobject将被赋予等号后面2个值中的
一个,变量proeffedObject中包含优先付给变量myobject,变量backupobject中不包含有效值的情况下提供后备值,如果proeffedobject值不是null,那么它的值赋值给myobject,如果是null,则将后面的backobject的值赋值给myobject
乘法操作符
//乘法(*)

alert(1*2)

技术分享

除法(/)

alert(1/0.2)

技术分享

 

求模(%)

alert(1%2)

技术分享




加法操作符
(与python里面的操作类似)

alert(1+1)

如果一个数是nan,则返回nan

如果infinity加infinity,则结果infinity

如果-infinity加-infinity,则结果-infinity

如果infinity加-infinity,则返回nan

//对于字符串(+):拼接,如下

 

s=‘abc‘; s=s+‘def‘; alert(s);

如果undefined和null,它分别调用String()函数

如果一个数值与一个字符串相加,如下

s=1

s2=‘1‘

s3=s+s2

打印‘11‘

注意

a=1

b=2

c=‘str1 和2‘+1+2

str1和212

这样是错误的

正确的写法

a=1

b=2

c=‘str1 和2‘+(1+2)

str1和23

减法

alert(2-1)

技术分享

关系操作符

< > <= >=

5<3  5>=3

规则

如果2个操作数都是数值,执行数值比较

如果2个操作数都是字符串,则比较2个字符串对应的编码值

如果一个是数值,别一个操作数转换为一个数值,然后再进行比较

如果一个操作数是对象,则调用对象的valueOf(),然后使用前面的规则执行,如果对象没有valueOf(),再调用toString()

如果一个操作数是对象,先转换为数值,再进行比较

如下

‘Abcd‘<‘abcd‘

a=97,A=65

所以返回true

通过一个方法可以把大小写转换成大小写

str.toLowerCase)

还有当数值比较,如下

‘23‘<‘3‘//false,字符串23会转换成23,然后再和3进行比较

不合理的方法

‘a‘<3;//返回nan

相等操作符

(==)如果2个操作数相同,返回true,(!=)如果2个操作数不同,则返回true

规则

如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值--false转换为0,true转换为1

如果一个操作数是字符串,另一个操作数是数值,在比较相等之前先将字符串转换为数值

如果一个操作数是对象,另一个操作数不是,则调用对象的valueOfA(),用得到基本类型值按照前面的规则进行比较

这2个操作符在比较时则遵守下列规则

null与undefined是相等的

在比较之前,不能将null与undefined转换其他任何值

如果有一个操作符nan,则相等操作返回false,而不相等则返回true

即使2个操作数都是nan,相等操作符返回false,nan不等于nan

如果2个操作符都是对象,则比较它们是不是同一个对象,如果是则true,否则false

 

下面一些特殊情况

null==undefined,NaN!=NaN,false==0//true 
‘NaN‘==NaN,5==NaN,NaN==NaN//false
true==1,‘5‘==5;//true true==2,
undefined==0,null==0//false
全等,不全等
(===)
(‘55‘==55)//转换后相等
(‘55‘===)//因为不同的数据类型不相等

条件表达式,语法
exr?true:false
例子
(num1>num2)?num1+1:num2-1
意思 :if num1>num2:返回num1+1,否则返回num2-1
赋值表达式
var num=10,
num=num+20
简写方式
num+=20
其他方式*= /=
逗号操作符
var n1=1,n2=2,n3=3;

语句体
if语句
语法
if(exr){
  pass}
else if(exr){
  pass}
else{
  pass}
do-while语法
作用:即只有在循环体内代码执行之后,才会测试出条件
也就是说,在对表达式测试之前,循环体内代码至少会执行一次
do{
  pass}while(exr){
        pass}
while属于前测试循环语句,也就是说,在循环体内代码被执行之前,就会对出口条件求值,如下

while (exr){pass}

for语法
for(var i=0;i<list.len;i++){
  }
for的无限循环语法
for(;;){
}
把while转换成for方式
count=10;

var i=0
for(;i<count;){

  i++}

for-in语法
for(var i in exr){
这个方式和python}

label语法,如下(作用:可以在代码中添加标签!)
label:statement
如下
str1:for(var i=0;i<count;i++){
  alert(i)}
break与continue语法(这2个作用所有语言都一样的,使用在for,while下面)

with语法(作用:将代码作用域设置到一个特定的对象中)
with(exr){
  pass}
switch语法
switch(exr){
  case value:statement;
    break
  default:statement  
  }

函数
function function1(){
  }
function function(a,b){
    return a+b}

 

 

 

 

 

 

 

 


 
































javascript dom编程艺术 第2版

标签:

原文地址:http://www.cnblogs.com/mhxy13867806343/p/4539327.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!