动态创建标记+css_dom+js动态效果

【7】动态创建标记
【7.1】一些传统方法
【7.1.1】document.write方法,不推荐使用


(1)
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title>Testing</title>
</head>
<body>
<script>
	document.write("<p>this is inserted.</p>");
</script>
</body>
</html>
【7.1.2】innerHTML 属性:可以用来读写某给定元素里的html内容; 


(2)
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title>Testing</title>
</head>
<script type="text/javascript" src="example.js">
</script>
<body>
<div id="testdiv">
	<p>this is <em>my</em> content. </p>
</div>
</body>
</html>
window.onload = function() {
  var para = document.createElement("p");
  var testdiv = document.getElementById("testdiv");
  alert(testdiv.innerHTML);
  testdiv.appendChild(para);
  var txt = document.createTextNode("Hello world");
  para.appendChild(txt);
}
【7.2】dom方法
【7.2.1】createElement 方法:创建一个元素节点;

var para = document.createElement("p");
【荔枝】查看上面<p>元素的 nodeType 和 nodeName值;
window.onload = function() {
var para = document.createElement("p");
var info = "nodeName: ";
info += para.nodeName;
info += ", nodeType:";
info += para.nodeType;
alert(info);
}

(3)


【7.2.2】appendChild方法

1)parent.appendChild(child); 让child元素成为  parent元素节点的子元素;

【7.2.3】createTextNode方法:创建文本节点
1)荔枝:
var text = document.createTextNode("hello world.");

(4)
window.onload = function() {
  var para = document.createElement("p");
  var testdiv = document.getElementById("testdiv");
  alert(testdiv.innerHTML);
  // appendChild方法添加para为testdiv的子元素;
  testdiv.appendChild(para);
  // createTextNode方法:创建文本节点
  var txt = document.createTextNode("Hello world");
  para.appendChild(txt);
}
【7.2.4】一个更复杂的组合
1)利用js生成<p>元素, 且元素内容为 this is my content.

(5)
window.onload = function() {
	// 利用js生成<p>元素,
	// 且元素内容为 this is my content.
	var para = document.createElement("p");
	var t1 = document.createTextNode("this is");
	var em = document.createElement("em");
	var t2 = document.createTextNode("my");
	var t3 = document.createTextNode("content. ");
	
	para.appendChild(t1);
	em.appendChild(t2);
	para.appendChild(em);
	para.appendChild(t3);
	var testdiv = document.getElementById("testdiv");
	testdiv.appendChild(para);
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title>Testing</title>
</head>
<script type="text/javascript" src="example3.js">
</script>
<body>
<div id="testdiv">
</div>
</body>
</html>
【7.3】重回图片库
【7.3.1】在已有元素前面插入一个新元素

parent.insertBefore(newElement, targetElement);
【7.3.2】在已有元素后面插入一个新元素
没有insertAfter, 自定义的insertAfter如下;
function insertAfter(newElement, target) {
var parent = target.parentNode;
if (parent.lastChild == target ){
parent.appendChild(newElement);
} else {
parent.insertBefore(newElement, target.nextSibling);
}
}
【7.3.3】图片库二次改进版
1)有5个函数,如下:

addLoadEvent;
insertAfter;
preparePlaceholder;
prepareGallery;
showPic;
function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      oldonload();
      func();
    }
  }
}

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

function preparePlaceholder() {
  if (!document.createElement) return false;
  if (!document.createTextNode) return false;
  if (!document.getElementById) return false;
  if (!document.getElementById("imagegallery")) return false;
  var placeholder = document.createElement("img");
  placeholder.setAttribute("id","placeholder");
  placeholder.setAttribute("src","images/placeholder.gif");
  placeholder.setAttribute("alt","my image gallery");
  var description = document.createElement("p");
  description.setAttribute("id","description");
  var desctext = document.createTextNode("Choose an image");
  description.appendChild(desctext);
  var gallery = document.getElementById("imagegallery");
  insertAfter(placeholder,gallery);
  insertAfter(description,placeholder);
}

function prepareGallery() {
  if (!document.getElementsByTagName) return false;
  if (!document.getElementById) return false;
  if (!document.getElementById("imagegallery")) return false;
  var gallery = document.getElementById("imagegallery");
  var links = gallery.getElementsByTagName("a");
  for ( var i=0; i < links.length; i++) {
    links[i].onclick = function() {
      return showPic(this);
	}
    links[i].onkeypress = links[i].onclick;
  }
}

