Javascript学习笔记 for 《javascript_DOM编程艺术》
😼 Basic Syntax
- 程序语言分解释型语言与编译型语言两种,前者只需有解释器(对Javascript代码来说是浏览器),后者要有编译器。
- js是一种基于对象的语言,而不是面向对象的语言。
- 语句:js脚本由一系列指令构成,这些指令叫语句,每条语句后加分号。
- 注释: 多行 / / 单行 <!-- //。
- 命名:变量用下划线;函数用驼峰命名法。
- 变量:声明(var 变量名)与赋值。
- 数据类型:js为弱类型语言;字符串由引号包围(双单均可);用反斜线对字符进行转义,如要在字符串中包含"(此字符串由双引号包围),则需用\";数值;布尔值;
- 数组:语法举例 var a = Array(4)(声明,数组元素个数4完全可以不写);a[0]=1(填充);a[1]=2; or var a = Array(1,2,3,4); or var a = [1,2,3,4]; or var a = [];a[0]=1; 数组中元素数据类型不需相同;关联数组 可在填充数组时为每个新元素明确地给出下标,这时下标不一定要用数字还可用字符串。
- 对象:var a = Object()(也可直接var a={};); a.year=0; a.month=1; or var a = {year:0, month:1}; 可把对象作为数组元素。
- 操作:算数操作符
- 条件语句:
- 比较操作符:==认为空字符串与false的含义相同,要进行严格比较须用全等操作符===,!=也是如此。
- 逻辑运算符:或 与 非
- 循环语句:while do while for
- 函数:function don(){ } 用var关键字给函数变量规定作用域,如没有用var则被视为全局变量
- 对象:一种自足的数据集合。假设Person是个内建对象,则可用var Jiadon = new Person;来新建对象的实例,然后就可用Jiadon.age、Jiadon.walk()等来使用对象的属性和方法。
- 内建对象举例:Math对象的round方法可把十进制数值舍为最接近的整数,如var res=Math.round(num);Date对象——var current_date=new Date(); var today = current_date.getDay(); 还有getHours,getDate,getMonth
- 宿主对象:由js运行环境提供如浏览器,由浏览器提供的预定义对象称为host object。如Form、Image、document对象。
- 用户定义对象
🎂 DOM
- DOM与js的关系:
DOM 是 JavaScript 操作网页的接口,全称为“文档对象模型”(Document Object Model)。它的作用是将网页转为一个 JavaScript 对象,从而可以用脚本进行各种操作(比如增删内容)。
浏览器会根据 DOM 模型,将结构化文档(比如 HTML 和 XML)解析成一系列的节点,再由这些节点组成一个树状结构(DOM Tree)。所有的节点和最终的树状结构,都有规范的对外接口。
DOM 只是一个接口规范,可以用各种语言实现。所以严格地说,DOM 不是 JavaScript 语法的一部分,但是 DOM 操作是 JavaScript 最常见的任务,离开了 DOM,JavaScript 就无法控制网页。另一方面,JavaScript 也是最常用于 DOM 操作的语言。后面介绍的就是 JavaScript 对 DOM 标准的实现和用法。
节点的类型有七种。
Document:整个文档树的顶层节点 DocumentType:doctype标签(比如
<!DOCTYPE html>
) Element:网页的各种HTML标签(比如<body>、<a>
等) Attribute:网页元素的属性(比如class="right") Text:标签之间或标签包含的文本 Comment:注释 DocumentFragment:文档的片段
获取元素:
- 有三种DOM方法可获取元素节点:getElementById() getElementsByTagName() getElementsByClassName(). 参数必须要用双引号包围。返回对象或对象数组。可用typeof document.getElementById()来获取返回数据的类型。
- 简要总结:一份文档就是一棵节点树。节点分为不同类型:元素节点 属性节点 文本节点。getElementById()返回一个对象,该对象对应文档里一个特定的元素节点。getElementsByTagName() getElementsByClassName() 返回一个对象数组,它们分别对应着文档里一组特定的元素节点。每个节点都是一个对象。
获取和设置属性:
- getAttribute():此方法不属于document对象,须用元素节点(对象)来调用。
Example:
var a = document.getElementsByTagName("a");
for(var i = 0; i<a.length; i++){
var att = a[i].getAttribute("href");
if(att) alert(att);
}
- setAttribute():与getAttribute类似。
Example:
var a = document.getElementsByTagName("a");
for(var i = 0; i<a.length; i++){
var att = a[i].getAttribute("href");
if(att){
alert(a[i].getAttribute("href"));
a[i].setAttribute("href", "google.com");
alert(a[i].getAttribute("href"));
}
}
🎃 案例研究:js图片库
<!--gallery.html: -->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta name="keywords" content="Pictures Animals" />
<link type="text/css" rel="stylesheet" href="gallery.css"/>
<title>Gallery</title>
</head>
<body>
<h1>Animal Pictures</h1>
<ul>
<li><a href="images/horse.jpg" title="a handsome horse" onclick="showPic(this); return false;">horse</a></li>
<li><a href="images/grass.jpg" title="lovely grass" onclick="showPic(this); return false;">grass</a></li>
<li><a href="images/bird.jpg" title="a rutting bird" onclick="showPic(this); return false;">bird</a></li>
<li><a href="images/squirrel.jpg" title="squirrel" onclick="showPic(this); return false;">squirrel</a></li>
</ul>
<img src="images/placeholder.jpg" alt="my image gallery" id="placeholder"/>
<script type="text/javascript" src="scripts/gallery.js"></script>
<p id="textholder">Please choose an image.</p>
</body>
</html>
//gallery.js:
function showPic(whichPic){
var source = whichPic.getAttribute("href");
var placeholder = document.getElementById("placeholder");
placeholder.setAttribute("src", source);//也可用:placeholder.src=source;
var text = whichPic.getAttribute("title");
var textholder = document.getElementById("textholder");
textholder.firstChild.nodeValue = text;//也可用childNodes[0]代替firstChild
}
function countBodyChildren(){
var body_element = document.getElementsByTagName("body")[0];
alert(body_element.childNodes.length); //childNodes属性返回的数组包含所有类型的节点
//alert(body_element.nodeType); 元素节点显示为1,属性为2,文本为3
}
window.onload = countBodyChildren;
/*gallery.css: */
body {
font-family: 'Courier New', Courier, monospace;
color: #333333;
background-color: #ccc;
border: thick brown groove;
margin: 50px;
padding: 50px;
}
h1 {
color: #333333;
background-color:transparent;
border-bottom: black medium solid;
}
a{
color: #c60;
background-color:transparent;
font-weight:bold;
text-decoration:none;
font-size:1.5em;
}
a:visited{color:red;}
a:hover{color:yellow;}
a:active{color:white;}
ul{
padding:0;
}
li{
float:left;
padding:1em;
padding-bottom:1.5em;
list-style: none;
}
img{
display:block; clear:both;
}
- 出现的新属性:chileNodes firstChild lastChild nodeType nodeValue
🍄 最佳实践
在HTML代码中调用函数:
"javascript:"伪协议,如
<a href="javascript:popUp(this.href);">pop up<a>
内嵌的事件处理程序,如上一个案例。
分离HTML与js。
平稳退化的概念
- 分离js
- 向后兼容
- 对象检测,如:有一个使用了getElementById()方法的函数,就可以使用对象检测来检查浏览器是否支持这个方法,只需将document.getElementById作为if条件判断表达式,而if中放置你想使用的那个方法。
- 浏览器嗅探技术
- 脚本性能考虑:尽量少访问DOM和尽量减少标记。合并放置脚本,将脚本统一放在一个脚本文件中。用软件压缩脚本以减小文件大小。
🏈 案例研究:图片库改进版
//gallery.js:
function prepareGallery(){
if(!document.getElementById) return false;
if(!document.getElementsByTagName) 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);};
}
}
function showPic(whichPic){
if(!document.getElementById("placeholder")) return false;
var source = whichPic.getAttribute("href");
var placeholder = document.getElementById("placeholder");
placeholder.setAttribute("src", source);//也可用:placeholder.src=source;
if(document.getElementById("textholder")){
var text = whichPic.getAttribute("title")?whichPic.getAttribute("title"):"none";
var textholder = document.getElementById("textholder");
textholder.firstChild.nodeValue = text;//也可用childNodes[0]代替firstChild
}
return true;
}
//addLoadEvent(prepareGallery);
window.onload = prepareGallery;
- 键盘访问(目前不已经需要)
- DOM Core 和 HTLML-DOM
👽 动态创建标记
- document.write(): 可以方便地写入HTML内容,缺点是它违背了“行为应该与表现分离”的原则。
- innerHTML属性: 全部替换HTML内容,不支持XHTML
- DOM方法(不行):
- 先创建新元素,再把这个新元素插入节点树。如:var para = document.createElement("p"); var testdiv = document.getElementById("testdiv"); testdiv.appendChild(para);
- 创建文本节点。如:var txt = document.creatTextNode("Hello world!"); para.appendChild(txt);
- 一个更复杂的组合:可先把所有节点创建出来然后再把它们连在一起;也可如上面一样做。
- 改进图片库
- 在已有元素前插入新元素:insertBefore方法,语法parentNode.insertBefore(newElement, tagetElement);
- 在已有元素后插入新元素:自建insertAfter方法,具体见下面代码。
最终版的gallery: ```javascript function prepareHolder(){ //动态创建标记 var placeholder = document.createElement("img"); var textholder = document.createElement("p"); var txt = document.createTextNode("Please choose an image. ");
placeholder.setAttribute("id", "placeholder"); placeholder.setAttribute("alt", "my image gallery"); placeholder.setAttribute("src", "images/placeholder.jpg"); textholder.setAttribute("id", "textholder"); textholder.appendChild(txt);
//document.getElementsByTagName("body")[0].appendChild("placeholder"); //document.getElementsByTagName("body")[0].appendChild("textholder");
var gallery = document.getElementById("imagegallery"); insertAfter(placeholder, gallery); insertAfter(textholder, placeholder); }
function prepareGallery(){ //平稳退化、对象检测、分离HTML与js if(!document.getElementById) return false; if(!document.getElementsByTagName) 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);};
}
}
function showPic(whichPic){ //执行刷新的主要功能
if(!document.getElementById("placeholder")) return false;
var source = whichPic.getAttribute("href");
var placeholder = document.getElementById("placeholder");
placeholder.setAttribute("src", source);//也可用:placeholder.src=source;
if(document.getElementById("textholder")){
var text = whichPic.getAttribute("title")?whichPic.getAttribute("title"):"none";
var textholder = document.getElementById("textholder");
textholder.firstChild.nodeValue = text;//也可用childNodes[0]代替firstChild
}
return true;
}
function insertAfter(newElement, targetElement){ var parent = targetElement.parentNode; if(parent.lastChild == targetElement){ parent.appendChild(newElement); }else{ parent.insertBefore(newElement, targetElement.nextSibling);//对应的还有previousSibling } }
//addLoadEvent(prepareGallery); window.onload = function(){ //调用函数 prepareHolder(); prepareGallery(); }
- Ajax
- 异步请求
充实文档的内容
------------------------------------
- 定义缩略语列表:
```javascript
function displayList(){
//获取所有符合元素节点
var abbreviation = document.getElementsByTagName("abbr");
if(abbreviation.length<1) return false;
//将值保存在数组中
var defs = Array();
for(var i = 0; i<abbreviation.length; i++){
var defination = abbreviation[i].getAttribute("title");
var key = abbreviation[i].lastChild.nodeValue;
defs[key] = defination;
}
//创建dl标记
var dlist = document.createElement("dl");
//创建多个dt dd标记
for(key in defs){
var defination = defs[key];
var dtitle = document.createElement("dt");
var ddesc = document.createElement("dd");
var dt_text = document.createTextNode(key);
var dd_text = document.createTextNode(defination);
dtitle.appendChild(dt_text);
ddesc.appendChild(dd_text);
dlist.appendChild(dtitle);
dlist.appendChild(ddesc);
}
//创建标题
var header = document.createElement("h1");
var header_txt = document.createTextNode("LIST: ");
header.appendChild(header_txt);
//添加标题和定义列表到页面主体
document.body.appendChild(header);
document.body.appendChild(dlist);
}
//调用
window.onload = displayList;
显示文件来源链接表:
function displayCitation(){ var quotes = document.getElementsByTagName("blockquote"); if(quotes.length<1) return false; for(var i = 0; i<quotes.length; i++){ if(!quotes[i].getAttribute("cite")) return false; var url = quotes[i].getAttribute("cite"); var quote_elements = quotes[i].getElementsByTagName('*'); if(quote_elements.length<1) continue; var elem = quote_elements[quote_elements.length-1]; var lin = document.createElement("a"); var lin_txt = document.createTextNode("source"); lin.appendChild(lin_txt); lin.setAttribute("href", url); var superscript = document.createElement("sup"); superscript.appendChild(lin); elem.appendChild(superscript); } } window.onload = displayCitation;
🐹 CSS-DOM
- CSS与DOM也有重叠的部分。
- 获取样式:不仅文档里每个元素都是一个对象,每个元素都是有一个style属性,它们返回的是对象而不是简单的字符串。但只有把CSS style属性插入到标记里,才可以用DOM style属性去查询那些信息。在外部样式表里声明的样式不会进入style属性返回的对象的属性中。用element.style.property来访问。(font-family属性应写成fontFamily,因为- +在js里是保留字符)。
- 设置样式:element.style.property = value (style对象的属性值永远是一个字符串)。
201907