function showPic(whichpic) {
  if (!document.getElementById("placeholder")) return true;
  var source = whichpic.getAttribute("href");
  var placeholder = document.getElementById("placeholder");
  placeholder.setAttribute("src",source);
  if (!document.getElementById("description")) return false;
  if (whichpic.getAttribute("title")) {
    var text = whichpic.getAttribute("title");
  } else {
    var text = "";
  }
  var description = document.getElementById("description");
  if (description.firstChild.nodeType == 3) {
    description.firstChild.nodeValue = text;
  }
  return false;
}
addLoadEvent(preparePlaceholder);
addLoadEvent(prepareGallery);
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title>Image Gallery</title>
  <script type="text/javascript" src="scripts/showPic.js"></script>
  <link rel="stylesheet" href="styles/layout.css" type="text/css" media="screen" />
</head>
<body>
  <h1>Snapshots</h1>
  <ul id="imagegallery">
    <li>
      <a href="images/fireworks.jpg" title="A fireworks display">
        <img src="images/thumbnail_fireworks.jpg" alt="Fireworks" />
      </a>
    </li>
    <li>
      <a href="images/coffee.jpg" title="A cup of black coffee" >
        <img src="images/thumbnail_coffee.jpg" alt="Coffee" />
      </a>
    </li>
    <li>
      <a href="images/rose.jpg" title="A red, red rose">
        <img src="images/thumbnail_rose.jpg" alt="Rose" />
      </a>
    </li>
    <li>
      <a href="images/bigben.jpg" title="The famous clock">
        <img src="images/thumbnail_bigben.jpg" alt="Big Ben" />
      </a>
    </li>
  </ul>
</body>
</html>

(6)
【7.4】ajax
1)ajax的主要优势:
对页面的请求以异步方式发送到服务器; 而服务器不会用整个页面来响应请求,它会在后台处理请求, 与此同时用户还能继续浏览页面并与页面交互;

【7.4.1】XMLHttpRequest对象
1)ajax的核心是 XMLHttpRequest对象。
这个对象充当着浏览器中的脚本(客户端)与服务器之间的中间人的角色。
2)以往的请求都由浏览器发出,而javascript通过这个对象可以自己发送请求,同时也自己处理响应;

【荔枝】如何发送ajax请求;
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title>ajax</title>
</head>
<body>
	<div id="new"></div>
	<script src="scripts/ajax.js"></script>
</body>
</html>
function getHttpObject() {
	if (typeof XMLHttpRequest == "undefined") {
		 // 定义XMLHttpRequest函数 ,返回 ActiveXObject对象
		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;
		}
	}
	// 返回XMLHttpRequest实例
	return new XMLHttpRequest();
}

// 在 document加载完毕后,执行addLoadEvent函数,
// 以绑定 func函数作为document加载完毕后,浏览器加载的函数;
function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      oldonload();
      func();
    }
  }
}

function getNewContent() {
	var request = getHttpObject();
	if (request) {
		request.opne("GET", "example.txt", true);
		request.onreadystatechange = function() {
			if (request.readyState == 4) {
				var para = document.createElement("p");
				var text = document.createTextNode(request.responseText);
				para.appendChild(text);
				document.getElementById("new").appendChild(para);
			}
		};
		request.send(null);
	} else {
		alert("sorry, your browser does not support XMLHttpRequest.");
	}
}
addLoadEvent(getNewContent);
【分析】
  • 分析1) 代码中的    onreadystatechange    是一个事件处理函数, 它会在服务器给 XMLHttpRequest 对象送回响应的时候被触发执行;  
  • 分析2) 在指定了请求目标,也明确如何处理响应后,就可以用send方法来发送请求了;
  • request.send(null);
  • 分析3) readyState属性的值有5个:
0 表示未初始化;
1表示正在加载;
2表示加载完毕;
3表示正在交互;
4表示完成;
  • 分析4)服务器发送回来的数据通过两个属性来完成, responseText属性 ,该属性用于保存文本字符串形式的数据; responseXML属性用于保存  Content-Type 头部中指定为 text/xml 的数据;
【注意】 在使用 ajax时,千万注意同源策略。使用 XMLHttpRequest对象发送的请求只能访问与其所在的html处于同一个域中的数据,不能向其他域发送请求;


【8】充实文档的内容

【8.4】显示缩略语列表
【8.4.1】编写 displayAbbreviations 函数

1) dl, dt, dd 分别表示定义列表,定义标题,定义描述;其中定义列表是表现缩略语及其解释的理想结构;
definition list, definition title, definition description

<dl>
    <dt>w3c</dt>
    <dd>world wide web.</dd>
    <dt>dom</dt>
    <dd>document objecty model. </dd>
</dl>


2)利用js动态创建 dl, dt, dd


(1)
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>Explaining the Document Object Model</title>
    <link rel="stylesheet" type="text/css" media="screen" href="styles/typography.css" />
    <script type="text/javascript" src="scripts/addLoadEvent.js"></script>
    <script type="text/javascript" src="scripts/displayAbbreviations.js"></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>
  </body>
</html>
function displayAbbreviations() {
// 检查浏览器兼容性问题
  if (!document.getElementsByTagName || !document.createElement || !document.createTextNode) return false;
// 获取所有缩略语
  var abbreviations = document.getElementsByTagName("abbr");
  if (abbreviations.length < 1) return false;
  var defs = new Array();
// 遍历缩略语
  for (var i=0; i<abbreviations.length; i++) {
    var current_abbr = abbreviations[i];
    if (current_abbr.childNodes.length < 1) continue;
    var definition = current_abbr.getAttribute("title");
    var key = current_abbr.lastChild.nodeValue;
    defs[key] = definition; // 用于存储缩略语标题的数组
  }
// 创建定义列表
  var dlist = document.createElement("dl");
// 遍历数组
  for (key in defs) {
    var definition = defs[key];
// 创建定义标题
    var dtitle = document.createElement("dt");
    var dtitle_text = document.createTextNode(key);
    dtitle.appendChild(dtitle_text);
// 创建定义描述
    var ddesc = document.createElement("dd");
    var ddesc_text = document.createTextNode(definition);
    ddesc.appendChild(ddesc_text);
// 添加主题到定义列表
    dlist.appendChild(dtitle); // 定义标题
    dlist.appendChild(ddesc); // 定义描述
  }
  if (dlist.childNodes.length < 1) return false;
// 创建元素节点
  var header = document.createElement("h2");
  // 创建文本节点
  var header_text = document.createTextNode("Abbreviations");
  header.appendChild(header_text);
// 添加元素节点到body
  document.body.appendChild(header);
// 添加定义列表到body
  document.body.appendChild(dlist);
}
// 使得displayAbbreviations函数在document加载完毕后就立即加载
addLoadEvent(displayAbbreviations);
【8.5】显示文献来源链接表

(2)
1)源码如下:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>Explaining the Document Object Model</title>
    <link rel="stylesheet" type="text/css" media="screen" href="styles/typography.css" />
    <script type="text/javascript" src="scripts/addLoadEvent.js"></script>
    <script type="text/javascript" src="scripts/displayAbbreviations.js"></script>
    <script type="text/javascript" src="scripts/displayCitations.js"></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.baidu.com">
      <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>
  </body>
</html>


function displayCitations() {
  if (!document.getElementsByTagName || !document.createElement || !document.createTextNode) return false;
// 获取所有的 blockquote 的元素节点
  var quotes = document.getElementsByTagName("blockquote");
// 遍历blockquote
  for (var i=0; i<quotes.length; i++) {
// 浏览器不支持cite属性,则继续;
    if (!quotes[i].hasAttribute("cite")) continue;
// store the cite attribute
    var url = quotes[i].getAttribute("cite");
// 获取 blockquote元素的所有节点
    var quoteChildren = quotes[i].getElementsByTagName('*');
// 浏览器不支持的话,则继续;
    if (quoteChildren.length < 1) continue;
// 获取blockquote元素的最后一个节点
    var elem = quoteChildren[quoteChildren.length - 1];
// 创建一个连接
    var link = document.createElement("a");
    var link_text = document.createTextNode("source");
    link.appendChild(link_text);
    link.setAttribute("href",url);
    var superscript = document.createElement("sup");
    superscript.appendChild(link);
// 把标记 superscript 添加到 blockquote元素的最后一个子节点
    elem.appendChild(superscript);
  }
}
addLoadEvent(displayCitations);
分析1)var quoteChildren = quotes[i].getElementsByTagName('*'); 把包含在当前 blockquote 元素里的所有元素节点找出来;

【8.6】显示 快捷键清单
1)accesskey 属性可以把一个元素如链接与键盘上的某个特定按键关联在一起;如 
<a href="http://www.baidu.com" accesskey="1">home</a>
2)下面利用dom技术,动态创建一份快捷键清单,如下:

(3)
【源码如下】
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>Explaining the Document Object Model</title>
    <link rel="stylesheet" type="text/css" media="screen" href="styles/typography.css" />
    <script type="text/javascript" src="scripts/addLoadEvent.js"></script>
    <script type="text/javascript" src="scripts/displayAbbreviations.js"></script>
    <script type="text/javascript" src="scripts/displayCitations.js"></script>
    <script type="text/javascript" src="scripts/displayAccesskeys.js"></script>
  </head>
  <body>
    <ul id="navigation">
      <li><a href="index.html" accesskey="1">Home</a></li>
      <li><a href="search.html" accesskey="4">Search</a></li>
      <li><a href="contact.html" accesskey="0">Contact</a></li>
    </ul>
    <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>
  </body>
</html>
function displayAccesskeys() {
  if (!document.getElementsByTagName || !document.createElement || !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") == null) continue;
// 获取 accesskey 属性值;
    var key = current_link.getAttribute("accesskey");
// 获取链接元素 <a> 的节点值;
    var text = current_link.lastChild.nodeValue;
// add them to the array
    akeys[key] = text;
  }
// 创建一个无序列表
  var list = document.createElement("ul");
// 遍历快捷键
  for (key in akeys) {
    var text = akeys[key];
//  创建一个字符串用于存储 快捷键 和 对应的链接
    var str = key + " : "+text;
// 创建一个列表项 <li>
    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);
// 添加标题到 <body> 元素
  document.body.appendChild(header);
// 添加列表到 <body> 元素
  document.body.appendChild(list);
}
addLoadEvent(displayAccesskeys);

【9】css-dom
【9.1】三位一体的网页

  • 结构层:由 html 或 xhtml的标记语言负责创建;
  • 表示层:由 css 负责完成;
  • 行为层:负责内容应该如何响应事件这一问题;这是javascript语言和dom发挥作用的领域;
【9.2】style属性
1)style属性值的数据类型为 object;
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title>style is object</title>
  
</head>
<body>
  <p id="example" style="color: grey; font-family: 'Arial',sans-serif;">
An example of a paragraph
  </p>
  <script type="text/javascript">
window.onload = function() {
  var para = document.getElementById("example");
  alert(typeof para.nodeName); // 获取节点名称的数据类型;string 类型
  alert(typeof para.style); // 获取节点style属性的数据类型;object 类型
}
  </script>
</body>
</html>
2)style属性包含元素的样式: element.style.property 来获取样式值;
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title>Example</title>
  <script type="text/javascript">
window.onload = function() {
  var para = document.getElementById("example");
  para.style.color = "black";
  para.style.font = "2em 'Times',serif";
  alert("The font family is " + para.style.fontFamily); // 获取style属性的fontFamily属性值
}
  </script>
</head>
<body>
  <p id="example" style="color: grey; font-family: 'Arial',sans-serif;">
An example of a paragraph
  </p>
</body>
</html>
【9.2.1】获取样式
1)获取 style属性的color属性; element.style.color ;
2)可以使用css速记属性,可以把多个样式组合在一起写成一行。比如,声明了 font:12px 'Arial', sans-serif, CSS font-size属性将被设置为 12px, CSS font-family 属性将被设置为 'Arial', sans-serif;


【注意】 dom style属性不能用来检索在外部CSS文件里声明的样式;

如 css 文件有如下声明,
p#example{
color: grey;
font: 12px, 'Arial', sans-serif;
}
则 document.getElementById("example").style.fontSize 等于空 或 无法获取值;

而且 把 p#example{
color: grey;
font: 12px, 'Arial', sans-serif;
}
放在 <head>元素的子元素<style>里面,dom sytle属性依然检索不到;


【注意】style对象只包含在 html代码里用 style属性声明的样式;这几乎没有作用,因为样式应该与标记分离开;(干货——style样式应该与标记分离开)


【9.2.2】设置样式
1)通过dom脚本赋值操作来更新样式:

element.style.property = value;
如 para.style.color = "green";
para.style.font = "2em 'Times', serif";

【9.3】何时应该用dom脚本设置样式
1)绝大多数情况下,应该使用 css 去设置样式,而不使用dom脚本;


【9.3.1】根据元素在节点树里的位置来设置样式

1)有3种方法:
  • 方法1)为标签元素如<p> 统一声明样式

p{

font-size: 1em;

}

  • 方法2)为class属性的所有元素统一声明样式

.className{

font-size: 1em;

}

  • 方法3)为id属性的元素单独声明样式

#idName {

font-size: 1em;

}

  • 补充方法4)为有类似属性的多个元素声明样式

input[type*="text"] {

font-size: 1em;

}

  • 补充方法5)根据元素的位置声明样式

p:first-of-type{

font-sieze: 1em;

}

2)css2 定义了很多选择器,如 :first-child, :last-child; css3定义了如 :nth-child() 和 :nth-of-type() 之类的位置选择器;

【荔枝】为 <h1> 元素的下一个元素节点添加样式类

(1)
【源码】

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html lang="en">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>Man bites dog</title>
    <script type="text/javascript" src="scripts/addLoadEvent.js"></script>
    <script type="text/javascript" src="scripts/styleHeaderSiblings.js"></script>
    <link rel="stylesheet" type="text/css" media="screen" href="styles/format.css" />
  </head>
  <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>
</html>
// 为 <h1> 元素的下一个元素节点添加样式类
function styleHeaderSiblings() {
  if (!document.getElementsByTagName) return false;
  var headers = document.getElementsByTagName("h1");
  for (var i=0; i<headers.length; i++) {
    var elem = getNextElement(headers[i].nextSibling);
	// 为elem元素添加样式类
    addClass(elem,"intro");
  }
}
// 添加元素 element 添加样式类 value
function addClass(element,value) {
  if (!element.className) {
    element.className = value;
  } else {
    element.className+= " ";
    element.className+= value;
  }
}

// 获取 node节点的下一个元素
function getNextElement(node) {
  if(node.nodeType == 1) {
	return node;
  }
  if (node.nextSibling) {
    return getNextElement(node.nextSibling);
  }
  return null;
}
addLoadEvent(styleHeaderSiblings);
【荔枝】为表格奇偶行添加斑马线效果
css3样式表定义如下:

 tr:nth-child(odd) {background-color: #ffc; }
 tr:nth-child(even) {background-color: #fff; }

(2)
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title>Cities</title>
  <link rel="stylesheet" type="text/css" media="screen" href="styles/format.css" />
  <script type="text/javascript" src="scripts/addLoadEvent.js"></script>
  <script type="text/javascript" src="scripts/stripeTables.js"></script>
  <script type="text/javascript" src="scripts/displayAbbreviations.js"></script>
  <script type="text/javascript" src="scripts/highlightRows.js"></script>
</head>
<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>
</html>
// 实现表格的奇偶行的斑马线效果
function stripeTables() {
  if (!document.getElementsByTagName) return false;
  var tables = document.getElementsByTagName("table");
  for (var i=0; i<tables.length; i++) {
    var odd = false;
    var rows = tables[i].getElementsByTagName("tr");
    for (var j=0; j<rows.length; j++) {
      if (odd == true) {
        addClass(rows[j],"odd");
        odd = false;
      } else {
        odd = true;
      }
    }
  }
}
// 为元素 element添加样式类 value
function addClass(element,value) {
  if (!element.className) {
    element.className = value;
  } else {
    newClassName = element.className;
    newClassName+= " ";
    newClassName+= value;
    element.className = newClassName;
  }
}
addLoadEvent(stripeTables);

// 鼠标停留在某行,则某行高亮
function highlightRows() {
  if(!document.getElementsByTagName) return false;
  var rows = document.getElementsByTagName("tr");
  for (var i=0; i<rows.length; i++) {
	  //鼠标进入的表格行效果
    rows[i].onmouseover = function() {
      this.style.fontWeight = "bold";
    }
	//鼠标退出的表格行效果
    rows[i].onmouseout = function() {
      this.style.fontWeight = "normal";
    }
  }
}
addLoadEvent(highlightRows);

function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      oldonload();
      func();
    }
  }
}
【9.3.3】响应事件
1)只要有可能,尽量选择css设置样式;
2)css提供的 :hover等伪class属性允许根据html元素的状态来改变样式;dom也可以使用 onmouseover来对html元素的状态变化做出响应;如:
a:hover {
color:  #c60;
}
tr: hover {
font-weight: bold;
}
【总结】如果想改变某个元素的呈现效果,使用css;如果想改变某个元素的行为,使用dom;

【9.4】className属性
1)与其使用 dom改变某个元素的样式,不如通过 js 代码去更新这个元素的class 属性;
外部css样式表,定义如下:
.intro {
font-weight:bold;
font-size:1.2em;
}
elem.setAttribute("class", "intro");
也可以使用 element.className = value 来设置;


2)可以利用字符串拼接操作,把新的class设置值追加到 className属性上去,如下:

element.className += " intro "; // intro 前面有一个空格;


3)以上内容封装到js函数,实现如下:

// 为元素 element添加样式类 value
function addClass(element,value) {
  if (!element.className) {
    element.className = value;
  } else {
    newClassName = element.className;
    newClassName+= " ";
    newClassName+= value;
    element.className = newClassName;
  }
}
【荔枝】直接改变奇数行的背景色实现斑马效果
// 实现表格的奇偶行的斑马线效果
function stripeTables() {
  if (!document.getElementsByTagName) return false;
  var tables = document.getElementsByTagName("table");
  for (var i=0; i<tables.length; i++) {
    var odd = false;
    var rows = tables[i].getElementsByTagName("tr");
    for (var j=0; j<rows.length; j++) {
      if (odd == true) {
		  // 直接改变奇数行的背景色实现斑马效果
        rows[j].style.backgroundColor = "#ffc";
        odd = false;
      } else {
        odd = true;
      }
    }
  }
}
【10】用javascript实现动画效果
【10.1】动画基础知识

1)网页元素在浏览器窗口里的位置是一种表示性信息; 位置信息通常由css负责设置;如:
element {
position: absolute;
top: 50px;
left: 100px;
}
2)下面是实现同样效果的 dom 代码:
element.style.position = "absolute";
element.style.left = "100px";
element.style.top = "50px";
3)position 属性的合法值有: static, fixed固定定位, relative相对定位 和 absolute绝对定位 四种值;
static是默认值;  http://www.w3school.com.cn/cssref/pr_class_position.asp

(1)
【10.1.2】时间
1)variable = setTImeout("function", interval) 间隔 interval 时间就调用 func 函数; interval的单位是毫秒;
2)clearTimeout(variable) 取消等待执行队列里的 function函数; 因为 variable 与 执行的函数名function 有绑定关系;
3)js 函数 parseInt 可以把字符串里的数值信息提取出来,如:
parseInt("30 steps") 返回 数值30 ;

【荔枝】不断刷新元素的位置


(2)
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title>Message</title>
  <script type="text/javascript" src="scripts/addLoadEvent.js"></script>
  <script type="text/javascript" src="scripts/positionMessage.js"></script>
  <script type="text/javascript" src="scripts/moveElement.js"></script>
</head>
<body>
  <p id="message">Whee!</p>
  <p id="message2">Whoa!</p>
</body>
</html>
// 调用位置移动函数移动文本节点位置 
function positionMessage() {
  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",125,25,20);
  if (!document.getElementById("message2")) return false;
  var elem = document.getElementById("message2");
  elem.style.position = "absolute";
  elem.style.left = "50px";
  elem.style.top = "50px";
  moveElement("message2",125,75,20);
}


// 移动元素位置的函数
function moveElement(elementID,final_x,final_y,interval) {
  if (!document.getElementById) return false;
  if (!document.getElementById(elementID)) return false;
  var elem = document.getElementById(elementID);
  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+")";
  movement = setTimeout(repeat,interval);
}


addLoadEvent(positionMessage);
【10.2】实用的动画
【10.2.3】 css

1)css的overflow属性:用来处理一个元素的尺寸超出其容器尺寸的情况;
2)overflow 有4种取值: visible, hidden, scroll, auto;
visible不裁剪溢出内容;
hidden隐藏溢出内容;
scroll 内容溢出后,有滚动条;
auto 若溢出则显示滚动条;否则不显示滚动条;

【荔枝】 使用 js 函数 moveElement 来移动 topics.gif 图片。 根据用户鼠标指针悬停在哪个链接上,我们将这个图片向左或向右移动。


(3)
#slideshow {
  width: 100px;
  height: 100px;
  position: relative;
  overflow: hidden;
}
【分析】 把position设置为 relative很重要,因为想让子图片使用绝对位置;通过使用relative, 子元素的 (0, 0) 坐标将固定在 slideshow div 的左上角;
<!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>
function prepareSlideshow() {
// 浏览器是否支持以下方法;
  if (!document.getElementsByTagName) return false;
  if (!document.getElementById) return false;
// 确保元素存在
  if (!document.getElementById("linklist")) return false;
  if (!document.getElementById("preview")) return false;
// 为元素 preview添加style 样式
  var preview = document.getElementById("preview");
  preview.style.position = "absolute";
  preview.style.left = "0px";
  preview.style.top = "0px";
// 获取元素 <ol>
  var list = document.getElementById("linklist");
  // 获取所有链接 <a>
  var links = list.getElementsByTagName("a");
// 绑定动画效果到链接
  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);

【10.2.5】 变量作用域问题

1)使用 js 函数 moveElement 来移动 topics.gif 图片。 根据用户鼠标指针悬停在哪个链接上,我们将这个图片向左或向右移动。
2)如果用户移动鼠标的速度够快,积累在 setTimeout队列里的事件就会导致动画效果产生滞后。为了消除动画滞后的现象,可以用  clearTimeout  函数清除积累在 setTimeout队列里的事件:
clearTimeout(movement); 

(4)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title>Message</title>
  <script type="text/javascript" src="scripts/addLoadEvent.js"></script>
  <script type="text/javascript" src="scripts/positionMessage.js"></script>
  <script type="text/javascript" src="scripts/moveElement.js"></script>
</head>
<body>
  <p id="message">Whee!</p>
  <p id="message2">Whoa!</p>
</body>
</html> 
// 调用位置移动函数移动文本节点位置 
function positionMessage() {
  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",125,25,20);
  if (!document.getElementById("message2")) return false;
  var elem = document.getElementById("message2");
  elem.style.position = "absolute";
  elem.style.left = "50px";
  elem.style.top = "50px";
  moveElement("message2",125,75,20);
}
// 移动元素位置的函数
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 函数清除积累在 setTimeout 队列里的事件
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+")";
  movement = setTimeout(repeat,interval);
}


// document加载完毕后,调用 window.onload 函数;
// 即把func函数加入了 onload加载函数列表中;
function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      oldonload();
      func();
    }
  }
}

addLoadEvent(positionMessage);
【10.2.6】通过js生成html标记来改进动画效果
1)以上的荔枝每次都仅移动一个像素,为了增加趣味性,可以移动多个像素,实现如下:
【经典代码如下】 dist 就是 每次移动的像素值;


if (xpos < final_x) {
    var dist = Math.ceil((final_x - xpos)/10);
    xpos = xpos + dist;
  }
  if (xpos > final_x) {
    var dist = Math.ceil((xpos - final_x)/10);
    xpos = xpos - dist;
  }
  if (ypos < final_y) {
    var dist = Math.ceil((final_y - ypos)/10);
    ypos = ypos + dist;
  }
  if (ypos > final_y) {
    var dist = Math.ceil((ypos - final_y)/10);
    ypos = ypos - dist;
  }

(5)

#slideshow {
  width: 100px;
  height: 100px;
  position: relative;
  overflow: hidden;
}
#preview {
  position: absolute;
}
<!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/insertAfter.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>
</body>
</html>
// 元素移动函数
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);
  if (xpos == final_x && ypos == final_y) {
    return true;
  }
  if (xpos < final_x) {
    var dist = Math.ceil((final_x - xpos)/10);
    xpos = xpos + dist;
  }
  if (xpos > final_x) {
    var dist = Math.ceil((xpos - final_x)/10);
    xpos = xpos - dist;
  }
  if (ypos < final_y) {
    var dist = Math.ceil((final_y - ypos)/10);
    ypos = ypos + dist;
  }
  if (ypos > final_y) {
    var 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);
}


// 绑定鼠标覆盖链接的响应事件
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);


// 在 targetElement 元素后面插入新元素 newElement
function insertAfter(newElement,targetElement) {
  var parent = targetElement.parentNode;
  if (parent.lastChild == targetElement) {
    parent.appendChild(newElement);
  } else {
    parent.insertBefore(newElement,targetElement.nextSibling);
  }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值